admin管理员组

文章数量:1323729

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?

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?

Share Improve this question edited Jan 12 at 5:52 Julian asked Jan 12 at 5:50 JulianJulian 11 bronze badge
Add a comment  | 

2 Answers 2

Reset to default 0

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.

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();
}

本文标签: javascriptrectangle 2d collision detection and response that works with cornersStack Overflow