Problem with collision detection/prevention

Hi guys, not quite sure on exactly what the problem is with this here… I’ve been scratching my head for days with it.

So, my collision detection works by:

  1. calculate where an entity wants to be next frame
  2. do AABB collision detection to check if the entity is allowed to be where it wants to be (by looping over all other entities and nearby tiles)
  3. if not allowed, work out the maximum the entity can move in the direction it wants to (someone said this a minimum translation vector I think?)
  4. move as above

It works great. Most of the time. I noticed that occasionally when running the routine above I get a problem like at the end of this gif:

(the white box is the box the collision detection runs on, which is why it is always clipping the other blue boxes)

The minimum movement goes a bit nuts and throws the entity the wrong way to avoid the clipping.

The movement controller class is here: http://pastebin.java-gaming.org/9550b6f511b19.
it has update(delta) method that loops over each entity in the game and checks if it can move (has MoveableEntity interface), wants to move (Entity.state == MOVING), and gets the direction is it going in (MoveableEntity.getFacingDirection). Then it applies collision detection as above.

I am absolutely stuck with this one, I think it only happen when clipping against multiple entities but I haven’t worked out any other conditions. From my code I can’t work out why it can happen - I only check for collisions in the direction the entity is moving in so when moving down it should check for collision below and move up to stop, when moving right it should check the entity to the right and move left to un-collide. In my head I can’t see why this would happen! ARGH!

Any help would be extremely welcomed!

I haven’t looked at the code yet but I noticed something in the gif… I’m guessing the white square is the player’s collision square… If it is then why is it partly in the tree?

The white square is not the player’s own collision box, it’s the box that the collision detection works with to calculate collisions. So if it’s not in another entity’s box then there is no collision.

what i do is check if 2 points are intersecting with the tile box player Size is 30 and block size is 32
then i use this in my update/tick metod

btw i just draw the player in the middle of the screen! hope this helps!

		double moveAmount = speed * deltaTime;
		
		if(left){
			
			if(!Collision.PlayerBlock(
					//LEFT DOWN
					new Point( (int) (xpos + Map.xOffset - moveAmount),
							   (int) (ypos + Map.yOffset + height)),
					//LEFT UP
					new Point( (int) (xpos + Map.xOffset - moveAmount), 
							   (int) (ypos + Map.yOffset)))){
					//MOVE MAP
					Map.xOffset -= moveAmount;
			}
		}

Looks like you find the first object in the list that the player will be inside of at the end of the frame and use that alone to determine the translation vector. But some time you will end up inside two or more objects or you will pass through the corner of one object before ending up inside another. In these cases your code can leave the player inside a different object from the one you calculated against. To fix this you need to determine the time of all possible collisions during the frame and then use the first one to determine your translation vector.

EWG! I’ll check that out later. So I need to list all the entities the player is about to collide with then fudge use minimum translation vector to stop the player colliding with all of them.

Damn, I thought the player would only ever be able to collide with a single entity when moving in a single direction at a time :confused: