Fixing a collision detection bug in Slick2D

Posted by Jesse Prescott on Game Development See other posts from Game Development or by Jesse Prescott
Published on 2012-10-24T01:50:06Z Indexed on 2012/10/24 5:28 UTC
Read the original article Hit count: 253

Filed under:
|
|

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;
}

}

© Game Development or respective owner

Related posts about java

Related posts about collision-detection