2
\$\begingroup\$

I'm developing my new platform engine and i don't know how to program collisions with slopes - I'm using hitboxes. For the collisions of rectangles i use this:

if (player.rec(Position, level.scale).Intersects(t.rec(level.scale)))

but this doesn't work for sloped collisions or triangular hitboxes. How can I do this?

\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

You want to read up on PIP algorithms. You'll be also able to find many implementations, even in C#. Here is my suggestion:

public static List<Vector3> intersectShape
    (Geometry polygon_to_cross_0, Geometry polygon_to_cross_1)
{
    List<Vector3> list_vertices = new List<Vector3>();

    for (int i = 0; i <= polygon_to_cross_1.Points_.Count - 1; i++)
    {
        if (Geometry.isInsideOf(polygon_to_cross_1.Points_[i], polygon_to_cross_0))
            list_vertices.Add(polygon_to_cross_1.Points_[i]);

        if (i < polygon_to_cross_1.Points_.Count - 1)
        {
            foreach (Vector3 p in Geometry.getIntersectionVertexGeometry(
                new Vector3[]{ polygon_to_cross_1.Points_[i], 
                polygon_to_cross_1.Points_[i + 1] }, polygon_to_cross_0))
            {
                list_vertices.Add(p);
            }
        }
    }

    for (int i = 0; i <= polygon_to_cross_0.Points_.Count - 1; i++)
    {
        if (Geometry.isInsideOf(polygon_to_cross_0.Points_[i], polygon_to_cross_1))
                list_vertices.Add(polygon_to_cross_0.Points_[i]);

        if (i < polygon_to_cross_0.Points_.Count - 1)
        {
            foreach (Vector3 p in Geometry.getIntersectionVertexGeometry(
                new Vector3[] { polygon_to_cross_0.Points_[i], 
                polygon_to_cross_0.Points_[i + 1] }, polygon_to_cross_1))
                {
                    list_vertices.Add(p);
                }
            }
        }

        return sortPolygonClockWise_XZ((list_vertices));
    }

Count(intersectShape(Geom1, Geom2)) > 0 == true stands for collision.

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to Game Dev! We generally prefer a bit of explanation with coding excerpts, and while you do provide reference material, links are subject to link rot - even wikipedia. They are helpful, when included with an inline explanation, but we do not consider them so by themselves. Could you provide a little elaboration on what your suggestion does, and why you have done it that way? \$\endgroup\$
    – Gnemlock
    Commented Dec 23, 2016 at 19:44
  • \$\begingroup\$ Two other things I feel I should point out. 1: this is an English speaking branch of the stack exchange, so comments should be in English. We retain language consistency for quality. 2: In most of your naming,you spell polygon wrong, often calling it poligon. I can see at least one case where you spell it correctly, but spelling and consistency are both helpful in making your code readable by (and accessible to) others. \$\endgroup\$
    – Gnemlock
    Commented Dec 23, 2016 at 20:00
-1
\$\begingroup\$

It is not just a rectangle/rectangle test. It is also a dot product test to determine which side of the slope line the other object is on. For this you will need to initialize the 2 end points of your slope. This becomes a line segment and the corners of your slope's collision rect. So your slope and rect both share point A & B.

enter image description here

The algorithm gos like this:

If other object is in the rect, check which side of the line it is on,

If above,

 No collision,

else

 Collision

In XNA, that would go something like this,

if(objectRect.Intersects(slopeRect)
{
  Vector2 objectRelativePosition = objectPosition - PointA;
  Vector2 slopeRelativePosition = PointB - PointA;
  Vector3 slopeNormal3 = Vector3.Cross(Vector3.UnitZ, Vector3(slopeRelativePosition,0));
  Vector2 slopeNormal = Vector2(slopeNormal3.X, slopeNormal3.Y);

  if(Vector2.Dot(slopeNormal, objectRelativePosition) > 0)
    {
      //object is above slope, no collision
    }
    else
    {
      // object is below slope, collision
    }
}

The slopeRelativePosition, slopeNormal3, & slopeNormal can all be done only once in the initialization of your map, not each frame. but objectRelativePosition must be recalculated each time you want to run a collision check with the slope.

You can also run this check against each point that makes up the object (say, each corner of a rectangle) if there is no single "position" for the object.

\$\endgroup\$
-2
\$\begingroup\$

I'm think it can be done like this:

class Tile
{
    public virtual float GetTileY(float pX)
    {
        return 1; // Mean tile size is 1x1 units; I'm using 1 unit = 8 pixels, for example.
    }
}

class SlopeTile : Tile
{
    public bool IsFlipped; // If true look like |\, if false - like /|.
    public override GetTileY(float pX)
    {
        return this.IsFlipped ? 1 - pX : pX;
    }
}

You send to GetTileY() value from 0 to 1 that mean how far on this tile player standing and get height, also as value from 0 to 1.

Vector2 position = ...;
Vector2 offset = ...;
Tile tile = ...;
float new_x = position.X + offset_x;
float new_y = position.Y + tile.GetTileY(new_x % 1);

Note, I'm not a professional but I'm also trying to make platformer and this is way I'm want to make slopes.

\$\endgroup\$
4
  • \$\begingroup\$ yeah but how i can know if im colision with the triangle hitbox? \$\endgroup\$ Commented Feb 2, 2015 at 9:46
  • \$\begingroup\$ Let slope be a triangle with size of bottom and left sides 1 unit, so it is inside rectangle 1x1. Check intersections with rectangle and then check position of player's foots does it intersects with slope using GetTileY(). In my platformer world is grid with cells 1x1 and any tile is full cell or part of it, so first i'm check did player even contact cell in which tile situated. \$\endgroup\$
    – user52551
    Commented Feb 2, 2015 at 9:57
  • \$\begingroup\$ offset are same as vector2 velocity? \$\endgroup\$ Commented Feb 2, 2015 at 10:31
  • \$\begingroup\$ Ratget, it velocity * time, in the simplest implementation. \$\endgroup\$
    – user52551
    Commented Feb 2, 2015 at 11:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .