Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a player polygon and I check to see if it's colliding with my tiled map with this method:

public static boolean playerCollisionWith() {
    for(int i = 0; i < Blockmap.entities.size(); i++) {
        Block entity1 = (Block) Blockmap.entities.get(i);
        if(playerPoly.intersects(entity1.poly)) {
            return true;
        }
    }
    return false;
}

This would work normally but I'm using a different method for movement. Instead of just adding a speed variable to the player's X axis. I move like this:

if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
        speedX = Math.min(5, speedX + 1);
        moving = true;

        playerPoly.setX(x);
        if(playerCollisionWith()) {
            speedX = -5;

            playerPoly.setX(x);
        }
    }

That Math.min call is what is messing me up. I can't just call speedX = -5, because when I do the player "bounces" when the right mouse button is down and it's colliding. Bounces as in flashes back and forth really quickly. But I don't really know how I would make it so that collisions on the Y axis would work either, whether the player is jumping or not. So if I could get some help with how to fix this problem that would be great.

EDIT: I just realized something, I have these lines of code which I'm pretty sure has a big effect on my collision problems.

if(!Keyboard.isKeyDown(Keyboard.KEY_LEFT) && speedX < 0 && !playerCollisionWith()) {
            speedX = 0f;

            playerPoly.setX(x);
        }
        if(!Keyboard.isKeyDown(Keyboard.KEY_RIGHT) && speedX > 0 && !playerCollisionWith()) {
            speedX = 0f;

            playerPoly.setX(x);
        }

So when I collide with a wall and I'm no longer pressing the arrow key, than the player drifts into the wall and is all glitchy. Sorry I didn't say that earlier, I just did some more testing. Thanks again!

share|improve this question
add comment

3 Answers 3

The problem is the speedX = -5; assignment in this code:

if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
    speedX = Math.min(5, speedX + 1);
    moving = true;

    playerPoly.setX(x);
    if(playerCollisionWith()) {
        speedX = -5;  // <---- PROBLEM!

        playerPoly.setX(x);
    }
}

In other words, when there's a collision, you set the speed to -5, regardless of which direction the character was going or how fast. If the character was moving forward (positive speedX), it suddenly ricochets backwards. If it was moving backwards at a speed of -4 to -1 inclusive, it suddenly speeds up.

share|improve this answer
add comment

The bouncing happens because you move the Character despite the movement not being valid. In order to prevent it from happening, you should only move the Character after checking if that movement is ok.


if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
    if(!playerCollisionWith()) {
        moving = true;
        speedX = 5;
        playerPoly.setX(x);
    }    
}
share|improve this answer
add comment

Your character is shifting between a speed of +5 and -5 between frames, causing the flashing. I'm not sure what kind of effect you are looking for, so solutions may vary.

Firstly, for input, keep things simple. Modify speed, leave the rest for another function:

if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT) {
    speedX = Math.min(5, speedX + 1);
}

(Note: since you are adding 1 to speed every frame, the rate the character accelerates at will be frame rate dependant, meaning it'll only work as expected at a certain fixed frame rate. Fixing it is beyond the scope of this question, but essentially you'd want to make acceleration/speed a function of time, to have your game work at slower or faster frame rates)

Now you've got your input function. Next, an update function. Here is where you actually move the player, and check for collisions. I haven't programmed in Java for a while, so I apologize for any errors in syntax:

public void update() {
    if (speedX > 0.0f) {  // Check if moving right
        positionX += speedX;
        // positionX += speedX * delta; // would produce a better result (where
                                        // delta is the change in time from the
                                        // last frame to this frame)
        float collisionRight = checkCollisionRight(); // This function checks 
            // collisions to the right, and returns a value for how much the
            // player is intersection. 0 if not intersecting.

        if (collisionRight > 0.0f) {  // Check if collision, if so, resolve collision
            positionX -= collisionRight; // Just shift the player back by
                                         // the amount intersected
            speedX = 0.0f;  // This stops the player if colliding. If you 
                            // want a bounce, the process is more complicated
        }
    }
}

Get the idea? Make collision detection and resolution independent of input, to minimize strange behaviour. The above still isn't perfect (what if the player is moving so fast, they end up moving through a wall, for example), but it's a start. If you want to do some reading on collision detection, look up AABB collision, it's one of the most basic and effective methods for simple collision detection.

share|improve this answer
    
"you'd want to make acceleration/speed a function of time" Or better yet, fix your timestep! –  Colonel Thirty Two Jan 15 at 15:22
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.