1

I'm fairly new to Swing, and I'm attempting to make a simple game in which, at its current stage, you move a box around with w-a-s-d and it faces the mouse cursor. In terms of those functions, I'm having no issues. Unfortunately, where I am having issues is with the application stuttering when few actions are being performed.

For example, if I am moving the box around but the cursor is still, the game starts stuttering badly. However, if I wiggle the cursor, the game runs fine. After some research, it appears that the issue is related to Swing's Component.repaint(). After implementing my understanding of this, though, the stuttering issues are unchanged.

The way I implemented it was by having my abstract base GameObject class extend Component, with all objects displayed in the game being descendants of that class.

In the Game class, the main class of the application, the run function is responsible for updating the objects in the game.

        long lastTime = System.nanoTime();
        double amountOfTicks = 60.0;
        double ns = 1000000000 / amountOfTicks;
        double delta = 0;
        long timer = System.currentTimeMillis();
        int frames = 0;

        while (running) {
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            while (delta >= 1) {
                tick();
                delta--;
            }
            if (running) {
                render();
            }
            frames++;

            if (System.currentTimeMillis() - timer > 1000) {
                timer += 1000;
                System.out.println("FPS: " + frames);
                frames = 0;
            }
        }
        stop();
    }

The tick() and render() functions call the handler, which handles all of the objects.

    private void tick() {
        handler.tick();
    }

The Handler class, complete with my additions of repainting the objects. I added repaint after calling both the tick and render functions of the object, but neither had any major effect.

public class Handler {

    LinkedList<GameObject> objects = new LinkedList<GameObject>();

    public void tick() {
        for (int i = 0; i < objects.size(); i++) {
            GameObject object = objects.get(i);

            object.tick();
            object.repaint();
        }
    }

    public void render(Graphics g) {
        for (int i = 0; i < objects.size(); i++) {
            GameObject object = objects.get(i);

            object.render(g);
            object.repaint();
        }
    }
}

So while these changes didn't seem to help the stuttering in my program, something else did - a print statement in the run function, printing a simple string. I can't for the life of me think how that could possibly be affecting anything, and it certainly isn't a permanent fix, so any advice on the situation would be greatly appreciated

  • 3
    Use a Swing Timer to schedule the animation and the state of the objects should be updated when the Timer fires. For a basic example of this approach check out: https://stackoverflow.com/questions/54028090/get-width-and-height-of-jpanel-outside-of-the-class/54028681#54028681 – camickr Jun 20 '19 at 14:43
  • 2
    You might want to use `Thread.yield()` to release the CPU inside your `while` loop, so other threads have a chance to run. Or you use a `Thread.sleep()` call to wait until it is really time to handle a tick and/or render the scene. No need to render the seen at ridiculous FPS you currently get, where nothing is changed... – Progman Jun 20 '19 at 18:00
  • 1
    Thanks for your help guys, Applying Thread.sleep() appears to have fixed the issue – quantummidget Jun 21 '19 at 04:58

0 Answers0