Skip to main content
deleted 22 characters in body
Source Link
jgallant
  • 8.5k
  • 7
  • 35
  • 46
// Process Y axis
Velocity.Y += Gravity.Y * elapsed * Mass;
Position.Y += Velocity.Y * elapsed;

// Handle vertical collision that may have occured
HandleCollisions(Direction.Vertical, generator);


// Process X Axis
Velocity.X += Speed * elapsed;
Position.X += Velocity.X * elapsed;

HandleCollisions(Direction.Horizontal, generator);
// Process Y axis
Velocity.Y += Gravity.Y * elapsed * Mass;
Position.Y += Velocity.Y * elapsed;

// Handle vertical collision that may have occured
HandleCollisions(Direction.Vertical, generator);


// Process X Axis
Velocity.X += Speed * elapsed;
Position.X += Velocity.X * elapsed;

HandleCollisions(Direction.Horizontal, generator);
// Process Y axis
Velocity.Y += Gravity.Y * elapsed * Mass;
Position.Y += Velocity.Y * elapsed;

// Handle vertical collision that may have occured
HandleCollisions(Direction.Vertical);


// Process X Axis
Velocity.X += Speed * elapsed;
Position.X += Velocity.X * elapsed;

HandleCollisions(Direction.Horizontal);
added 100 characters in body
Source Link
jgallant
  • 8.5k
  • 7
  • 35
  • 46

private bool HandleCollisions(Direction direction) { bool collides = false;

private bool HandleCollisions(Direction direction)
{
    bool collides = false;

    // Whatever method you use to get a list of tiles to check against
    // A quad tree structure here would be beneficial to query
    List<Land> land = GetListOfLandTilesToCheck();

    // process tiles and check if we are colliding with them
    foreach (Land l in land)
    {
        // Calculate how deep the intersection is
        Vector2 depth;      
        if (l.Rectangle.Intersects(Rectangle))
        {
            if (TileIntersectsPlayer(Rectangle, l.Rectangle, direction, out depth))
            {
                // Adjust position for collision response
                Position += depth;
                collides = true;
            }
        }   
    }
    return collides;
}

}

private bool HandleCollisions(Direction direction) { bool collides = false;

// Whatever method you use to get a list of tiles to check against
// A quad tree structure here would be beneficial to query
List<Land> land = GetListOfLandTilesToCheck();

// process tiles and check if we are colliding with them
foreach (Land l in land)
{
    // Calculate how deep the intersection is
    Vector2 depth;      
    if (l.Rectangle.Intersects(Rectangle))
    {
        if (TileIntersectsPlayer(Rectangle, l.Rectangle, direction, out depth))
        {
            // Adjust position for collision response
            Position += depth;
            collides = true;
        }
    }   
}
return collides;

}

private bool HandleCollisions(Direction direction)
{
    bool collides = false;

    // Whatever method you use to get a list of tiles to check against
    // A quad tree structure here would be beneficial to query
    List<Land> land = GetListOfLandTilesToCheck();

    // process tiles and check if we are colliding with them
    foreach (Land l in land)
    {
        // Calculate how deep the intersection is
        Vector2 depth;      
        if (l.Rectangle.Intersects(Rectangle))
        {
            if (TileIntersectsPlayer(Rectangle, l.Rectangle, direction, out depth))
            {
                // Adjust position for collision response
                Position += depth;
                collides = true;
            }
        }   
    }
    return collides;
}
Source Link
jgallant
  • 8.5k
  • 7
  • 35
  • 46

Here is some code that I pulled up for you from my XNA coding days. This is how I would handle collisions with XNA. This method works strictly with Rectangle colliders.

The first function I will show you is to get the intersection depth between two Rectangles:

public static float GetHorizontalIntersectionDepth(Rectangle rectA, Rectangle rectB)
{
    // Calculate half sizes.
    float halfWidthA = rectA.Width / 2.0f;
    float halfWidthB = rectB.Width / 2.0f;

    // Calculate centers.
    float centerA = rectA.Left + halfWidthA;
    float centerB = rectB.Left + halfWidthB;

    // Calculate current and minimum-non-intersecting distances between centers.
    float distanceX = centerA - centerB;
    float minDistanceX = halfWidthA + halfWidthB;

    // If we are not intersecting at all, return (0, 0).
    if (Math.Abs(distanceX) >= minDistanceX)
        return 0f;

    // Calculate and return intersection depths.
    return distanceX > 0 ? minDistanceX - distanceX : -minDistanceX - distanceX;
}

Since the vertical intersection calculation is slightly different, here is the function to grab that depth as well:

public static float GetVerticalIntersectionDepth(Rectangle rectA, Rectangle rectB)
{
    // Calculate half sizes.
    float halfHeightA = rectA.Height / 2.0f;
    float halfHeightB = rectB.Height / 2.0f;

    // Calculate centers.
    float centerA = rectA.Top + halfHeightA;
    float centerB = rectB.Top + halfHeightB;

    // Calculate current and minimum-non-intersecting distances between centers.
    float distanceY = centerA - centerB;
    float minDistanceY = halfHeightA + halfHeightB;

    // If we are not intersecting at all, return (0, 0).
    if (Math.Abs(distanceY) >= minDistanceY)
        return 0f;

    // Calculate and return intersection depths.
    return distanceY > 0 ? minDistanceY - distanceY : -minDistanceY - distanceY;
}

With these functions, you can determine how deep an intersection between two rectangles are. This is important as we need to know this information in order to correct our position in our collision response.

The next method, is a "helper" function that will calculate the depth between two rectangles based on the direction you are looking to check:

private bool TileIntersectsPlayer(Rectangle player, Rectangle block, Direction direction, out Vector2 depth)
{
    if (direction == Direction.Vertical) {
        depth = new Vector2(0, GetVerticalIntersectionDepth(player, block));
    } else if (direction == Direction.Horizontal) {
        depth = new Vector2(GetHorizontalIntersectionDepth(player, block), 0);
    }
    
    return depth.Y != 0 || depth.X != 0;
}

With this helper method, we will now be able to handle the collision handling and response with this function:

private bool HandleCollisions(Direction direction) { bool collides = false;

// Whatever method you use to get a list of tiles to check against
// A quad tree structure here would be beneficial to query
List<Land> land = GetListOfLandTilesToCheck();

// process tiles and check if we are colliding with them
foreach (Land l in land)
{
    // Calculate how deep the intersection is
    Vector2 depth;      
    if (l.Rectangle.Intersects(Rectangle))
    {
        if (TileIntersectsPlayer(Rectangle, l.Rectangle, direction, out depth))
        {
            // Adjust position for collision response
            Position += depth;
            collides = true;
        }
    }   
}
return collides;

}

And then finally, you need to handle your movement and collision checks one-axis at a time in order for this method to work. In your update method you would have something like this:

// Process Y axis
Velocity.Y += Gravity.Y * elapsed * Mass;
Position.Y += Velocity.Y * elapsed;

// Handle vertical collision that may have occured
HandleCollisions(Direction.Vertical, generator);


// Process X Axis
Velocity.X += Speed * elapsed;
Position.X += Velocity.X * elapsed;

HandleCollisions(Direction.Horizontal, generator);