Hey guys, i've been making a little super mario clone in Java but I need help,

you see, if you download it and play it, you will notice it is quite stutter-y, and that really shouldn't be the case since it's such a small program.

game link : Click Here (scroll down a little to download)

So i assume it's 2 things, either my game loop is faulty (i'll provide the code below) or it's simply that Java just sucks at this, so I'm gonna go with the first one cause i love Java.

Anyways, here's my game loop.

/**
 * Contains the main flow of the game.
 */
private void run() {

    timer.schedule(new TimerTask() {
        private final BufferStrategy bf = frame.getBufferStrategy();
        private long startTime = System.currentTimeMillis();
        private long currTime = startTime;
        @Override
        public void run() {
            elapsedTime = System.currentTimeMillis() - currTime;
            currTime += elapsedTime;
            try {
                //get graphics
                g = bf.getDrawGraphics();
                //get input
                inputGame();
                //update the game
                updateGame(elapsedTime);
                //draw the game
                drawGame(g, elapsedTime);

            } finally {
                    g.dispose();
            }

            // Shows the contents of the backbuffer on the screen.
            bf.show();

            Toolkit.getDefaultToolkit().sync();
        }
    //start this loop every 17 milliseconds, which is roughly 58 frames per second
    }, 10, 17);
}

the variable timer, is of class Timer in Java.util.Timer, not the swing Timer, which i heard is unreliable, but this one is too clearly.

at the moment, I'm not really doing much with elapsedTime, but it's there just in case, i figured i didn't need it since that loop will
run every 17 milliseconds, and my update and rendering methods only take 2-5 milliseconds to finish.

I have another issue though, sometimes when i run the game with no background tasks going on (web browser, itunes etc), the loop only runs every 32 milliseconds instead of the intended 17, however, if i open other tasks it runs as intended, any ideas as to why this happens?

Do you guys know of very effective game loops that provide very smooth rendering?

I can provide more code if necessary, Thanks in advance!

Edited 4 Years Ago by thanatos1

DIY loops and graphics are not the way to go. Swing is in charge of Java GUIs, so you have to operate within swing's design assumptions.
Swing Timer is the timer used by Swing itself - you can definitely rely on it. Also its the only one that ensures you avoid swing threading problems. Here's the template for how to use a swing timer for animation (it's a fully runnable program)

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MiniAnimation extends JFrame implements ActionListener {
   // absolutely minimal example of how to structure animation in Swing

   public static void main(String[] args) {
      new MiniAnimation();
   }

   private int xPos = 0; // current position(s) of animated object(s)


   MiniAnimation() {
      buildWindow();
      // start Timer to call actionPerformed 20 times/sec...
      new javax.swing.Timer(50, this).start();
   }

   void buildWindow() {
      // build a minimal working window...
      this.setTitle("Minimal Swing Animation Demo");
      setMinimumSize(new Dimension(300, 200));
      setLocationRelativeTo(null);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setVisible(true);
   }

   public void actionPerformed(ActionEvent arg0) {
      // called by Timer 20 times/sec
      xPos += 1; // update position(s) of object(s)
      repaint(); // request screen refresh
   }

   @Override
   public void paint(Graphics g) {
      // screen refresh - called by Swing as needed
      // override paintComponent instead if extending JPAnel
      super.paint(g); // ensure background etc is painted
      g.fillRect(xPos, 50, 100, 100); // paint object(s) at latest position(s)
   }

}

oh okay thank you, but here's where i get confused, since i was reading for a while regarding how to properly deal with smooth graphics and animations in Java, and I always read that using the paint method was never a good idea since you never knew when it would actually get called, the calls to paint could either happen more than once per frame, or it would never happen at all and so forth.

But i will give this a try now, thanks for the help.

That's why we separate updating the model from updating the GUI.
Remember also that a lot of the stuff you see on the web is many years out of date, so, for example, you no longer need to double-buffer things because Swing now double-buffers ny default.
Just try it - it works.

This article has been dead for over six months. Start a new discussion instead.