I am using a Swing Timer in my game but when the game is running it appears to have moments when it runs smoothly and moments when it slows down.
Why is the time fl
Because the rendering is trivial, I find this variation of your example to be very smooth. The render time is well below a half millisecond, so the 12 millisecond period (~83 Hz) is plenty of time to finish a frame, typically taking less that 10% of one core. As the render time grows, the timer thread becomes saturated, and events are coalesced. The effect is magnified on a single core, as rendering competes with garbage collection and external processing demands. Java is not a real-time system, and not all schedulers are created equal.
You'll certainly want to profile your actual code, as suggested here, to see any correlation with fluctuating performance. One alternative approach is to lengthen the period (decrease the frequency) to meet your rendering deadline and use a larger increment in moveImage()
to get the same velocity.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Main extends JFrame {
private static final int W = 800;
private static final int H = 400;
public Main() {
super("JFrame");
this.add(new ImagePanel());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
setSize(W, H);
this.setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Main();
}
});
}
class ImagePanel extends JPanel {
Timer movementTimer;
int x, y;
public ImagePanel() {
x = 0;
y = 0;
movementTimer = new Timer(12, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
moveImage();
repaint();
}
});
movementTimer.start();
}
public void moveImage() {
x++;
y++;
if (x > W) {
x = 0;
}
if (y > H) {
y = 0;
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
long start = System.nanoTime();
g.setColor(Color.RED);
g.fillRect(0, 0, W, H);
g.setColor(Color.BLUE);
g.fillRect(x, y, 50, 50);
double delta = (System.nanoTime() - start) / 1000000d;
g.drawString(String.format("%1$5.3f", delta), 5, 15);
}
}
}