Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


endless11111

Member Since 04 Apr 2012
Offline Last Active Sep 18 2014 03:43 PM

#5175103 Collision detection problem

Posted by endless11111 on 20 August 2014 - 01:57 PM

I think the reason why the player is going halfway into the rectangle before being pushed out is because of when you handle the collision detection. Let's try stepping through the code one at a time, lets say you start to the left of the rectangle and you press and hold the right key.

 

At the beginning of the code you gave us you do the collision handling. Because you're not intersecting with the rectangle right now, the collision handling section is skipped because there is no collision.

 

Next you have your keystates. The game detects that you are holding the right key so it moves your player to the right, then it draws the player in this position. Now this is important to note that the player is drawn right after he moved, meaning the collision detection has not happened yet.

 

Next you go back to the beginning of the loop and here you run the collision handling because, this time, your player is inside the rectangle. After the collision handling is finished the player is no longer in the rectangle.

 

But once you reach the input handling you move the player back inside the rectangle and then when you draw the player, he is drawn inside the rectangle because you won't handle collision until the next frame.

 

If you let go of the right key, then the collision handling will occur like always, but this time the player won't move because you are no longer handling any input. The player is drawn outside the rectangle because you haven't moved him.

 

So in short the player is drawn right after he moves, before the collision handling can occur so he is drawn inside the rectangle and his position isn't corrected until the next frame. But even if his position is corrected the next frame, if you are still holding down the right key he moves into the rectangle again so in the end you're still in the rectangle.

 

if you restructure your code so the collision handling occurs after the player actually moves then your problem with the player going inside the rectangle should be fixed.

 

 

 

As for the problem with things moving too fast you'll have to find a way to deal with it yourself. For the most part you can just limit the speed of everything so they can't go through objects, but if thats not possible there are other methods. Since you're using axis-aligned rectangles (non rotated rectangles) you could check out http://www.gamedev.net/page/resources/_/technical/game-programming/swept-aabb-collision-detection-and-response-r3084 to learn about swept AABB collision detection. This is basically where you predict where the player traveled during the frame and check if the course he traveled through intersects with any objects and handle collision accordingly. I think that limiting the speed of the objects are good enough if you're just starting out with game development, but if you want you can always implement more advance techniques if your game needs it.




#5175070 Collision detection problem

Posted by endless11111 on 20 August 2014 - 11:57 AM

When you're checking which side of the player is intersecting with the rectangle the first part will always evaluate to true because if the player is at the right side of the rectangle then 
his position will always be greater than the rectangle's position. So when you check for collision it always executes the first half of your if statement.

if (PlayerRectangle.Intersects(BoxRectangle))
{
    if (Position.X + 32 >= BoxRectangle.X )

    //this part will always be true because if the player is at the right side of the rectangle
    //then his position is already greater than the box's position so this is the only part that executes

       Position.X = BoxRectangle.X - 32;
    else if (Position.X <= BoxRectangle.X + BoxRectangle.Width)

    //this part won't execute because the first statement is always true if there is an intersection.
       Position.X = BoxRectangle.X + BoxRectangle.Width;
}

 
Alternatively if you switch the two statements and run the second test first then the collision will only work from the right side of the box. If there is ever a collision between the box and the player then both of those statements will always be true, whichever one is checked first is the one that's executed. You checked the collision from the left side of the box first so only the left side is executed. when you try to collide from the right side of the rectangle you get pushed to the left.
 
 
Instead of doing the above, an easy way to decide where to move the player is to calculate the smallest distance required to move the player in order for the two rectangles to stop intersecting.

 

I don't know XNA so i don't know if the functions abs and min are available to you.

//calculate the smallest distance required to move the player in order to escape collision

//good to have named constants so you know what the numbers refer to
const int playerWidth = 32;

//distance from the right edge of the player to the left edge of the rectangle
float rightEdgeDistance = BoxRectangle.x - (Position.x + playerWidth);

//distance from the left edge of the player to the right edge of the rectangle
float leftEdgeDistance = BoxRectangle.x + BoxRectangle.Width - Position.x;

//figure out the smaller distance, use the absolute values of both calculations because
//the distance might be negative due to the calculations
float smallerDistance = min(abs(rightEdgeDistance), abs(leftEdgeDistance));

//move the player towards the edge of the rectangle that requires the smallest distance to move
if(smallerDistance == abs(leftEdgeDistance))
{
    //distance from right edge of rectangle to the left edge of player is the smallest
    Position.X = BoxRectangle.X + BoxRectangle.Width;

} else if(smallerDistance == abs(rightEdgeDistance))
{
    //distance from left edge of rectangle to right edge of player is smallest
    Position.X = BoxRectangle.X - playerWidth;
}

This usually works if your character is moving in small increments that way when you collide with something only a small portion of the player is actually intersecting with the other object. if your character moves too fast then he risks teleporting to the other side of the rectangle. 




#4968323 TTF Problem

Posted by endless11111 on 10 August 2012 - 10:36 PM

Hello again
I now have another problem xP with my C++ and SDL.
Im now learning to use the ttf library and Ive linked all the libraries together, and theirs no issues with the compiler trying to find the functions or anything, but when I try to load a font, the ttf_openfont command cant find "lazy.ttf" and returns null, so I end up with the message that the program returned 4, meaning the font failed to load.

Any help as to why the program cant find the font? Posted Image

Thanks!


do you have the font file in the save directory as the project file? by font file i mean the actual lazy.ttf file, not the dll's. if the error is due to the program being unable to load the font file it means the compiler cant find the lazy.ttf file. just make sure the lazy.ttf file is in the same directory as your compiler's project file if you are running the program through the compiler. if you run it using the .exe file put the lazy.ttf file in the same directory as the .exe.


#4938415 Beginner's Problem with SDL in C++

Posted by endless11111 on 08 May 2012 - 10:14 AM

the image might not be loading up because you don't have the image file in the same folder as the project file. if you are compiling a program, all the files accosiated with the program must be in the same folder as the .cpp files, and if you are running the .exe file, all the files accosiated with the program must be in the same folder as the .exe file. and i am not really familiar with text intput and output in sdl using cin and cout, but as far as i know, you can't use cin or cout like you would with a console application, you can't just output text or input text directly using cin and cout.


#4938410 [C++] Simple audio

Posted by endless11111 on 08 May 2012 - 09:55 AM

It would definetly make it alot easier to use SDL_mixer


PARTNERS