Beginner Design Questions

[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.

I changed it in my code according to your sugestion. Every key should then have an if statement like that:

 if (keyHandler.keyDown(KeyEvent.VK_UP)) {
                player1.setya(-1);
            }

should I move this code to a method or even another class? With several keys this would get unhandy. And could I even change the key values for that (clicking a button and the next key will be up/down/left/right)?

These changes seem to work fine, I have just one question about collision detection:
I tried to detect when the player is out of the racing track and move his position to the point where he was still in the track but somehow the point just gets stuck and can’t move anymore.

	public void update(double delta, GameHelper gameHelper) {
		// mapPositionX&Y are floats, therefore another cast
		gameHelper.checkLocation(this);

		if (onTrack) {
			mapPositionX = (float) (mapPositionX + xa * delta);
			mapPositionY = (float) (mapPositionY + ya * delta);
		} else {
			System.out.println("not on track");
			mapPositionX = mapPositionXBefore;
			mapPositionY = mapPositionYBefore;
		}

	}

and I set the mapPositionXBefore( I know, bad name ;)) here in the game loop:

player1.setMapPositionXBefore(player1.getMapPositionX());
			player1.setMapPositionYBefore(player1.getMapPositionY());
			player2.setMapPositionXBefore(player2.getMapPositionX());
			player2.setMapPositionYBefore(player2.getMapPositionY());

			// Poll the KeyboardHandler!!!
			keyHandler.poll();

			// player 1
			if (keyHandler.keyDown(KeyEvent.VK_UP)) {
				player1.setya(-1);

			}

[quote=“synLB,post:22,topic:47805”]
You could move it to a seperate method (e.g. handleInput). I dont really understand what you mean by changing the key values?

[quote=“synLB,post:22,topic:47805”]
Yeah thats where things get “interesting” ;D Collission detection and physics is often quite hard to get right. Things get stuck to walls, drop through or just generally explode in interesting directions, without any clear reason.

Do you use an IDE like Eclipse? For problems like these debugging is a great help. You can go through your program line by line and see what happens with the variables. From your problem description I expect the issue is with the checkLocation method, but I dont have time to figure out precisely what the issue is. Good luck!

Say if I wanted to change the key that moves the player forward/backwards/left/right could I assign this to another key by clicking a button that registers the next key that is pressed?

Yeah I use Eclipse and know the basics of debugging, creating breakpoints and moving through the code, I will try to do this.

Thanks for the help :slight_smile:

Hey chaps please consider using the JGO pastebin for large bits of code.

Cas :slight_smile:

Good one, I have to get used to pastebin a bit more.

Sure, you could store this in an InputConfiguration class or something, which links each game command to an input (e.g. keyboard key or mouse press).