Collision bug in a 2D platfrom game.

Hi,
I’m new to java, and game programming and I’m starting my first big project which is a 2D platform puzzle game.
This is my player movement code


		
		if (speedX > 0 && centerX <= 400){
			centerX += speedX;
		}
		
		if (speedX < 0 && centerX >= 400){
			centerX += speedX;
		}
		
		if (speedX > 0 && centerX >= 400){
			bg1.setSpeedX(-MOVESPEED);
			bg2.setSpeedX(-MOVESPEED);
		}
		
		if (speedX < 0 && centerX <= 400){
			bg1.setSpeedX(MOVESPEED);
			bg2.setSpeedX(MOVESPEED);
		}
		
		if (speedX == 0){
			bg1.setSpeedX(0);
			bg2.setSpeedX(0);
		}
		
		if(movingRight == true && movingLeft == true ){
			bg1.setSpeedX(0);
			bg2.setSpeedX(0);
		}

		// Handles Jumping
		if (jumped == true) {
			speedY += 1;


		}

		// Prevents going beyond X coordinate of 0
		if (centerX + speedX <= 60) {
			centerX = 61;
		}
		rect.setRect(centerX - 47, centerY - 65, 32, 87);
		
		centerY += speedY;
	}

	public void moveRight() {
				speedX = MOVESPEED;		
	
	}

	public void moveLeft() {
			speedX = -MOVESPEED;
	}

	public void stopRight() {
		movingRight = false;
		stop();
	}

	public void stopLeft() {
		movingLeft = false;
		stop();
	}

	private void stop() {
		if (movingRight == false && movingLeft == false) {
			speedX = 0;
		}
		if (movingRight == false && movingLeft == true) {
			moveLeft();
		}

		if (movingRight == true && movingLeft == false) {
			moveRight();
		}
}

	

	public void jump() {
		if (jumped == false) {
			speedY = JUMPSPEED;
			jumped = true;
		}

	}


and this is the collision code


    public void checkCollision(Rectangle rect){
    	if (rect.intersects(r)){
    		if(Player.movingRight){
    		Player.centerX = tileX + 11;
    		Player.speedX =0;
    		}
    		
    		if(Player.movingLeft){
    		Player.centerX = tileX + 89;
    		Player.speedX = 0;
    		}
    		
    		if(Player.speedY > 0){
    			Player.centerY = tileY - 25;
    			Player.speedY = 0;
    			Player.jumped = false;
    		}
    	}
 
    }
    


There are two problems.The first one is that if I press one of the movement keys when landing the character “teleports” to the right or left.
I know this happens because I programmed it that if the character intersects with the ground while movingRight or movingLeft are true he moves right or left.(I made it this way so the horizonal collision will work) and I cant think of any other way to do it or how to fix it.

The second problem is that if the character moves of a platfrom he does not fall down.
I tryed to fix it by adding to the collision method


else{
speedY += 1;
}

But it made the character disappear for some reason.

Thanks a lot!

By the way, sorry for my english it is not my native language.

When I first start with java to make platformer games i had dificulty to manage collision.

Then i figure out a simple way:

Create only one rectangle to your player and method called for example: canMove();

Before you make the move use this:

if(canMove(nextX,nextY)){

}

the nextX and nextY is going to be your next position based on your speed

Hi,

Not sure if this will help with your specific problem, but it might be a better way to handle collisions during player movement.

You may find it useful to go ahead and move the character 1 pixel at a time until they’ve moved their whole speed – but don’t draw it yet! Every pixel the character moves, check to see if moving that pixel would make it collide with anything. Then, if it does, simply stop the movement before that pixel.

For simple collision, you can just see if a rectangle you make that surrounds it overlaps with the rectangles of other objects. Here is what you could do for each pixel of movement:


int moveX = 0;
int moveY = 0;
if(movingLeft) { moveX = -1; }
else if(movingRight) { moveX = 1; }
if(movingUp) { moveY = 1; } //assuming y goes up and not down
else if(movingDown) { moveY = -1; }

//box is the rectangle around your character used for checking collision
//obstacles is an ArrayList of every other rectangle on the level the character can collide with
Rectangle nextSpot = new Rectangle(box.x + moveX, box.y + moveY, box.width, box.height)
boolean collided = false;
for(Rectangle thing : obstacles) {
    if(nextSpot.intersects(thing)) {
        collided = true;
        break; //no need to continue checking obstacles -- we've hit one
    }
}
if(collided == true) {
    //no more movement!
    break;
    //if we're inside another loop that goes until we've moved our whole speed,
    //we can get out of it with break.
} else {
    //move that little bit!
    playerX += moveX;
    playerY += moveY;
}

Then, once the character has moved as far as they can with that collision checking method, update the screen.

You can also just check the bounding volume of the intersecting bodies and say, if the player is moving toward a static body with a positive x velocity, you get the left most edge of the object it collides with, and minus the width of the player. This is pixel perfect with rectangles and doesn’t require iterating per pixel, as it will just automatically push you to the left most edge of whatever you’ve collided with. My implementation looks like this:

public void collisionChecks() {
                //move the player's rectangle the entire velocity
		player.rect.x += player.xvel;
                //if the player leaves the boundary of the camera, load a new map segment 
		if (player.rect.x < 0 && pmx > 0) {
			pmx -= 1;
			loadRoom();
			bulletList.clear();
			player.rect.x = 1899;
		} else if (player.rect.x < 0) {
			pmx = MX - 1;
			loadRoom();
			bulletList.clear();
			player.rect.x = 1899;
		}
		if (player.rect.x > 1900 && pmx < MX - 1) {
			pmx += 1;
			loadRoom();
			bulletList.clear();
			player.rect.x = 1;
		} else if (player.rect.x > 1900) {
			pmx = 0;
			loadRoom();
			bulletList.clear();
			player.rect.x = 1;
		}
                //do actual collision check
		for (int i = 0; i < rectList.size(); i++) {
			if (player.rect.overlaps(rectList.get(i))) {
				player.rect.x -= player.xvel;
				if (player.xvel > 0) {
					player.rect.x += rectList.get(i).x - player.rect.x - 20; //20 is the player width, I'm just too lazy to use player.rect.width()
					player.xvel = 0; //set velocity to 0 as we've collided
					touchingRight = true;
				} else if (player.xvel < 0) {
					player.rect.x += rectList.get(i).x + 32 - player.rect.x; //32 is tile width, also too lazy to use rectList.get(i).width()
					player.xvel = 0; //set velocity to 0 as we've collided
					touchingLeft = true;
                 		}
                                //if we know there's a collision, leave the loop
				break;
			}
                        //if there is no collision, reset touching booleans
			touchingRight = false;
			touchingLeft = false;
		}
	}
		

keep in mind this only will work if your velocity is less than the width of a tile, but you can test for that and iterate in velocity steps that are the size of tiles, so it’s just less iterations, rather than per pixel.