Jump to content
  • Advertisement
Sign in to follow this  
JoakimNordstrandStien

Collision Detection behaving strange (jnrdev#1)

This topic is 2706 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Salutations!

After browsing these forums for about a month, I decided to create an account, because I'm hopelessly stuck, and you guys know your stuff.

I found a link a week ago (or so) to a web archive containing a "Jump n Shoot" tutorial written by jnrdev. I've been trying to build my own library based on his design on class interaction... Some parts are directly stolen, primarily because they work good, and I don't hold the skills to improve it much.

The main problems I am experiencing is that it detecs a collision when starting in the middle of the screen. Only the outer edges are covered in solid tiles. If I start to move using the arrow keys, the player suddenly drops through the map, until the y value exceeds what an int can hold. I've attached a screenshot showing the console and the main game window.

The Pmap class:
Contains an array of type TILE which contains a pointer to an SDL_Surface, and a boolean containing whether it's solid or not.
class Pmap{

public:

//The only one worth noticing in Pmap
bool colmapxy( int x, int y )
{
return Mtile[x][y].solid;
}

private:

};


Player class, main function:
Interacts with the Pmap class using the "collision_ver" and "collision_hor" functions, which can be seen below.


void Player::think(SDL_Event &event, Pmap& map, SDL_Surface &screen)
{
cout<<"\n\nThinking..\n";
handleInput(event);

int tilecoord;

//X-axis first

//Moving right
if( xVel > 0)
{
printf("Moving right...xVel:%d, yVel:%d, x:%d, y:%d\n", xVel, yVel, x, y);
if(collision_ver( x+xVel+w, y, tilecoord, map) )
x = tilecoord*40 -w-1;
// else x += xVel;
}

//Moving left
if( xVel < 0)
{
printf("Moving left...xVel:%d, yVel:%d, x:%d, y:%d\n", xVel, yVel, x, y);
if( collision_ver( x+xVel, y, tilecoord, map))
x = (tilecoord+1) *40+1;
// else x += xVel;
}

//Caps the xVel at SPEED
if( xVel > SPEED ) xVel = SPEED;


//Then Y-axis
//Moving up
if( yVel < 0 )
{
printf("Moving up...xVel:%d, yVel:%d, x:%d, y:%d\n", xVel, yVel, x, y);

//Moving up & block in the way
if( collision_hor( x, y+yVel, tilecoord, map))
{
y = (tilecoord+1) *40+1;
yVel = 0;
}

//Moving up through blank spots
else
{
y += yVel;
yVel += GRAVITATION;
}

}

//yVel > 0, hence falling or on the ground
else
{
printf("Moving down / on ground...xVel:%d, yVel:%d, x:%d, y:%d\n", xVel, yVel, x, y);

//Moving down, block in the way
if( collision_hor( x, y+yVel+h, tilecoord, map))
{
y = tilecoord*40-h -1; //On ground
yVel = 1;
}
//Falling / in air
else
{
printf("Falling...xVel:%d, yVel:%d, x:%d, y:%d\n", xVel, yVel, x, y);
y += yVel;
yVel += GRAVITATION;

if( yVel >= TILESIZE )
yVel = TILESIZE;

jumpLock = true;
}
}
}



Collision checker function:
Note: there are two of these (_hor and _ver), but they are so similar I choose to only copy in one of them.
Also, this one is identical to jnrdev's function, except for variable names.


bool Player::collision_hor(int x, int y, int &tilecoordy, Pmap& map){
int tilexpixels = x-(x%40); //calculate the x position (pixels!) of the tiles we check against
int testend = x + w; //calculate the end of testing (just to save the x+w calculation each for loop)

tilecoordy = y/40; //calculate the y position (map coordinates!) of the tiles we want to test

int tilecoordx = tilexpixels/40; //calculate map x coordinate for first tile


//loop while the start point (pixels!) of the test tile is inside the players bounding box
while(tilexpixels <= testend){
if(map.colmapxy(tilecoordx, tilecoordy)) //is a solid tile is found at tilecoordx, tilecoordy?
{
printf("Collision(hor) at: X:%d, Y:%d\n", x, y);
return true;
}

tilecoordx++; //increase tile x map coordinate
tilexpixels+=40; //increase tile x pixel coordinate
}

cout<<"No hor coll\n";
return false;
}


Edit:
For some reason, collision_ver() kept returning a wrong value, which I've corrected now, and it appears to be working. If possible, please delete this thread.
The lesson I've learned is that printf / cout will save you tons of time when debugging.

Edited by Admiral Pimms

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!