Jump to content

  • Log In with Google      Sign In   
  • Create Account

endless11111

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

Posts I've Made

In Topic: Collision detection problem

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.


In Topic: Collision detection problem

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. 


In Topic: 2D Platformer collision handling...

16 June 2013 - 11:14 PM

I handle collisions pretty easily, first i calculate the distance it traveled in the x axis only, then i check if it collides with anything not passable, like a block.

if i collides with anything, i reduce the distance it traveled in this frame and move it back to its previous position, and then i do the same for the y axis.

 

so for psuedocode it would look like this, actually its closer to c++ code than psudocode, but it's pretty self explanatory: 

 

//so add the distance traveled this frame, distance = velocity * time

//save the distance traveled so i can subtract it later and move back to previous position in case of collision

float distance_Traveled = x_Velocity * delta_Time;

 

x_Position += distance_Traveled;

 

if(check for collision with any entity)

{

     x_Position -= distance_Traveled;

}

 

then i just repeat that for the y axis, and the object will move to the last position it existed on before it had a collision. note there are some problems, for example if there is a collision before and after it moves, like the bounding box is located inside a block before it moves, and inside a block after it moves, it will move back to its previous position even if its still colliding with something. another problem is if it travels too far within a single frame, and crosses a huge gap at once and collides with something, it will move back to its original position even if the distance is enormous.

 

lets say the square bracket is the player, and the 0 is a wall

[]                    0

if its that far, and in one frame the square bracket moves inside the 0

                      [(])

then it wil move all the way back to its last position

[]                      0

and not take into account the entire gap in between.

 

another problem has more to do with collision detection than handling, if an entity moves from one side of a block to another in a single frame without touching it, it wont count as a collision and he will pass through the block.

 

ex:

 

frame 1:

[]          0

 

frame 2:

             0     []

 

no collision, so it will keep moving just fine.

 

anyways this simple way to handle collision works fine until it starts lagging or objects move at high velocities. also if it looks like the player is floating over a block then just make the bounding boxes of the player / block smaller than the image, that way it looks a little bit better. and one last thing, if you move one axis at a time, handling slopes will be easy because you just handle slope on the x axis and you can easily use something like y=mx + b to determien the position.  

 

here is a final guide that you can look over to help you understand how to implement platformers, i really suggest you read it, its great. 

 

http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/

its on gamedev.net too but my computer lags too badly to search for it so i just used the first link i found. Good luck


In Topic: How do you make an AI follow an A* path in a 2D platformer game

23 December 2012 - 12:52 PM

Alright thanks for the help guys.


In Topic: How do you make an AI follow an A* path in a 2D platformer game

22 December 2012 - 08:04 PM

Remember that A* is a graph-based function. It only follows connections between nodes. It doesn't matter if those nodes are regular, odd, evenly spaced, top-down, or from the side. The best bet is to pre-calculate all possible jumps (up and down) and plot how those would look in space. Then, as you prepare your level, you mark up the places where the nodes connect -- obviously next to each other, but also where there are potential jump paths as well. Then, the AI just analyzes those nodes and the connections available to find the best possible route to the goal.

 

Now all of that assumes A*. If you are just using a local steering function, that is actually (believe it or not) slightly more complicated in this manner. If you were to simply scan the squares in an area around you (say a 3x3 grid centered on the agent), you can identify places you could possibly go next. Either by moving 1 square left or right (normal movement), a square up or down and also left right (e.g. your 4th-6th columns in the video above), etc. If you can't go directly to a square in the direction you want to move, you also scan 2 squares over and see if there is something available to jump to. That way, if a direct path is not available, it might elect to jump a gap (e.g. the middle-right area of your video). That's more of a clunky rule-based brute force way of doing it, though.

Thank you for the reply, but im still confused about how i would implement the search algorithm. First of all how would i make the search algorithm take into account gravity and jumping. also how would i make the algorithm go from one solid node to another and take into account the gaps in between and the distances for jumping. lastly would i implement a search algorithm in the AI itself or just a generic search algorithm that anything can use. thanks for the help so far and sorry i couldnt grasp how i would implement it.


PARTNERS