-
Choppy motion / graphics
I have an applet thats sort of a 2-d physics simulator, you can shoot a ball and bounce off walls and slopes, but the animation is really "choppy." It doesnt lag, but the ball kind of flickers and such. the applet sleeps for '6' each frame (Thread.sleep(6);) but it still flickers at larger numbers. the ball is simply a g.fillOval.
any ideas?
i would post it if i knew how, would have to be a zip because im using 9 classes
-
Is it a Swing app or an AWT app? If Swing, I would use a Swing Timer. Either way, you should never call Thread.sleep on the EDT, the event dispatch thread.
-
its an awt applet, and why not use sleep, i just run an endless loop that runs a couple functions and a repaint.
-
Because if you sleep on the main thread, you'll put your painting to sleep. I recommend that you graduate to Swing and again use a Swing Timer. If you can't do this, then do your sleeping in a background thread.
-
Can you post the smallest code possible that shows your techniques, for instance something that moves a box along the applet, nothing more? It needs to be something we can compile and run.
-
For example compare this simple Applet animation code:
Code:
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@SuppressWarnings("serial")
public class MyApplet extends Applet {
private static final int SIDE = 20;
int x = 10;
int y = 10;
public void init() {
super.init();
addMouseListener(new MouseAdapter() {
private static final long ANIMATION_DELAY = 6;
private boolean moving = false;
public void mousePressed(MouseEvent e) {
if (!moving) {
new Thread(new Runnable() {
public void run() {
moving = true;
while (x < 1200 && moving) {
x++;
y++;
try {
Thread.sleep(ANIMATION_DELAY);
}
catch (InterruptedException e1) {
}
repaint(x - 10, y - 10, x + SIDE + 10, y + SIDE + 10);
}
}
}).start();
} else {
moving = false;
x = 10;
y = 10;
repaint();
}
}
});
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(x, y, SIDE, SIDE);
}
}
With this Swing JApplet code that uses a Swing Timer:
Code:
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JApplet;
import javax.swing.JPanel;
import javax.swing.Timer;
@SuppressWarnings("serial")
public class MyJApplet extends JApplet {
private static final int SIDE = 20;
protected static final int TIMER_DELAY = 6;
int x = 10;
int y = 10;
private JPanel panel = new JPanel() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
myPaint(g);
}
};
@Override
public void init() {
panel.addMouseListener(new MouseAdapter() {
private Timer timer = null;
private boolean moving = false;
public void mousePressed(MouseEvent e) {
if (!moving) {
timer = new Timer(TIMER_DELAY, new ActionListener() {
public void actionPerformed(ActionEvent e) {
x++;
y++;
repaint(x - 4, y - 4, x + SIDE + 4, y + SIDE + 4);
}
});
moving = true;
timer.start();
} else {
timer.stop();
x = 10;
y = 10;
moving = false;
repaint();
}
}
});
getContentPane().add(panel);
}
private void myPaint(Graphics g) {
g.fillRect(x, y, SIDE, SIDE);
}
}