Fixing a collision detection bug in Slick2D
- by Jesse Prescott
My game has a bug with collision detection.
If you go against the wall and tap forward/back sometimes the game thinks the speed you travelled at is 0 and the game doesn't know how to get you out of the wall.
My collision detection works by getting the speed you hit the wall at and if it is positive it moves you back, if it is negative it moves you forward.
It might help if you download it:
https://rapidshare.com/files/1550046269/game.zip
Sorry if I explained badly, it's hard to explain.
float maxSpeed = 0.3f;
float minSpeed = -0.2f;
float acceleration = 0.002f;
float deacceleration = 0.001f;
float slowdownSpeed = 0.002f;
float rotateSpeed = 0.08f;
static float currentSpeed = 0;
boolean up = false;
boolean down = false;
boolean noKey = false;
static float rotate = 0;
//Image effect system
static String locationCarNormal;
static String locationCarFront;
static String locationCarBack;
static String locationCarBoth;
static boolean carFront = false;
static boolean carBack = false;
static String imageRef;
boolean collision = false;
public ComponentPlayerMovement(String id, String ScarNormal, String ScarFront, String ScarBack, String ScarBoth)
{
this.id = id;
playerBody = new Rectangle(900/2-16, 700/2-16, 32, 32);
locationCarNormal = ScarNormal;
locationCarFront = ScarFront;
locationCarBack = ScarBack;
locationCarBoth = ScarBoth;
imageRef = locationCarNormal;
}
@Override
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException
{
Input input = gc.getInput();
playerBody.transform(Transform.createRotateTransform(2));
float hip = currentSpeed * delta;
float unstuckspeed = 0.05f * delta;
if(carBack && !carFront)
{
imageRef = locationCarBack;
ComponentImageRender.updateImage();
}
else if(carFront && !carBack)
{
imageRef = locationCarFront;
ComponentImageRender.updateImage();
}
else if(carFront && carBack)
{
imageRef = locationCarBoth;
ComponentImageRender.updateImage();
}
if(input.isKeyDown(Input.KEY_RIGHT))
{
rotate += rotateSpeed * delta;
owner.setRotation(rotate);
}
if(input.isKeyDown(Input.KEY_LEFT))
{
rotate -= rotateSpeed * delta;
owner.setRotation(rotate);
}
if(input.isKeyDown(Input.KEY_UP))
{
if(!collision)
{
up = true;
noKey = false;
if(currentSpeed < maxSpeed)
{
currentSpeed += acceleration;
}
MapCoordStorage.mapX += hip * Math.sin(Math.toRadians(rotate));
MapCoordStorage.mapY -= hip * Math.cos(Math.toRadians(rotate));
}
else
{
currentSpeed = 1;
}
}
else if(input.isKeyDown(Input.KEY_DOWN) && !collision)
{
down = true;
noKey = false;
if(currentSpeed > minSpeed)
{
currentSpeed -= slowdownSpeed;
}
MapCoordStorage.mapX += hip * Math.sin(Math.toRadians(rotate));
MapCoordStorage.mapY -= hip * Math.cos(Math.toRadians(rotate));
}
else
{
noKey = true;
if(currentSpeed > 0)
{
currentSpeed -= deacceleration;
}
else if(currentSpeed < 0)
{
currentSpeed += acceleration;
}
MapCoordStorage.mapX += hip * Math.sin(Math.toRadians(rotate));
MapCoordStorage.mapY -= hip * Math.cos(Math.toRadians(rotate));
}
if(entityCollisionWith())
{
collision = true;
if(currentSpeed > 0 || up)
{
up = true;
currentSpeed = 0;
carFront = true;
MapCoordStorage.mapX += unstuckspeed * Math.sin(Math.toRadians(rotate-180));
MapCoordStorage.mapY -= unstuckspeed * Math.cos(Math.toRadians(rotate-180));
}
else if(currentSpeed < 0 || down)
{
down = true;
currentSpeed = 0;
carBack = true;
MapCoordStorage.mapX += unstuckspeed * Math.sin(Math.toRadians(rotate));
MapCoordStorage.mapY -= unstuckspeed * Math.cos(Math.toRadians(rotate));
}
else
{
currentSpeed = 0;
}
}
else
{
collision = false;
up = false;
down = false;
}
if(currentSpeed >= -0.01f && currentSpeed <= 0.01f && noKey && !collision)
{
currentSpeed = 0;
}
}
public static boolean entityCollisionWith() throws SlickException
{
for (int i = 0; i < BlockMap.entities.size(); i++)
{
Block entity1 = (Block) BlockMap.entities.get(i);
if (playerBody.intersects(entity1.poly))
{
return true;
}
}
return false;
}
}