Player collision detection bug.

So my collision detection for the player is this:


public void update(Input input) {
     if(input.isKeyDown(Keyboard.KEY_UP) && !bounds.instersects(anycollisions)) {
          y--;
     }
     if(input.isKeyDown(Keyboard.KEY_DOWN) && !bounds.instersects(anycollisions)) {
          y++;
     }
     if(input.isKeyDown(Keyboard.KEY_LEFT) && !bounds.instersects(anycollisions)) {
          x--;
     }
     if(input.isKeyDown(Keyboard.KEY_RIGHT) && !bounds.instersects(anycollisions)) {
          x++;
     }
}

When I hit something I will just stop moving completely. I know why it’s happening. However I don’t know any other ways of doing collision detection. Is there any other way that I can still use bounding boxes? What I need is a way for the collision to involve direction somehow. I just don’t know how I could implement that.

You doing (primitive) collision detection, but no collision resolution.

Well then how do I step up my game? I was never taught any other way.

You’ll have to use some basic, Newtonian physics.

I would start off by adding Velocities to your game.

Velocity is a measure of distance per time. (For example, 10meters/second)
Your new update method might look something like this :

update(Input input) {
    if(input.isKeyDown(Keyboard.KEY_UP))
          velocity.y -= verticalMoveSpeed;
     if(input.isKeyDown(Keyboard.KEY_DOWN))
          velocity.y += verticalMoveSpeed;
     if(input.isKeyDown(Keyboard.KEY_LEFT))
          velocity.x -= horizontalMoveSpeed;
     if(input.isKeyDown(Keyboard.KEY_RIGHT))
          velocity.x += horizontalMoveSpeed;

position.x += velocity.x;
position.y += velocity.y;

// If our velocity didnt decrease every update, we would never slow down.
// The damping value is a normalized value that you can use to decrease the velocity by a little bit each update.
// For example, a damping of .95f would mean that every update your velocity decreases by 5%.
velocity *= damping;
}

Adding in velocity, acceleration, and eventually forces will make your game feel far more natural. It will be also be far more difficult and complex. You’ll have to detect collision between shapes moving at different speeds, a good way to do this would be to use the Separating Axis Theorem (or AABB, if your shapes are all axis-aligned).

Even after you can successfully detect collision, you have to learn how to “resolve” a collision.
Resolving a collision basically entails changing an object’s state so that objects dont go through eachother.

You’re doing NON-collision detection ;). Your player stops moving because once you intersect another set of bounds you don’t move the player away from it and your conditional then always return false. As Burnt_Pizza said you’re not doing any resolution. A simple solution is to move the player back to it’s previous location, as long as it’s not moving too fast.

Well alright, then I need to know collision solution. I can check if the object collides, however I need to know if the object collides with the rectangle before the object gets there because I don’t want to have to bounce the object back as this creates a gross flashing back in forth effect that isn’t the attractive. What can I do?

These are two main ways of doing it, with posteriori being much simpler to implement. The priori method is the “predictive” type.

Note that while posteriori is “bouncing the object back” it doesn’t create flashing because the object is “bounced” in the same frame the collision is detected.


     public void update(GameContainer gc) {
		bounds.setX(x);
		bounds.setY(y + 32 - 8);
		if(gc.getInput().isKeyDown(Keyboard.KEY_UP)) {
			if(!isCollision(0, -3)) {
				y -= 3;
			}
		}
		if(gc.getInput().isKeyDown(Keyboard.KEY_DOWN)) {
			if(!isCollision(0, 3)) {
				y += 3;
			}
		}
		if(gc.getInput().isKeyDown(Keyboard.KEY_RIGHT)) {
			if(!isCollision(3, 0)) {
				x += 3;
			}
		}
		if(gc.getInput().isKeyDown(Keyboard.KEY_LEFT)) {
			if(!isCollision(-3, 0)) {
				x -= 3;
			}
		}
	}
	
	public boolean isCollision(int x, int y) {
		checker.setX(bounds.getX()+x);
		checker.setY(bounds.getY()+y);
		for(int i = 0; i < ec.getList().size(); i++) {
			temp = ec.getList().get(i);
			
			if(temp instanceof SolidEntity) {
				if(checker.intersects(((SolidEntity) temp).getBounds())) {
					return true;
				}
			}
		}
		return false;
	}

This is the code that I devised. It works when I have the checker set to the player’s x and y and not his bounding box. However when I have the checker’s x and y set to the offset + the bounds’ x and y it doesn’t let the player move at all. Why doesnt this work with the bounding box but it works with the player’s sprite coords?

What I like to do is create a bounding class. You simply select the location you would like to draw it and it makes 4 rectangles (in the shape of a rectangle). All you have to do is program what happens when one the rectangles collide with another rectangle. I hope it sounds simple. I’ll send you the source (about 8 - 10 lines of code) if I get my computer back today.

PS: Check Kik :stuck_out_tongue:


for(Entity e : Game.ec.getList()) {
			if(e.bounds.intersects(bounds) && !(e instanceof Character)) {
				if(facing == LEFT) {
					x += speed;
				}
				if(facing == RIGHT) {
					x -= speed;				
				}
				if(facing == UP) {
					y += speed;
				}
				if(facing == DOWN) {
					y -= speed;
				}
			}
		}

so this is the code I devised. When a person walks into a tree it works. Except if they spam the keys you end up phasing through the tree. How can I fix this?

use point Collision Detection!

example!

Collision Class

	public static boolean PlayerBlock(Point pt1, Point pt2) {
		for(Tile tiles : Map.tiles){ //LOOP ALL TILES
			if(tiles.isSolid()){ //CHECK IF THE TILE IS SOLID
				if(tiles.contains(pt1) || tiles.contains(pt2)){ //CHECKS IF THE TILE CONTAINTS THE 2 POINTS
					return true; //IF IT DOES RETURN TRUE
				}
			}
		}
		return false; //ELSE RETURN FALSE
	}

that code checks if the tile contains those 2 points!

in tick method or update

double moveAmount = speed * deltaTime;

		if(left){ //CHECK IF LEFT IS TRUE
			
			if(!Collision.PlayerBlock(
					//LEFT BOTTOM
					new Point( (int) (xpos + Map.xOffset - moveAmount),
							   (int) (ypos + Map.yOffset + height)),
					//LEFT TOP
					new Point( (int) (xpos + Map.xOffset - moveAmount), 
							   (int) (ypos + Map.yOffset)))){
					//MOVE MAP
				
					Map.xOffset += moveAmount; //MOVE THE MAP WITH MOVE AMOUNT
			}
		}

that checks this 2 points on player

http://s13.postimg.org/wd5gs96o3/i_MAGAS.png

what that does it checks if those 2 points on player xpos and ypos - the moveamount is not colliding and if its not just keep on moving

What Map.xOffset is and Map.yOffset is the map x and y coos i draw player in middle of screen and move the map not the player

if you need more help just comment!

  • VirtueeL