So, this is a thing. I've got a simple little 2D game where a character can run left and right and jump. My problem here is that I've got two velocities, xVel and yVel, that I need to increment as the character runs in a certain direction, and stop altogether as the player stops moving altogether. Right now, I'm only focusing on xVel. So we have the player class, which contains the movement methods. I've got two booleans to determine when to increment the velocities, goingRight and goingLeft. When going left, goingRight is false and goingLeft is true, and vice versa. The only problem is that when the player doesn't move, he shouldn't have any velocity. But there isn't a way to determine when the player isn't moving.Now, the above is my setup for velocities and such so that the player can run into a jump and move in the air. I'm getting confused just trying to think about it, and overall, it just feels disorganized. Am I doing this right, and if so, what can I do to improve it? If not, what would be the best approach for adjusting these velocities and making player movement more smooth. I'll post both classes for the game below so that you can analyze what I'm doing wrong. I don't necessarily need code corrected, but I would like a solid understanding and explanation of what I can do to improve the continuity of the game's movement.Main class: import com.hasherr.platformer.entity.Player;import org.lwjgl.LWJGLException;import org.lwjgl.input.Keyboard;import org.lwjgl.opengl.Display;import org.lwjgl.opengl.DisplayMode;import static org.lwjgl.opengl.GL11.*;public class Main {    private void display() {        try {            Display.setDisplayMode(new DisplayMode(1000, 550));            Display.setTitle(Unnamed Platformer Game);            Display.create();        } catch (LWJGLException e) {            e.printStackTrace();            System.exit(0);        }        // OpenGL        while (!Display.isCloseRequested()) {            Display.update();            Display.sync(60); // sync to 60 fps            initGL();            player.update();            handleKeyboardInput();          }        Display.destroy();    }    private void handleKeyboardInput() {        if (!player.goingLeft && !player.goingRight) {            player.xVel = 0;        }        if (Keyboard.isKeyDown(Keyboard.KEY_D)) {            player.moveRight();        } else if (Keyboard.isKeyDown(Keyboard.KEY_A)) {            player.moveLeft();        } else if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {            player.jump();        }    }    private void initGL() {        // initial OpenGL items for 2D rendering        glClear(GL_COLOR_BUFFER_BIT);        glEnable(GL_TEXTURE_2D);        glMatrixMode(GL_MODELVIEW);        glLoadIdentity();        glOrtho(0 , 1000, 0, 550, 1, -1);        // start rendering player image        player.grabTexture().bind();        glBegin(GL_QUADS);        glTexCoord2f(0, 0);        glVertex2f(player.xPos, player.yPos);        glTexCoord2f(1, 0);        glVertex2f(player.xPos + 150, player.yPos);        glTexCoord2f(1, 1);        glVertex2f(player.xPos + 150, player.yPos + 150);        glTexCoord2f(0, 1);        glVertex2f(player.xPos, player.yPos + 150);        glEnd(); // stop rendering this image    }    Player player = new Player();    public static void main(String[] args) {        Main main = new Main();        main.display();    }}Player class: import java.io.IOException;import org.newdawn.slick.opengl.Texture;import org.newdawn.slick.opengl.TextureLoader;import org.newdawn.slick.util.ResourceLoader;public class Player {    public Texture playerTexture;    // Positions & speed    public float xPos = 20.0f; // This is initial    public float yPos = 0.0f; // Same as above.    public float xVel, yVel;    public static int gravityForce = 6;    public static int jumpVelocity = 100;    private static int moveSpeed = 15;    public boolean isSupported = true; // Once again, initial value.    public boolean goingRight, goingLeft;    // movement methods    public void update() {        applyGravity();        checkForSupport();    }    private void checkForSupport() {        if (yPos == 0) {            isSupported = true;        } else if (yPos > 0 /* and is not on a platform */) {            isSupported = false;        }    }    public Texture grabTexture() {        try {            playerTexture = TextureLoader.getTexture(PNG, ResourceLoader                    .getResourceAsStream(resources/test_char.png));        } catch (IOException e) {            e.printStackTrace();        }        return playerTexture;    }    private void applyGravity() {        if (!isSupported) {            yPos -= gravityForce;            if (yPos < 0) {                yPos = 0;            }        }    }    private void printPos(String moveMethod) {        System.out.println(moveMethod +  X:  + xPos +  Y:  + yPos                +  Left:  + goingLeft +  Right:  + goingRight);    }    // movement methods    public void moveRight() {        xPos += moveSpeed;        goingRight = true;        goingLeft = false;        printPos(Moving right!);    }    public void moveLeft() {        xPos -= moveSpeed;        goingRight = false;        goingLeft = true;        printPos(Moving left!);    }    public void jump() {        if (isSupported) {            yPos += jumpVelocity;        }    }    public void shoot() {        // do shooty stuff here    }}
Issue regarding game velocity
java;opengl;physics
The movement of your character is going to feel a bit unnatural in this setup. When you hit the left key, the character will immediately start moving left at full speed; as soon as you stop hitting the key, the character will stop dead. I suggest modeling the character's velocity as well as its position, so that e.g. while holding on the left key, the character's velocity decreases steadily until it reaches a minimum. Likewise, modeling gravity as a constant velocity instead of an acceleration will lead to unnatural looking jumps.As for the goingLeft and goingRight bools, they seem like an awkward way to manage state, and it will require great care as your control scheme becomes more complex to maintain a consistent state. If you need to maintain this information beyond (or instead of) the velocity I suggest, consider an enum with the values XMOTION_LEFT, XMOTION_STOPPED, XMOTION_RIGHT, or similarly descriptive names.