[quote=“synLB”]
There’s many approaches to do this, but the generally used one (and the one I prefer) is to do it the following way:
- the update() method updates the players state, i.e. the player does in fact change position, orientation etcetera. Similarly pretty much every thing in your game will be update()d every frame. After the game state has changed (i.e. the player has moved) you can render the new game state. Every game loop generally follows the same pattern: update the game state in one go, then render the new game state.
- other methods, like moveUp(), moveDown() should not directly move the player but instead set how the next update will play out. E.g. if you call moveUp() that would mean that the next update your player will move up a bit (depending on how much time has passed since the last frame, and the movement speed).
Doing all the update in one method makes it much easier to do more advanced stuff like more complex movement, collision detection etctera. Instead of having the moveUp() method set velocity, for example, you could make it set accelleration (change in velocity per second) and then change velocity and position in the update.
About the keyboard handling: the idea here is similar to what I described above. You should call the keyHandler.poll() method every frame (ideally before updating the player and other things to make it as responsive as possible), e.g.
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
long lastFpsTime = 0;
int fps = 0;
while (loopCondition) {
keyHandler.poll(); // poll keyboard here
long now = System.nanoTime();
long updateLength = now - lastLoopTime;
lastLoopTime = now;
You should remove anything referring to the player from the KeyboardHandler class and leave it as you copied it. Then give movement commands (like what direction to move) to the player from the Game’s main update loop (you can think of this as the place where you link inputs to game commands). After that update the game state (in this case player 1 and 2 positions): (I move the poll a bit down here)
if (lastFpsTime >= 1000000000) {
System.out.println("(FPS: " + fps + ")");
lastFpsTime = 0;
fps = 0;
}
// do game updates
keyHandler.poll(); // poll keyboard here
if (keyHandler.keyDown(KeyEvent.VK_UP)) {
player1.setya(-1);
}
if (keyHandler.keyDown(KeyEvent.VK_DOWN)) {
player1.setya(1);
}
// and so on ...
// updates (moves) the player according to the delta calculated and velocity set
// above
player1.update(delta);
player2.update(delta);
Also the setMapPositionXBefore() calls in the Game class can be moved to the Player’s update class, which is much nicer. E.g.
public void update(double delta) {
// mapPositionX&Y are floats, therefore another cast
setMapPositionXBefore(getMapPositionX());
setMapPositionYBefore(getMapPositionY());
if (this.onTrack == true) {
mapPositionX = (float) (mapPositionX + xa * delta);
mapPositionY = (float) (mapPositionY + ya * delta);
You could do the same with the location checking.
Some more advice:
- avoid using full paths (like the “C:/Users/racingtrack.png” etc) as this makes your game unusable on other computers and makes it hard to keep track of everything. Always use a path relative to your application, e.g. in a “data” subdirectory, and then use e.g. “data\racingtrack.png” as the path.
- you take an interesting approach towards checking whether the player is on the track. Its a creative solution and it could work. Collision detection is quite difficult to do right, though, but it is a great thing to learn.