Decreasing walk speed over time

hi there, i'm having trouble to figure how to have my player walk speed to decrease over time.

(start walking full speed, then the more you walk the more speed decrease)

i use this to move player upon keypress:

playerNode.getLocalTranslation().x -= cam.getDirection().x * playerSpeed * tpf;
playerNode.getLocalTranslation().z -= cam.getDirection().z * playerSpeed * tpf;

the problem here is that playerSpeed is variable. default is 4f, but user can change that through control screen.
i've made user to be able to change playerSpeed within 1f to 16f range.

i thought this could work:

private float reduce=playerSpeed;
reduce +=tpf*-2;
playerNode.getLocalTranslation().x += cam.getDirection().x * reduce*tpf;
playerNode.getLocalTranslation().z += cam.getDirection().z * reduce*tpf;
//reset reduce each time we finished moving 1 block

that did work, but when i change playerSpeed in the control screen, everything goes wrong..

how could i make walk speed to decrease with variable speed setting ?


My first thought is that you're complicating the problem by combining two things that should be separated:

  1. the translation of the playerNode in the game loop
  2. the changing of the playerSpeed value

    Without knowing more about exactly what you're trying to do, I'm thinking the first has to do with rendering, and the second with that nebulous concept of "game logic".  Create a function that determines what the current playerSpeed should be, and call that function from the game loop.  It may not sound like it will make a difference, but I think it will simplify the issue and you'll be able to find a solution easier.

    Good luck!

I agree with mjsimpson, you are going to probably want to write a method that is something along the lines of:

public float determineSpeed()


    // manipulate the float value that corresponds to the speed here

    return the speed


… then implement this into the rendering part of the code:

playerNode.getLocalTranslation().x -= cam.getDirection().x * this.determineSpeed() * tpf;

playerNode.getLocalTranslation().z -= cam.getDirection().z * this.determineSpeed() * tpf;

I can't know the exact way to do this without seeing your exact code, but I hope this gets you on the right path.

@Treebranch & mjsimpson

tnx for the advices :)
the exact code  can be seen here
private float playerSpeed = TestGameStateSystem.walkSpeed;
is fetch from another class, it's variable. default is 4f. (as of now  in can change from 1f to 16f upon user choice in controls screen).
webstart can be tested from here
as you can see, i move one block at a time, in an animated fashion.
right now the speed is the same along the whole animation (move 1 block). what i'm trying to do is:
when start moving forward or backward, the movementstartfull speed, and decrease along as the movement take place to reach zero when the movement should stop (moved one block)
what do you think ?
would it work if i try with Treebranch code?

I will have more time to actually look at your code later to see if I can help at all, but I would like to mention right now, that as I was running the application, I noticed a few things:

  1. For each time you move "one unit," you have to repress the key, it might be good to be able to continue to move forward as you hold the key pressed down. Also, if I am understanding the goal you want to achieve with the decreasing speed, I think you are going to need the button to work when held down.

  2. I am not sure how it happened, but the camera or character got off the "track" when I bumped up the walk speed and rotation speed a bit. At some point, the camera was angled incorrectly and it lead to running into the wall. I am not sure what went wrong there.

Okay, I just took a brief look at your code and I was looking at the line that said:

private float playerSpeed = TestGameStateSystem.walkSpeed;

What I think would be best to do is to go to your class TestGameStateSystem and have a method that determines the players speed and have that method return walkSpeed, then when you write the above line, you can change it to:

private float playerSpeed = TestGameStateSystem.determineWalkSpeed()

... or something like that. This way, Ingamestate doesn't even have to worry about how fast the player is moving, because it is already done for it. I hope that helps.

tnx but,

it's okay to move only one block at a time. without key repeat. (it's not meant to  be a fps).
the camera getting off track is a problem, i know, i wanted to get the speed reduction done fisrt.

About the playerSpeed its value is already dynamic, having a method to return it, or getting its value like i do now.
i don't see how that could change anything? because this is where my problem is:
when playerSpeed get changed, all the stuff i made for speed reduction fails.
so value being changed is handled it seems.

here's what happen:

1) it works: 1 block movement at a time, speed reduction when moving across a block.
2) user change value of playerSpeed (through "controls" screen, then go back to game)
3) speed reduction doesn't work anymore , and more than 1 block distance is walked.

look like it's working  like this:

                if (dir == Direction.FORWARD) {
                    float value = 0;                   
                    value = playerSpeed*tpf*-1;                     
                    toMove += value;
                    playerNode.getLocalTranslation().x += cam.getDirection().x * toMove*-value;                   
                    if (toMove <= 0) {
                        isMoving = false;
                if (dir == Direction.BACKWARD){
                    float value = 0;
                    value = playerSpeed*tpf;
                    toMove -= value;                   
                    playerNode.getLocalTranslation().x -= cam.getDirection().x * toMove*value;
                    if (toMove <= 0) {
                        isMoving = false;

i had to reduce the move_step to 2.45f  tho..
i've made a new webstart : here
speed decrease as you're nearing toward the end of the move.
tnx for the help:)