// John Kalstrom // Java Fundamentals I animation assignment, 10/97 // "Gratuitous Spinning Corporate Logo" import java.awt.Graphics; import java.awt.Image; import java.awt.Color; import java.util.Random; import java.awt.Event; public class Logo extends java.applet.Applet implements Runnable { Graphics offscreenGraphics; Image offscreenImage; Image logo_pics[]; int logo_MAX; int logo_idx = 0, spin_dir = 1, spin_delay = 100; Thread runner; int xpos = 0, xspd = 5; int ypos = 0, yspd = 5; int XMAX, YMAX, logo_XMAX, logo_YMAX; static int logo_SPEED = 30, BUMPER_SIZE = 5; Random rnd = new Random(); public void init() { logo_pics = new Image[11]; // DecimalFormat fmt = new DecimalFormat("00"); // security violation! // Create offscreen image to draw in. (For double-buffering) // And a graphics object to get at methods to draw on it with XMAX = size().width - 1; YMAX = size().height - 1; offscreenImage = createImage(XMAX, YMAX); offscreenGraphics = offscreenImage.getGraphics(); // 'File("images").list()' generates security violation! logo_MAX = logo_pics.length-1; for (int idx=1; idx <= logo_MAX+1; ++idx) { if (idx < 10) logo_pics[idx-1] = getImage(getCodeBase(), "images/logo0"+ idx + ".gif"); else logo_pics[idx-1] = getImage(getCodeBase(), "images/logo"+ idx + ".gif"); // Actually go get the image, so we can get its size prepareImage(logo_pics[idx-1], this); } // Wait until image has been loaded, then set bounce size while ((checkImage(logo_pics[logo_MAX], this) & (WIDTH | HEIGHT)) != (WIDTH | HEIGHT)) ; logo_XMAX = XMAX - logo_pics[logo_MAX].getWidth(this) - BUMPER_SIZE; logo_YMAX = YMAX - logo_pics[logo_MAX].getHeight(this) - BUMPER_SIZE; } public void start() { if (runner == null) { runner = new Thread(this); runner.start(); } } public void stop() { if (runner != null) { runner.stop(); runner = null; } } public void run() { // Runner thread -- does animation for (logo_idx = 0; Thread.currentThread() == runner; logo_idx += spin_dir) { // Draw if (logo_idx < 0) logo_idx = logo_MAX; if (logo_idx > logo_MAX) logo_idx = 0; offscreenGraphics.setColor(new Color(0xA0, 0x80, 0xFF)); offscreenGraphics.fillRect(0, 0, XMAX, YMAX); // Rubber bumpers offscreenGraphics.setColor(Color.black); offscreenGraphics.fillRect(5, 5, XMAX-10, YMAX-10); // Black background offscreenGraphics.drawImage(logo_pics[logo_idx], xpos, ypos, this); // Logo repaint(); pause(spin_delay); // Move xpos += xspd; if (xpos < BUMPER_SIZE || xpos > logo_XMAX) { xspd = -xspd + (int)(5 * (rnd.nextFloat() - 0.5)); xspd = Math.min(xspd, logo_SPEED); xspd = Math.max(xspd, -logo_SPEED); xpos = Math.min(xpos, logo_XMAX); xpos = Math.max(xpos, BUMPER_SIZE); } ypos += yspd; if (ypos < BUMPER_SIZE || ypos > logo_YMAX) { yspd = -yspd + (int)(5 * (rnd.nextFloat() - 0.5)); yspd = Math.min(yspd, logo_SPEED); yspd = Math.max(yspd, -logo_SPEED); ypos = Math.min(ypos, logo_YMAX); ypos = Math.max(ypos, BUMPER_SIZE); } } } public boolean mouseDown(Event evt, int x, int y) { // Right click -- change direction and speed of spin if (evt.metaDown()) { spin_dir = -spin_dir; spin_delay = 50 + (int)(rnd.nextFloat() * 100); } else { // Left click -- set location of logo xpos = x - (logo_pics[0].getWidth(this) / 2); ypos = y - (logo_pics[0].getHeight(this) / 2); } return true; } void pause(int time) { try { Thread.sleep(time); } catch (InterruptedException e) { } } // Override, to avoid clearing with white public void update (Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(offscreenImage, 0, 0, this); } public void destroy() { offscreenGraphics.dispose(); } }