KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java2d > demos > Mix > Balls


1 /*
2  * @(#)Balls.java 1.32 06/08/29
3  *
4  * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * -Redistribution of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * -Redistribution in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * Neither the name of Sun Microsystems, Inc. or the names of contributors may
17  * be used to endorse or promote products derived from this software without
18  * specific prior written permission.
19  *
20  * This software is provided "AS IS," without a warranty of any kind. ALL
21  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
22  * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
24  * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
25  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
26  * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
27  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
28  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
29  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  * You acknowledge that this software is not designed, licensed or intended
33  * for use in the design, construction, operation or maintenance of any
34  * nuclear facility.
35  */

36
37 /*
38  * @(#)Balls.java 1.32 06/08/29
39  */

40
41 package java2d.demos.Mix;
42
43 import java.awt.*;
44 import java.awt.image.*;
45 import java.awt.event.*;
46 import javax.swing.*;
47 import java2d.AnimatingControlsSurface;
48 import java2d.CustomControls;
49
50 import static java.awt.Color JavaDoc.*;
51 import static java.lang.Math JavaDoc.*;
52
53
54 /**
55  * Animated color bouncing balls with custom controls.
56  */

57 public class Balls extends AnimatingControlsSurface {
58
59     private static Color JavaDoc colors[] =
60             { RED, ORANGE, YELLOW, GREEN.darker(), BLUE,
61                 new Color JavaDoc(75, 00, 82), new Color JavaDoc(238,130,238) };
62     private long now, deltaT, lasttime;
63     private boolean active;
64     protected Ball balls[] = new Ball[colors.length];
65     protected boolean clearToggle;
66     protected JComboBox combo;
67
68
69     public Balls() {
70         setBackground(WHITE);
71         for (int i = 0; i < colors.length; i++) {
72             balls[i] = new Ball(colors[i], 30);
73         }
74         balls[0].isSelected = true;
75         balls[3].isSelected = true;
76         balls[4].isSelected = true;
77         balls[6].isSelected = true;
78         setControls(new Component[] { new DemoControls(this) });
79     }
80
81
82     public void reset(int w, int h) {
83         if (w > 400 && h > 100) {
84             combo.setSelectedIndex(5);
85         }
86     }
87
88
89     public void step(int w, int h) {
90         if (lasttime == 0) {
91             lasttime = System.currentTimeMillis();
92         }
93         now = System.currentTimeMillis();
94         deltaT = now - lasttime;
95         active = false;
96         for (Ball ball : balls) {
97             if (ball == null) {
98                 return;
99             }
100             ball.step(deltaT, w, h);
101             if (ball.Vy > .02 || -ball.Vy > .02 ||
102                     ball.y + ball.bsize < h) {
103                 active = true;
104             }
105         }
106         if (!active) {
107             for (Ball ball : balls) {
108                 ball.Vx = (float)random() / 4.0f - 0.125f;
109                 ball.Vy = -(float)random() / 4.0f - 0.2f;
110             }
111             clearToggle = true;
112         }
113     }
114
115
116     public void render(int w, int h, Graphics2D g2) {
117         for (Ball b : balls) {
118             if (b == null || b.imgs[b.index] == null || !b.isSelected) {
119                 continue;
120             }
121             g2.drawImage(b.imgs[b.index], (int) b.x, (int) b.y, this);
122         }
123         lasttime = now;
124     }
125
126
127     public static void main(String JavaDoc argv[]) {
128         createDemoFrame(new Balls());
129     }
130
131
132     static class Ball {
133     
134         public static final int nImgs = 5;
135
136         public int bsize;
137         public float x, y;
138         public float Vx = 0.1f;
139         public float Vy = 0.05f;
140         public BufferedImage imgs[];
141         // Pick a random starting image index, but not the last: we're going UP
142
// and that would throw us off the end.
143
public int index = (int) (random() * (nImgs-1));
144     
145         private static final float inelasticity = .96f;
146         private static final float Ax = 0.0f;
147         private static final float Ay = 0.0002f;
148         private static final float Ar = 0.9f;
149         private static final int UP = 0;
150         private static final int DOWN = 1;
151
152         private int indexDirection = UP;
153         private boolean collision_x, collision_y;
154         private float jitter;
155         private Color JavaDoc color;
156         private boolean isSelected;
157     
158     
159         public Ball(Color JavaDoc color, int bsize) {
160             this.color = color;
161             makeImages(bsize);
162         }
163     
164     
165         public void makeImages(int bsize) {
166             this.bsize = bsize*2;
167             int R = bsize;
168             byte[] data = new byte[R * 2 * R * 2];
169             int maxr = 0;
170             for (int Y = 2 * R; --Y >= 0;) {
171                 int x0 = (int) (sqrt(R * R - (Y - R) * (Y - R)) + 0.5);
172                 int p = Y * (R * 2) + R - x0;
173                 for (int X = -x0; X < x0; X++) {
174                     int x = X + 15;
175                     int y = Y - R + 15;
176                     int r = (int) (sqrt(x * x + y * y) + 0.5);
177                     if (r > maxr) {
178                         maxr = r;
179                     }
180                     data[p++] = r <= 0 ? 1 : (byte) r;
181                 }
182             }
183     
184             imgs = new BufferedImage[nImgs];
185     
186             int bg = 255;
187             byte red[] = new byte[256]; red[0] = (byte) bg;
188             byte green[] = new byte[256]; green[0] = (byte) bg;
189             byte blue[] = new byte[256]; blue[0] = (byte) bg;
190     
191             for (int r = 0; r < imgs.length; r++) {
192                 float b = 0.5f + (float) ((r+1f)/imgs.length/2f);
193                 for (int i = maxr; i >= 1; --i) {
194                     float d = (float) i / maxr;
195                       red[i] = (byte)
196                               blend(blend(color.getRed(), 255, d), bg, b);
197                     green[i] = (byte)
198                               blend(blend(color.getGreen(), 255, d), bg, b);
199                      blue[i] = (byte)
200                               blend(blend(color.getBlue(), 255, d), bg, b);
201                 }
202                 IndexColorModel icm = new IndexColorModel(8, maxr + 1,
203                             red, green, blue, 0);
204                 DataBufferByte dbb = new DataBufferByte(data, data.length);
205                 int bandOffsets[] = {0};
206                 WritableRaster wr = Raster.createInterleavedRaster(dbb,
207                     R*2,R*2,R*2,1, bandOffsets,null);
208                 imgs[r] = new BufferedImage(icm, wr,icm.isAlphaPremultiplied(),null);
209             }
210         }
211     
212     
213         private final int blend(int fg, int bg, float fgfactor) {
214             return (int) (bg + (fg - bg) * fgfactor);
215         }
216     
217     
218         public void step(long deltaT, int w, int h) {
219             collision_x = false;
220             collision_y = false;
221     
222             jitter = (float) random() * .01f - .005f;
223     
224             x += Vx * deltaT + (Ax / 2.0) * deltaT * deltaT;
225             y += Vy * deltaT + (Ay / 2.0) * deltaT * deltaT;
226             if (x <= 0.0f) {
227                 x = 0.0f;
228                 Vx = -Vx * inelasticity + jitter;
229                 collision_x = true;
230             }
231             if (x + bsize >= w) {
232                 x = w - bsize;
233                 Vx = -Vx * inelasticity + jitter;
234                 collision_x = true;
235             }
236             if (y <= 0) {
237                 y = 0;
238                 Vy = -Vy * inelasticity + jitter;
239                 collision_y = true;
240             }
241             if (y + bsize >= h) {
242                 y = h - bsize;
243                 Vx *= inelasticity;
244                 Vy = -Vy * inelasticity + jitter;
245                 collision_y = true;
246             }
247             Vy = Vy + Ay * deltaT;
248             Vx = Vx + Ax * deltaT;
249     
250             if (indexDirection == UP) {
251                 index++;
252             }
253             if (indexDirection == DOWN) {
254                 --index;
255             }
256             if (index+1 == nImgs) {
257                 indexDirection = DOWN;
258             }
259             if (index == 0) {
260                 indexDirection = UP;
261             }
262         }
263     } // End class Ball
264

265
266
267     class DemoControls extends CustomControls implements ActionListener {
268
269         Balls demo;
270         JToolBar toolbar;
271
272         public DemoControls(Balls demo) {
273             super(demo.name);
274             this.demo = demo;
275             add(toolbar = new JToolBar());
276             toolbar.setFloatable(false);
277             addTool("Clear", true);
278             addTool("R", demo.balls[0].isSelected);
279             addTool("O", demo.balls[1].isSelected);
280             addTool("Y", demo.balls[2].isSelected);
281             addTool("G", demo.balls[3].isSelected);
282             addTool("B", demo.balls[4].isSelected);
283             addTool("I", demo.balls[5].isSelected);
284             addTool("V", demo.balls[6].isSelected);
285             add(combo = new JComboBox());
286             combo.addItem("10");
287             combo.addItem("20");
288             combo.addItem("30");
289             combo.addItem("40");
290             combo.addItem("50");
291             combo.addItem("60");
292             combo.addItem("70");
293             combo.addItem("80");
294             combo.setSelectedIndex(2);
295             combo.addActionListener(this);
296         }
297
298
299         public void addTool(String JavaDoc str, boolean state) {
300             JToggleButton b = (JToggleButton) toolbar.add(new JToggleButton(str));
301             b.setFocusPainted(false);
302             b.setSelected(state);
303             b.addActionListener(this);
304             int width = b.getPreferredSize().width;
305             Dimension prefSize = new Dimension(width, 21);
306             b.setPreferredSize(prefSize);
307             b.setMaximumSize(prefSize);
308             b.setMinimumSize(prefSize);
309         }
310
311
312         public void actionPerformed(ActionEvent e) {
313             if (e.getSource() instanceof JComboBox) {
314                 int size = Integer.parseInt((String JavaDoc) combo.getSelectedItem());
315                 for (Ball ball : demo.balls) {
316                     ball.makeImages(size);
317                 }
318                 return;
319             }
320             JToggleButton b = (JToggleButton) e.getSource();
321             if (b.getText().equals("Clear")) {
322                 demo.clearSurface = b.isSelected();
323             }
324             else {
325                 int index = toolbar.getComponentIndex(b)-1;
326                 demo.balls[index].isSelected = b.isSelected();
327             }
328         }
329
330         public Dimension getPreferredSize() {
331             return new Dimension(200,40);
332         }
333
334
335         public void run() {
336             try { thread.sleep(999); } catch (Exception JavaDoc e) { return; }
337             Thread JavaDoc me = Thread.currentThread();
338             ((AbstractButton) toolbar.getComponentAtIndex(2)).doClick();
339             while (thread == me) {
340                 try {
341                     thread.sleep(222);
342                 } catch (InterruptedException JavaDoc e) { return; }
343                 if (demo.clearToggle) {
344                     if (demo.clearSurface) {
345                         combo.setSelectedIndex((int) (random()*5));
346                     }
347                     ((AbstractButton) toolbar.getComponentAtIndex(0)).doClick();
348                     demo.clearToggle = false;
349                 }
350             }
351             thread = null;
352         }
353     } // End DemoControls
354
} // End Balls
355
Popular Tags