Collision Detection Fix Needed!!!

xpos = Player Xposition 
ypos = Player Yposition 

PlayingState.xOffset = map x
PlayingState.xOffset = map y

Speed fields
private double runningSpeed = 6;
private double normalSpeed = 4;
public double speed;
	
Player width and height are 30
and blocks are 32

if you need something else just ask!

this is where i move map and check for collision

private void EntityMovement(double deltaTime) {
		
		if(canMove){
			if(isLeft()){
				
				if(!Collision.PlayerBlock(
						//LEFT DOWN
						new Point( (int) xpos + PlayingState.xOffset ,
								   (int) (ypos + PlayingState.yOffset - height)),
						//LEFT UP
						new Point( (int) (xpos + PlayingState.xOffset), 
								   (int) (ypos + PlayingState.yOffset)))){
					
					if(PlayingState.xOffset > 1){
						//MOVE MAP
						PlayingState.xOffset -= speed * deltaTime;
					}
					
				}
			}
			
			if(isRight()) {
				if(!Collision.PlayerBlock(
						// RIGHT DOWN
						new Point( (int) xpos + PlayingState.xOffset + width ,
								   (int) (ypos + PlayingState.yOffset - height)),
						// RIGHT UP
						new Point( (int) (xpos + PlayingState.xOffset + width), 
								   (int) (ypos + PlayingState.yOffset)))){
					if(PlayingState.xOffset < 5110){
						//MOVE MAP
						PlayingState.xOffset += speed * deltaTime;
					}
				}
			}
			
			if(isUp()){
				if(!Collision.PlayerBlock(
						//UP LEFT
						new Point( (int) xpos + PlayingState.xOffset ,
								   (int) (ypos + PlayingState.yOffset)),
						//UP RIGHT		
						new Point( (int) (xpos + PlayingState.xOffset + width), 
								   (int) (ypos + PlayingState.yOffset)))){
					
					if(PlayingState.yOffset > 20){	
						//MOVE MAP
						PlayingState.yOffset -= speed * deltaTime;
					}
				}	
			}
			
			if(isDown()) {
				if(!Collision.PlayerBlock(
						//DOWN RIGHT
						new Point( (int) xpos + PlayingState.xOffset ,
								   (int) (ypos + PlayingState.yOffset + height)),
						//DOWN LEFT
						new Point( (int) (xpos + PlayingState.xOffset + width), 
								   (int) (ypos + PlayingState.yOffset + height)))){
					
					
					if(PlayingState.yOffset < 5700){
						//MOVE MAP
						PlayingState.yOffset += speed * deltaTime;
					}
				}
			}
			
			

			if(isRunning()){
				if(getStamina() > 2){
					speed = runningSpeed;
					setAnimationSpeed(50);
				}
				if(getStamina() < 2){
					speed = normalSpeed;
					setAnimationSpeed(200);
				}
				LoseStamina(deltaTime);
			}else{
				addStamina(deltaTime);
				setAnimationSpeed(200);
				speed = normalSpeed;
			}
		}
	}

this is the collision Class

	public static boolean PlayerBlock(Point pt1, Point pt2) {
		for(Block b : PlayingState.blocks){
			if(b.isSolid()){
				if(b.contains(pt1) || b.contains(pt2)){
					return true;
				}
			}
		}
		return false;
	}

but what ever i do he always goes a small bit in to the block and prevent me from moving other ways

so if i walk right he goes little in to the block that prevents me from moving up and down!

how do i make so he does not go in to the block?
and sometimes he goes different jumps in to the block!!!

Hi there,

One thing I spotted here… the first point you pass as a parameter doesn’t have any brackets around the x side:

new Point( (int) xpos + PlayingState.xOffset ,
(int) (ypos + PlayingState.yOffset - height))

Should it be:

new Point( (int) (xpos + PlayingState.xOffset) ,
(int) (ypos + PlayingState.yOffset - height))

You have the whole expression in brackets everywhere else (the y side of the first point and both sides of the second point).

yeah ty, still does same thing doh? any idea how to fix?

Ok, I think I have it…

what you need to do is work out the player’s position after he moves then run your Collision.PlayerBlock on that.

A simple fix would be to do something like this in EntityMovement:

private void EntityMovement(double deltaTime) {
      
      if(canMove){

++         double moveAmount = speed * deltaTime;

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

And so on for moving right, up, and down.

Hope that helps :slight_smile:

Edit: What we’re doing is checking if the player’s new position will collide and if it will, don’t allow the move.

thanks now the last problem is that sometimes is stays differed jumps from blocks like so…

[] = block
p = player

[ ][ ][ ] p
[ ]p
[ ] P
[ ] p
[ ] p
[ ]p

that is a bad explanation but sometimes he just stays different amounts of pixels away from blocks that prevents him from
walking between 2 block

[ ] p
[ ] [ ]

i can just show on img if you want lol?

You need to do either one of 2 things.

You can either predict collisions before they happen, or let them happen and then correct it. I prefer the latter and that seems to be what you are trying.

You need to find the contact point of your collision (the normal, sometimes), find out how much the object is inside and then add this to the objects position.

So say I am at x = 5 and y = 5, a block is at x = 6 and y = 5.

I step to the right at my players speed * delta, let’s just say the player moves at 50 units * delta, assuming delta time is roughly 60fps so 0.0166ms.

By the time I collide with the block and go inside it and the collision is detected, I should be roughly 0.83 units into it. You need to take this number and use it to correct the collision, this is called the Minimum Translation Vector.

You can easily calculate this by taking the first colliding object and the second colliding object and doing something like this:


    /*
     * Here we check 2 rectangles for the amount they overlap
     */
     public Vector2 getMTV(Rectangle r1, Rectangle r2){
        Vector2 vec;
         
        // Variables that indicate the left, right, top
        // and bottom edges of the colliding rect
        float left, right, top, bottom;
         
        // Assign all these values, this should
        // make sense if you have done any sort
        // of origin based code,
        // like sprite.origin.x = sprite.width / 2
        left = r2.x - (r1.x + r1.width);
        right = (r2.x + r2.width) - r1.x;
        top = r2.y - (r2.y + r2.height);
        bottom = (r2.x + r2.height) - r1.y;
         
        // Check each side of the rectangle
        // and get the overlap amount
        if(Math.abs(left) > right)
            vec.x = right;
        else
            vec.x = left;
            
        if(Math.abs(bottom) > top)
            vec.y = top;
         else
            vec.y = bottom;
            
        // Check which component is the smallest
        // so we can correct the collision
        // MTV always uses the quickest way to resolve
        // the collision, in this case the smallest
        // overlap
        if(Math.abs(vec.x) < Math.abs(vec.y)
            vec.y = 0;
        else
            vec.x = 0;
            
        // Return the vector, we can now use this
        // to offset our object, I think you have
        // to multiply it by 2, can't remember.
        return vec;
         
         
     }
     
}

Google MTV or SAT, you will get plenty of nice tutorials. This one I gave you is very simple, I used it for a pong clone successfully (not the exact above code, I typed that in notepad). It may be buggy but the idea is the same, I tried to comment it as much as I could.

Now that is exactly what I’ve been too lazy to implement in my game :slight_smile:

Thank you for sharing that Gibbo, you just motivated me to sort it out!