AABB Collision response(Push back colliding objects)

I'm having problem with collision detection with my C++ game. I first tried AABB and successfully got it to detect collision but the problem was that I want to be able to push each other so I went with a basic solution to push both objects back half of the distance penetrated. But that only pushed the objects to a 45 degree angle to each other.Link to GIF explaining what i mean

IF YOU DON'T WANT TO READ SKIP THIS PARAGRAPH

So I figured that I need an direction to push the objects in, so I tried to modify some code from a tutorial. The direction is a normalized vector between the center of both objects. And then half of the collision depth is multiplied with the normalized vector so they get pushed in the opposite direction of each other. This worked but it used circular collision(it used radius + radius to calculate collision depth) and this meant that I couldn't use rectangles with different width and height, for instance 32x64 48x32(I had to use 32x32 48x48 64x64 and so on and so forth). This is a big problem because I NEED TO BE ABLE TO USE TEXTURES WITH DIFFERENT WIDTH AND HEIGHT .

So once again a went back to AABB and got it to work with out being able to push each other, so you just come to a complete stop. But the problem here is that when I collide on one axis I can't move in the other. For example, if I hold down UP and LEFT and collide with a wall on the LEFT i come to a complete stop instead of continue going UP where there is no wall.

SO WHAT I WANT HELP WITH IS either AABB collision where objects push each other with half of the distance penetrated in the correct direction or just plain AABB where you come to a complete stop BUT are able to walk in the non colliding direction when colliding on the other axis, for example Holding down up and down would result in this


Here's something to think about AABB collision checking:

Let's say you have two box objects: O1(x,y,width,height) and O2(x,y,width,height), where 'x' and 'y' are the bottom-left corner of the box object.

Let's say you move O1 with a step of S(x,y)

In order to avoid a full stop on collision, you should divide your collision check in two - once a collision for horizontal, and once for a vertical.

So, get the origin differences after moving: diff = vec2(O1.x + Sx - O2.x, O1.y + Sy - O2.y)

Before going any further, you should check if the two objects never overlap:

if( (diff.x < -O1.width || diff.x > O2.width) && (diff.y < -O1.height || diff.y > O2.height) return;

If they never overlap, there's no need to constrain the movement and we just skip the collision.

Then we start constraining our horizontal movement:

  • If diff.x is smaller than -O1.width , then O1 is on the far left. It can move freely on the horizontal. So Sx remains as is.

  • Else if diff.x is bigger than O2.width , then O1 is on the far right, and can move freely on the horizontal. So Sx remains as is.

  • Otherwise, we have a situation where O1 overlaps O2 on the horizontal. So just check if(diff.x<0) Sx -= O1.width+diff.x; and, respectively if(diff.x>=0) Sx += O2.width-diff.x;

  • Your horizontal movement should be ready in Sx . Now, following the same principle, take care of your vertical movement:

  • If diff.y is smaller than -O1.height , then O1 is far below. It can move freely on the vertical. So Sy remains as is.

  • Else if diff.y is bigger than O2.height , then O1 is far up, and can move freely on the vertical. So Sy remains as is.

  • Otherwise, we have a situation where O1 overlaps O2 on the vertical. So just check if(diff.y<0) Sy -= O1.height+diff.y; and, respectively if(diff.y>=0) Sy += O2.height-diff.y;

  • In essence, at the end you have a S(x,y) which contains your new 'safe' moving step. All you have to do, is to move O1 by S, and then repeat the process on next step.

    链接地址: http://www.djcxy.com/p/95572.html

    上一篇: 先进的碰撞检测?

    下一篇: AABB碰撞响应(推回碰撞物体)