0
\$\begingroup\$

I have a player, that I can control using WASD. And I don't want him to leave the screen.

So I've tried the following:

if (player1.getX()+5 < 974 && player1.getX()-5 > 0) {
    if(Keyboard.isKeyDown(Input.KEY_D)) {
        player1.addForce(5, "d");
    }
    if(Keyboard.isKeyDown(Input.KEY_A)) {
        player1.addForce(5, "a");
    }
    if(Keyboard.isKeyDown(Input.KEY_W)) {
        player1.addForce(5, "w");
    }
    if(Keyboard.isKeyDown(Input.KEY_S)) {
        player1.addForce(5, "s");
    }
} else if(player1.getX() >= 974) {
    player1.addForce(5, "a");
} else if(player1.getX() <= 0) {
    player1.addForce(5, "d");
}

It actually works, but the player gets stuck at the edge of screen, and can't move anymore. Any ideas why? Or rather, how do I make a proper collision detection?

NB: 1024 is the width of screen. And my player is 50 pixels wide, thus the 974. I am only working with X at the momemnt, to try getting it to work.

\$\endgroup\$
3
  • \$\begingroup\$ Collision detection and Collision response are two different things. Keep that in mind \$\endgroup\$
    – Sidar
    Commented Feb 8, 2013 at 9:33
  • \$\begingroup\$ Voting to close for "debug my code for me". \$\endgroup\$ Commented Feb 13, 2013 at 0:00
  • \$\begingroup\$ This sounds reasonable to me (provided there's no duplicate somewhere else). \$\endgroup\$ Commented Feb 13, 2013 at 11:31

5 Answers 5

6
\$\begingroup\$

What that code is doing is limiting motion to only if you're inside the screen. What you should instead do is something like this:

//control code here

if(player.getx() > 1024){
    player.setx(1024);
}else if(player.getx() < 0){
    player.setx(0);
}

that way if the player exceeds the bounds of the screen the position will be set back to the bounds.

\$\endgroup\$
4
  • \$\begingroup\$ That seemed to work, however, now the player is flickering, if i keep moving at 1024 or 0. \$\endgroup\$ Commented Feb 6, 2013 at 18:58
  • \$\begingroup\$ this is due to the player going off screen and then being teleported back, try instead of setting the location, adding force to it in the opposite direction it's going, smoothly pushing it back. I implemented this in my answer. \$\endgroup\$
    – Dylan Katz
    Commented Feb 6, 2013 at 19:02
  • \$\begingroup\$ Didn't seem to solve it. Still flickering \$\endgroup\$ Commented Feb 6, 2013 at 19:04
  • \$\begingroup\$ @KevinJensenPetersen Try using >= 1024 and <= 0 instead. this way the char probably won't teleport back a pixel each time it pushes. \$\endgroup\$
    – petervaz
    Commented Feb 7, 2013 at 13:06
1
\$\begingroup\$

Try this:

 if(player1.getX()+5 < 1024 && player1.getX()-5 > 0) {

        //Player 1
        if(Keyboard.isKeyDown(Input.KEY_D)) {
            player1.addForce(5, "d");
        }
        if(Keyboard.isKeyDown(Input.KEY_A)) {
            player1.addForce(5, "a");
        }
        if(Keyboard.isKeyDown(Input.KEY_W)) {
            player1.addForce(5, "w");
        }
        if(Keyboard.isKeyDown(Input.KEY_S)) {
            player1.addForce(5, "s");
        }
    } else if(player1.xlocation>=1024) {
        player1.addForce(5,"a");
    } else if(player1.xlocation<=0) {
        player1.addForce(5,"d");
    }
\$\endgroup\$
9
  • \$\begingroup\$ addForce is doing it's work in background, with the "-" also. About the answer, it's still stuck! :D \$\endgroup\$ Commented Feb 6, 2013 at 18:42
  • \$\begingroup\$ When it hits the edge of screen \$\endgroup\$ Commented Feb 6, 2013 at 18:42
  • \$\begingroup\$ I think your player is getting off screen, lets reset him. \$\endgroup\$
    – Dylan Katz
    Commented Feb 6, 2013 at 18:48
  • \$\begingroup\$ hmm. try estimating where the player will be before moving, and then prevent the movement from happening if he is past 1024 or less than 0. then if he isn't, allow the move. \$\endgroup\$
    – Dylan Katz
    Commented Feb 6, 2013 at 19:04
  • \$\begingroup\$ Can't really see how to work that one out. \$\endgroup\$ Commented Feb 6, 2013 at 19:07
1
\$\begingroup\$

Compute for the future position first before updating the position of your player:

if( RIGHT is pressed )
{
    var futurePositionX = currentPositionX + increment;

    if( futurePositionX < rightScreenBound )
    {
        currentPositionX = futurePostionX;
    }
    else
    {
        // if futureposition will exceed bound, set position to bound
        // (rightScreenBound is the rightmost possible position)
        currentPositionX = rightScreenBound;
    }
}
\$\endgroup\$
0
\$\begingroup\$

Flickering behavior is correct. It is like throwing ball at the wall and when it bounces away, you punch it back to the wall. It is because you are setting forces instead of positions.

First, you must decide, wheter you want to control the position, or force (speed = derivative of position). If you want to set forces, then:

  • you can not simply add force when button is down. It may grow to infinity.

  • when object reaches the border, set force to zero! don't add force in another direction!

\$\endgroup\$
-1
\$\begingroup\$

The reason it's flickering is probably because you update the possition, then update the image then check for collision then update the possition again and then update the image again.

Instead try to put the collision detection before you update the image.

\$\endgroup\$
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .