skip to Main Content

I’m making a 2d game, and I’ve been struggling a lot with 2d collision. I have code that seems to work fine except for corners. When an entity collides exactly with a corner it just end up going straight though.

I’ve been trying to fix for literally 3 weeks. Ive tried AI, I’ve tried documentation, yt tutorials (which is where i got the code i have now) but nothing seems to work for corners as well.

Here is my current code:

for (let i = 0; i < entityHitboxLength; i += 8) {
        let entityX = entityHitboxes[i];
        let entityY = entityHitboxes[i + 1];
        let entityXW = entityHitboxes[i + 2];
        let entityYH = entityHitboxes[i + 3];
        let prevEntityX = entityHitboxes[i + 4];
        let prevEntityY = entityHitboxes[i + 5]; 
        let prevEntityXW = entityHitboxes[i + 6];
        let prevEntityYH = entityHitboxes[i + 7];

        if (
          selfYH > entityY &&
          selfY < entityYH &&
          selfX < entityXW &&
          selfXW > entityX
        ) {
          if (selfYH >= entityY && prevSelfYH < prevEntityY) {
            selfYH = entityY - 1;
            selfY = entityY - 1 - height;
          } else if (selfY <= entityYH && prevSelfY > prevEntityYH) {
            selfY = entityYH + 1;
            selfYH = entityYH + 1 + height;
          }
          else if (selfXW >= entityX && prevSelfXW < prevEntityX) {
            selfXW = entityX - 1;
            selfX = entityX - 1 - width;
          } else if (selfX <= entityXW && prevSelfX > prevEntityXW) {
            selfX = entityXW + 1;
            selfXW = entityXW + 1 + width;
          }
        }
      }

Here is the code documentation i used for this.

Pretty simple and it works fine for edges.
Ive also tried an AI generated approach like

if (
  selfYH > entityY &&
  selfY < entityYH &&
  selfX < entityXW &&
  selfXW > entityX
) {
  // Calculate overlaps on both axes
  const overlapY = Math.min(selfYH - entityY, entityYH - selfY);
  const overlapX = Math.min(selfXW - entityX, entityXW - selfX);

  // Resolve the smaller overlap first
  if (overlapX < overlapY) {
    // Resolve X-axis collision
    if (selfXW >= entityX && prevSelfXW < prevEntityX) {
      selfXW = entityX - 1;
      selfX = entityX - 1 - width;
    } else if (selfX <= entityXW && prevSelfX > prevEntityXW) {
      selfX = entityXW + 1;
      selfXW = entityXW + 1 + width;
    }
  } else {
    // Resolve Y-axis collision
    if (selfYH >= entityY && prevSelfYH < prevEntityY) {
      selfYH = entityY - 1;
      selfY = entityY - 1 - height;
    } else if (selfY <= entityYH && prevSelfY > prevEntityYH) {
      selfY = entityYH + 1;
      selfYH = entityYH + 1 + height;
    }
  }
}

But this passes through even more than the one im using, even at corners still. Is there something wrong with this code? how can i make it work?

2

Answers


  1. Whitouth seen understanding you code very very (some relevant parts are missing) I would think the first if statement seems to be the culprit

        if (
          selfYH > entityY &&
          selfY < entityYH &&
          selfX < entityXW &&
          selfXW > entityX
        ) 
    

    because here you are checking for > / < and not >= / <=, but in the inner if statements you are checking for >= / <=. So I assume, this could be the source of the problem especially in the corner area.

    Login or Signup to reply.
  2. I hope this function will be useful…

    This is a small representation of our rectangle:

    A------B
    |      |
    |      |
    C------D
    

    We will take the “x” of point A with obj.getX(), the “y”, with *obj.*getY()**, the “x” of point B with obj.getX() + obj.getwidth() and the Y of point C with obj.getY() + obj.getHeigth().

    Then we have the width of the rectangle, obj.getWidth() and the height obj.getHeigth().

    Then the expression to know if there is a collision is:

    function isSuperpuestos( objA, objB ) {
       return objA.getX() + objA.getWidth() > objB.getX() &&
              objA.getX() < objB.getX() + objB.getWidth() && 
              objA.getY() < objB.getY() + objB.getHeigth() && 
              objA.getY() + objA.getHeigth() > objB.getY();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search