0

Allow me to begin by mentioning my description may not be completely understandable. I honestly have trouble finding the words to describe this problem, so I compiled my code into a executable jar you may run to try to understand what I am saying.

Here is the link: http://www.mediafire.com/download/r1n0ox8ioyzwb2n/WORK.jar

As the image is moved (via the arrow keys) to any direction the image will have a weird effect. I can only describe the effect as the image being drawn from top left to bottom right slow enough to be visibly noticeable. If I had to guess I believe it may have to do with the sleeping that is being done in my game loop. Here is my game loop and render method.

public void gameLoop() {
    final int FPS = 60;

    int frames = 0;
    lastTime = System.nanoTime();
    long lastFPS;
    lastTime = lastFPS = System.nanoTime();
    init();
    while (running) {
        long deltaTime = System.nanoTime() - lastTime;
        lastTime += deltaTime;

        if (!frame.isFocusOwner()||!isFocusOwner())
            update(deltaTime);
        else{
            updateFocus(deltaTime);
        }

        // Must setup these do-while loops like this according to
        // BufferStrategy's Javadoc
        render();
        // calculate the FPS
        frames++;
        if (System.nanoTime() - lastFPS >= 1e9) {
            fpsValue = frames;
            frames = 0;
            lastFPS += 1e9;
        }

        // Gets the remaining number of milliseconds left in the frame
        long sleepTime = Math
                .round((1e9 / FPS - (System.nanoTime() - lastTime)) / 1e6);
        if (sleepTime <= 0)
            continue;

        // this sleeping method uses Thread.sleep(1) for the first 4/5 of
        // the sleep loop, and Thread.yield() for the rest. This gives me an
        // accuracy of about 3-4 microseconds
        long prev = System.nanoTime(), diff;
        while ((diff = System.nanoTime() - prev) < sleepTime) {
            if (diff < sleepTime * 0.8)
                try {
                    Thread.sleep(1);
                } catch (Exception exc) {
                }
            else
                Thread.yield();
        }
        sync(60);
    }
    stop();

}

 public void sync(int sync) {
     if (sync!=-1) {
        long diff = 1000000000L / sync + lastTime;
        long now = System.nanoTime();

        try {
           while (diff > now) {
              Thread.sleep((diff-now) / 2000000L);
              now = System.nanoTime();
           }
        } catch (Exception e) {}

        lastTime = now;
     } 
}

public void render() {

    BufferStrategy strategy = getBufferStrategy();
    if (strategy == null) {
        createBufferStrategy(3);
        return;
    }

    do {
        do {
            Graphics2D g = (Graphics2D) strategy.getDrawGraphics();

            // draw your game

            g.drawImage(image, 0, 0, getWidth(), getHeight(), null); 
            render.setGraphics(g);

            // clear the screen
            render.clear();

            if (sbg != null) {
                try {
                    sbg.renderState(render, g);

                    // if not focused we draw a focus nagger
                    if (!frame.isFocusOwner() && !isFocusOwner()
                            && sbg.getNagState() != null) {
                        sbg.getNagState().render(render, g);
                    }
                } catch (VulpusException e) {
                    e.printStackTrace();
                }
            }

            if (drawFPS) {
                g.setColor(Color.white);
                g.drawString("FPS: " + fpsValue, 15, 20);
            }

            g.dispose();
            Toolkit.getDefaultToolkit().sync();
        } while (strategy.contentsRestored());

        strategy.show();
    } while (strategy.contentsLost());

}

The sync method allows it to actually run at 60fps, otherwise the game would be running 1000+ fps. If you have any idea's / suggestions / need me to clarify anything please ask. Thanks again in advance.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Evan Nudd
  • 216
  • 2
  • 10
  • I get the feeling like your sleep and fps is not accurate. You might try simplifying the whole sync part and the while loops to just a single sleep method of delta time. – ug_ Apr 07 '14 at 03:17
  • 1
    Is your game loop running in the Event Dispatch thread or a separate thread? It should be running in a separate thread, with Swing component calls in the game loop going through the invokeLater method of SwingUtilities. – Gilbert Le Blanc Apr 07 '14 at 03:18
  • Runs smoothly here. Are you talking about http://en.wikipedia.org/wiki/Screen_tearing ? (I always wondered why people are using own BufferStrategies for simple things like this, but this is only remotely related to the question...) – Marco13 Apr 07 '14 at 08:25
  • Its running on a separate thread that calls the game loop method – Evan Nudd Apr 07 '14 at 12:29

0 Answers0