/* * @(#)Balls.java 1.10 98/06/29 * * Copyright 1998 by Sun Microsystems, Inc., * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. * All rights reserved. * * This software is the confidential and proprietary information * of Sun Microsystems, Inc. ("Confidential Information"). You * shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with Sun. */ package demos.Mix; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import J2DCanvas; /** * Three animated color balls bouncing. */ public class Balls extends J2DCanvas { private Ball balls[]; private Color colors[] = { Color.red, Color.green.darker(), Color.blue }; private long lasttime; private int clearNum = 1; private boolean active; public Balls() { setBackground(Color.white); balls = new Ball[colors.length]; runnable = true; } public void drawDemo(Graphics2D g2) { if (newBufferedImage) { for (int i = 0; i < colors.length; i++) balls[i] = new Ball(colors[i], w, h); lasttime = System.currentTimeMillis(); clearCanvas = true; } long now = System.currentTimeMillis(); long deltaT = now - lasttime; active = false; for (int i = 0; i < balls.length; i++) { balls[i].step(deltaT); if (balls[i].Vy > .02 || -balls[i].Vy > .02 || balls[i].y + balls[i].bwidth < h) { active = true; } } if (!active) { for (int i = 0; i < balls.length; i++) { balls[i].Vx = (float)Math.random() / 4.0f - 0.125f; balls[i].Vy = -(float)Math.random() / 4.0f - 0.2f; } clearCanvas = clearNum++%2 == 0; if (clearNum > 100) clearNum = 1; } for (int i = 0; i < balls.length; i++) { Ball b = balls[i]; if (b == null) continue; if (b.imgs[b.index] == null) continue; g2.drawImage(b.imgs[b.index], (int) b.x, (int) b.y, this); } lasttime = now; } public static void main(String s[]) { final Balls demo = new Balls(); WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} public void windowDeiconified(WindowEvent e) { demo.start(); } public void windowIconified(WindowEvent e) { demo.stop(); } }; Frame f = new Frame("Java2D Demo - Balls"); f.addWindowListener(l); f.add("Center", demo); f.pack(); f.setSize(new Dimension(400,300)); f.show(); demo.start(); } public class Ball { public int bwidth, bheight; public float x, y; public float Vx = 0.1f; public float Vy = 0.05f; public int nImgs = 5; public BufferedImage imgs[]; public int index = (int) (Math.random() * (nImgs-1)); private final float inelasticity = .96f; private final float Ax = 0.0f; private final float Ay = 0.0002f; private final float Ar = 0.9f; private final int UP = 0; private final int DOWN = 1; private int indexDirection = UP; private int w, h; public Ball(Color color, int w, int h) { this.w = w; this.h = h; int R = w/10; x = (float) (Math.random() * w); bwidth = R*2; bheight = R*2; byte[] data = new byte[R * 2 * R * 2]; int maxr = 0; for (int Y = 2 * R; --Y >= 0;) { int x0 = (int) (Math.sqrt(R * R - (Y - R) * (Y - R)) + 0.5); int p = Y * (R * 2) + R - x0; for (int X = -x0; X < x0; X++) { int x = X + 15; int y = Y - R + 15; int r = (int) (Math.sqrt(x * x + y * y) + 0.5); if (r > maxr) maxr = r; data[p++] = r <= 0 ? 1 : (byte) r; } } imgs = new BufferedImage[nImgs]; int bg = 255; byte red[] = new byte[256]; red[0] = (byte) bg; byte green[] = new byte[256]; green[0] = (byte) bg; byte blue[] = new byte[256]; blue[0] = (byte) bg; for (int r = 0; r < imgs.length; r++) { float b = 0.5f + (float) ((r+1f)/imgs.length/2f); for (int i = maxr; i >= 1; --i) { float d = (float) i / maxr; red[i] = (byte) blend(blend(color.getRed(), 255, d), bg, b); green[i] = (byte) blend(blend(color.getGreen(), 255, d), bg, b); blue[i] = (byte) blend(blend(color.getBlue(), 255, d), bg, b); } IndexColorModel icm = new IndexColorModel(8, maxr + 1, red, green, blue, 0); DataBufferByte dbb = new DataBufferByte(data, data.length); int bandOffsets[] = {0}; WritableRaster wr = Raster.createInterleavedRaster(dbb, R*2,R*2,R*2,1, bandOffsets,null); imgs[r] = new BufferedImage(icm, wr, icm.isAlphaPremultiplied(),null); } } private final int blend(int fg, int bg, float fgfactor) { return (int) (bg + (fg - bg) * fgfactor); } public void step(long deltaT) { boolean collision_x = false; boolean collision_y = false; float jitter = (float)Math.random() * .01f - .005f; x += Vx * deltaT + (Ax / 2.0) * deltaT * deltaT; y += Vy * deltaT + (Ay / 2.0) * deltaT * deltaT; if (x <= 0.0f) { x = 0.0f; Vx = -Vx * inelasticity + jitter; collision_x = true; } Dimension d = getSize(); if (x + bwidth >= w) { x = w - bwidth; Vx = -Vx * inelasticity + jitter; collision_x = true; } if (y <= 0) { y = 0; Vy = -Vy * inelasticity + jitter; collision_y = true; } if (y + bheight >= h) { y = h - bheight; Vx *= inelasticity; Vy = -Vy * inelasticity + jitter; collision_y = true; } Vy = Vy + Ay * deltaT; Vx = Vx + Ax * deltaT; if (indexDirection == UP) index++; if (indexDirection == DOWN) --index; if (index+1 == nImgs) indexDirection = DOWN; if (index == 0) indexDirection = UP; } } // End class Ball }