Is this really the reason for smoother movement?

Actually i'm watching a tutorial series on youtube about 2D Game programming in Java. My question is about the player-movement.

The first version:

        public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();

if(key == KeyEvent.VK_RIGHT) {
player.setX(p.getX() + 5);
}else if(key == KeyEvent.VK_LEFT) {
player.setX(p.getX() - 5);
}else if(key == KeyEvent.VK_DOWN) {
player.setY(p.getY() + 5);
}else if(key == KeyEvent.VK_UP) {
player.setY(p.getY() - 5);
}
}


The problem in this first version is, that if you press now for example VK-RIGHT (and holding it), than the figur in the game moves first one step to the right, then stops for a half second or so and then the figur moves constantly to the right. The problem here is the stopping, which takes a half second or so. This is not smooth.

Then the author of the tutorial presented a second, better version:

        public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();

if(key == KeyEvent.VK_RIGHT) {
player.setVelX(5);
}else if(key == KeyEvent.VK_LEFT) {
player.setVelX(-5);
}else if(key == KeyEvent.VK_DOWN) {
player.setVelY(5);
}else if(key == KeyEvent.VK_UP) {
player.setVelY(-5);
}

}

public void keyReleased(KeyEvent e) {

int key = e.getKeyCode();

if(key == KeyEvent.VK_RIGHT) {
player.setVelX(0);
}else if(key == KeyEvent.VK_LEFT) {
player.setVelX(0);
}else if(key == KeyEvent.VK_DOWN) {
player.setVelY(0);
}else if(key == KeyEvent.VK_UP) {
player.setVelY(0);
}

}


and the tick() method in the Player.java:

public void tick() {
x += velX;
y += velY;
}


The author said, that the second version is smoother, because we don't need to ask first with the get-methods the actually value of x/y. Is this really the reason, why the second method is smoother respectively we don't have still this stop for a half second or so?

If this is really the reason, why the start time of the player figur is in both version the same? In the first version the player figure would then have to need more time to start movement? But this is not the case! The difference is this stop for a half second or so after the first steop of movement is finished.

The get methods do not take so much time, so you're right - this isn't the reason. What's probably happening is that the KeyEvents aren't executed every tick, but are showing the same behaviour as you expect in a browser or anywhere else - when writing something and you move the cursor with the arrow keys, it first moves one space, then stops, and only after half a second or so continues moving. In the second version, you only use the KeyEvent to set the velocity of the player, which is then applied on every tick without pause.

• For what its worth, this is related to the 'repeat delay' in Windows (though I think most systems have something similar) and will be different for each user. It represents the time between holding a key down and the system spamming the key press (as fast as indicated by the 'repeat rate'). Jan 3 '14 at 15:46
• I'm pretty sure Java has something for just detecting keyDown - this is fired off once, immediately when the key is pressed down. That combined with keyUp (or equivalent - been a while since I did Java) gives you a much more exact keyboard handler. No idea why the author went with keyPressed and keyReleased. Jan 11 '14 at 16:22

The first method relies directly on the key presses.

It's a standard behavior ( probably coming from the operating system ) for there to be a delay before it starts repeating itself. That's why it moves, then stops and then keeps moving afterwards.

The second method sets a value for the velocity which is then applied to the x position. It's not exactly clear whether your event or tick() function is called first.

When you press the right key, it adds 5 ( or subtracts it if it's the left key) from the x value. When you release the key the velocity is set to 0. So when the tick() function is called 0 is added to the x property.

You have to think in logical steps. It's smoother in the sense that the movement depends on a value rather than a direct key press. You basically "turn" the value "on" by key presses and "turn" it "off" by releasing a key.

Edit: A lot of game frameworks come with something like an Input manager which you can check in your tick() or update() function.

No, the game code has nothing to do with it. I don't know where he got that idea from and if that is what he said, you should look elsewhere for tutorials. Sounds more like BIOS / OS-level key-repeat functionality to me, which should be bypassed for games.

Typically there are two types of key / button input supported for games:

• Press OR press-and-hold results in a single frame's worth of action (like hitting F1 for help -- holding makes no difference)
• Press and hold results in contininuous action between frames (like holding for movement)

Usually the underlying input API is written in such a way that the key-repeat functionality is ignored altogether, and input values are stored in a boolean buffer that indicates whether each key is up or down. Then additional functionality such as one-press keys (F1) can be built on top of that.

You can certainly do that in Java quite easily, as I have in the past.