[Newbie]Need feedback on achieving smooth animation

Hi all,

First post here. I have been using Java for a few years now but never programmed games. I am learning how to program simple games like pong, etc and will slowly advance to more difficult games. The game loop I understand at a basic level and created pong with a very basic loop, but without using delta time, etc. My loop was literally this:

while(running){
      update(); //move object positions     
      checkCollisions(); //check if objects collided
      repaint();  // call paint to re draw the screen

      Thread.sleep(16) //this is ~60 fps
}

Below is some I code I have written that animates moving square moving back and forth across the screen. So far, I have also figured out how fps is calculated and that is what you sleep by, but that is it really. Unfortunately, the square seems to be jumping during the animation at certain points. The motion is visibly choppy. At the moment, every update I want it to move at a speed/velocity of 5, but it jumps too much and is very noticeable. I also realise it might run slower/faster on your computer. On my machine, fps is getting printed out as 62/63 when the ‘game’ is running. So I have 2 or 3 frames to spare.

    package com.game;

    import java.awt.Dimension;
    import java.awt.Graphics;
    import static java.util.concurrent.TimeUnit.NANOSECONDS;
    import javax.swing.JFrame;

    import javax.swing.JPanel;

    class GamePanel extends JPanel implements Runnable {

        //Panel specific stuff
        private static Dimension dimension = new Dimension(800, 400);

        //Square drawing stuff
        private double x = 0, y = 0;
        private double xDir = 5;
        private double squareWidth = 50;

        //Game thread stuff
        private Thread gameThread = new Thread(this);
        private boolean running = true;
        private long targetFps = 1000 / 60;

        public GamePanel() {
            setPreferredSize(dimension);
        }

        @Override
        public void run() {
            gameLoop();
            System.out.println("Game loop complete");
            //System.exit(0);
        }

        private void gameLoop() {
            int fps = 0;
            long timeAtLoopStart = 0;
            long timeAtLoopEnd = 0;
            long frameTime = 0;
            long loopTimer = NANOSECONDS.toSeconds(System.nanoTime());
            while (running) {
                timeAtLoopStart = NANOSECONDS.toSeconds(System.nanoTime());
                fps++;

                if (timeAtLoopStart == loopTimer + 1) {
                    System.out.println("FPS is: " + fps);
                    fps = 0;
                    loopTimer = NANOSECONDS.toSeconds(System.nanoTime());
                }

                //check fps to see if we are over our target fps
                if(loopFPS > FPS){
                //if we are here we have processed more frames than our target fps in one second
                    // do something??
                }

                update();
                checkCollisions();
                repaint(); //paintComponents

                timeAtLoopEnd = NANOSECONDS.toSeconds(System.nanoTime());
                frameTime = timeAtLoopEnd - timeAtLoopStart;
                // System.out.println(frameTime);
                try {
                    Thread.sleep(targetFps);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }

        private void update() {
            x = x + xDir; //use delta time here somehow?
            if (x + squareWidth == dimension.width) {
                xDir = -5; //go left if we hit the right side
            }
            if (x == 0) {
                xDir = 5; //go right if we hit the left side
            }
        }

        private void checkCollisions() {
               //TODO
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.fillRect((int) x, (int) y, (int)squareWidth, (int)squareWidth);
        }

        public void start() {
            gameThread.start();
        }

        public static void main(String[] args) {
            JFrame jf = new JFrame("Game");
            GamePanel gp = new GamePanel();
            jf.add(gp);
            jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jf.setLocationByPlatform(true);
            jf.pack();
            jf.setVisible(true);
            gp.start();
        }
    }

Sorry for the long post, but I would like to (using this code) to achieve smooth motion using whatever speed I give xDir. I have seen articles related to game loops, etc. and have tried to use them but I am not understanding them correctly. Maybe I am and the code above is actually fine, and I am just being to critical of the animation. Could someone please run the above code and give feedback?

Just to note: I tried avoiding the repaint method in a further update of the above code and used the “double buffer” strategy where you draw to a separate image and then paint the whole image to the jpanel. That didn’t smooth out the motion either so I reverted back to repaint (for no particular reason I might add).

Thanks