Have repaint
(which triggers update
)
avoid clearing the screen each time as follows:
public void update(Graphics g) { paint(g); } |
Then, assuming objects dont overlap, erase each object at its old location by drawing a solid rectangle in the background color, then draw at the new location.
import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.util.Vector; //---------------------------------------------------- /** Bounce circles around on the screen. * Doesn't use double buffering so has problems * with overlapping circles. Overrides update * to avoid flicker problems. */ public class Bounce extends Applet implements Runnable, ActionListener { private Vector circles; private int width, height; private Button startButton, stopButton; private Thread animationThread = null; public void init() { setBackground(Color.white); width = getSize().width; height = getSize().height; circles = new Vector(); startButton = new Button("Start a circle"); startButton.addActionListener(this); add(startButton); stopButton = new Button("Stop all circles"); stopButton.addActionListener(this); add(stopButton); } //---------------------------------------------------- /** When the "start" button is pressed, start the * animation thread if it is not already started. * Either way, add a circle to the Vector of * circles that are being bounced. * * When the "stop" button is pressed, stop * the thread and clear the Vector of circles. */ public void actionPerformed(ActionEvent event) { if (event.getSource() == startButton) { if (circles.size() == 0) { // Erase any circles from previous run. getGraphics().clearRect(0, 0, getSize().width, getSize().height); animationThread = new Thread(this); animationThread.start(); } int radius = 25; int x = radius + randomInt(width - 2 * radius); int y = radius + randomInt(height - 2 * radius); int deltaX = 1 + randomInt(10); int deltaY = 1 + randomInt(10); circles.addElement(new MovingCircle(x, y, radius, deltaX, deltaY)); } else if (event.getSource() == stopButton) { if (animationThread != null) { animationThread = null; circles.removeAllElements(); } } repaint(); } //---------------------------------------------------- /** Each time around the loop, call paint and then * take a short pause. The paint method will * move the circles and draw them. */ public void run() { Thread myThread = Thread.currentThread(); // Really while animationThread not null while(animationThread==myThread) { repaint(); pause(100); } } //---------------------------------------------------- /** Skip the usual screen-clearing step of update * so that there is no "flicker" between each * drawing step. */ public void update(Graphics g) { paint(g); } //---------------------------------------------------- /** Erase each circle's old position, move it, * then draw it in new location. */ public void paint(Graphics g) { MovingCircle circle; for(int i=0; i<circles.size(); i++) { circle = (MovingCircle)circles.elementAt(i); g.setColor(getBackground()); circle.draw(g); // Old position circle.move(width, height); g.setColor(getForeground()); circle.draw(g); // New position } } //---------------------------------------------------- // Returns an int from 0 to max (inclusive), // yielding max + 1 possible values. private int randomInt(int max) { double x = Math.floor((double)(max + 1) * Math.random()); return((int)(Math.round(x))); } //---------------------------------------------------- // Sleep for the specified amount of time. private void pause(int milliseconds) { try { Thread.sleep((long)milliseconds); } catch(InterruptedException ie) {} } } |
/** An extension of SimpleCircle that can be moved * around based on deltaX and deltaY values. Movement * will continue in a given direction until the * edge of the circle reaches a wall, in which case it * will "bounce" and move the other direction. */ public class MovingCircle extends SimpleCircle { private int deltaX, deltaY; public MovingCircle(int x, int y, int radius, int deltaX, int deltaY) { super(x, y, radius); this.deltaX = deltaX; this.deltaY = deltaY; } public void move(int windowWidth, int windowHeight) { setX(getX() + getDeltaX()); setY(getY() + getDeltaY()); bounce(windowWidth, windowHeight); } private void bounce(int windowWidth, int windowHeight) { int x = getX(), y = getY(), radius = getRadius(), deltaX = getDeltaX(), deltaY = getDeltaY(); if ((x - radius < 0) && (deltaX %lt; 0)) setDeltaX(-deltaX); else if ((x + radius > windowWidth) && (deltaX > 0)) setDeltaX(-deltaX); if ((y -radius < 0) && (deltaY < 0)) setDeltaY(-deltaY); else if((y + radius > windowHeight) && (deltaY > 0)) setDeltaY(-deltaY); } public int getDeltaX() { return(deltaX); } public void setDeltaX(int deltaX) { this.deltaX = deltaX; } public int getDeltaY() { return(deltaY); } public void setDeltaY(int deltaY) { this.deltaY = deltaY; } } |
© 1996-99 Marty Hall, 1999 Lawrence M. Brown