Balls.java
Upload User: cdlibang
Upload Date: 2016-07-17
Package Size: 774k
Code Size: 13k
Category:

2D Graphic

Development Platform:

Java

  1. /*
  2.  * @(#)Balls.java 1.17 99/04/23
  3.  *
  4.  * Copyright (c) 1998, 1999 by Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
  7.  * modify and redistribute this software in source and binary code form,
  8.  * provided that i) this copyright notice and license appear on all copies of
  9.  * the software; and ii) Licensee does not utilize the software in a manner
  10.  * which is disparaging to Sun.
  11.  * 
  12.  * This software is provided "AS IS," without a warranty of any kind. ALL
  13.  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
  14.  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  15.  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
  16.  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
  17.  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
  18.  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
  19.  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
  20.  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
  21.  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
  22.  * POSSIBILITY OF SUCH DAMAGES.
  23.  * 
  24.  * This software is not designed or intended for use in on-line control of
  25.  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
  26.  * the design, construction, operation or maintenance of any nuclear
  27.  * facility. Licensee represents and warrants that it will not use or
  28.  * redistribute the Software for such purposes.
  29.  */
  30. package demos.Mix;
  31. import java.awt.*;
  32. import java.awt.image.*;
  33. import java.awt.event.*;
  34. import javax.swing.*;
  35. import AnimatingContext;
  36. import DemoSurface;
  37. import DemoPanel;
  38. import CustomControls;
  39. /**
  40.  * Animated color bouncing balls with custom controls.
  41.  */
  42. public class Balls extends DemoSurface implements AnimatingContext, CustomControls {
  43.     private static Color colors[] = 
  44.             { Color.red, Color.orange, Color.yellow, Color.green.darker(),
  45.               Color.blue, new Color(75, 00, 82), new Color(238,130,238) };
  46.     private long now, deltaT, lasttime;
  47.     private boolean active;
  48.     private DemoControls controls;
  49.     protected Ball balls[] = new Ball[colors.length];
  50.     protected boolean clearToggle;
  51.     public Balls() {
  52.         setBackground(Color.white);
  53.         for (int i = 0; i < colors.length; i++) {
  54.             balls[i] = new Ball(colors[i], 30);
  55.         }
  56.         balls[0].isSelected = true;
  57.         balls[3].isSelected = true;
  58.         balls[4].isSelected = true;
  59.         balls[6].isSelected = true;
  60.         controls = new DemoControls(this);
  61.     }
  62.     public String[] getCustomControlsConstraints() {
  63.         return new String[] { BorderLayout.NORTH };
  64.     }
  65.     public Component[] getCustomControls() {
  66.         return new Component[] { (Component) controls };
  67.     }
  68.     public void customControlsThread(int state) {
  69.         if (state == CustomControls.START) {
  70.             controls.start();
  71.         } else if (state == CustomControls.STOP) {
  72.             controls.stop();
  73.         }
  74.     }
  75.     public void reset(int w, int h) {
  76.         if (w > 400 && h > 100) {
  77.             controls.combo.setSelectedIndex(5);
  78.         }
  79.     }
  80.     public void step(int w, int h) {
  81.         if (lasttime == 0) {
  82.             lasttime = System.currentTimeMillis();
  83.         }
  84.         now = System.currentTimeMillis();
  85.         deltaT = now - lasttime;
  86.         active = false;
  87.         for (int i = 0; i < balls.length; i++) {
  88.             if (balls[i] == null) {
  89.                 return;
  90.             }
  91.             balls[i].step(deltaT, w, h);
  92.             if (balls[i].Vy > .02 || -balls[i].Vy > .02 ||
  93.                     balls[i].y + balls[i].bsize < h) {
  94.                 active = true;
  95.             }
  96.         }
  97.         if (!active) {
  98.             for (int i = 0; i < balls.length; i++) {
  99.                 balls[i].Vx = (float)Math.random() / 4.0f - 0.125f;
  100.                 balls[i].Vy = -(float)Math.random() / 4.0f - 0.2f;
  101.             }
  102.             clearToggle = true;
  103.         }
  104.     }
  105.     public void drawDemo(int w, int h, Graphics2D g2) {
  106.         for (int i = 0; i < balls.length; i++) {
  107.             Ball b = balls[i];
  108.             if (b == null || b.imgs[b.index] == null || !b.isSelected) {
  109.                 continue;
  110.             }
  111.             g2.drawImage(b.imgs[b.index], (int) b.x, (int) b.y, this);
  112.         }
  113.         lasttime = now;
  114.     }
  115.     public static void main(String argv[]) {
  116.         final DemoPanel dp = new DemoPanel(new Balls());
  117.         JFrame f = new JFrame("Java2D Demo - Balls");
  118.         f.addWindowListener(new WindowAdapter() {
  119.             public void windowClosing(WindowEvent e) {System.exit(0);}
  120.             public void windowDeiconified(WindowEvent e) { 
  121.                 dp.surface.start(); 
  122.             }
  123.             public void windowIconified(WindowEvent e) { 
  124.                 dp.surface.stop(); 
  125.             }
  126.         });
  127.         f.getContentPane().add("Center", dp);
  128.         f.pack();
  129.         f.setSize(new Dimension(400,300));
  130.         f.show();
  131.         dp.surface.start();
  132.     }
  133.     static class Ball {
  134.     
  135.         public int bsize;
  136.         public float x, y;
  137.         public float Vx = 0.1f;
  138.         public float Vy = 0.05f;
  139.         public int nImgs = 5;
  140.         public BufferedImage imgs[];
  141.         public int index = (int) (Math.random() * (nImgs-1));
  142.     
  143.         private final float inelasticity = .96f;
  144.         private final float Ax = 0.0f;
  145.         private final float Ay = 0.0002f;
  146.         private final float Ar = 0.9f;
  147.         private final int UP = 0;
  148.         private final int DOWN = 1;
  149.         private int indexDirection = UP;
  150.         private boolean collision_x, collision_y;
  151.         private float jitter;
  152.         private Color color;
  153.         private boolean isSelected;
  154.     
  155.     
  156.         public Ball(Color color, int bsize) {
  157.             this.color = color;
  158.             makeImages(bsize);
  159.         }
  160.     
  161.     
  162.         public void makeImages(int bsize) {
  163.             this.bsize = bsize*2;
  164.             int R = bsize;
  165.             byte[] data = new byte[R * 2 * R * 2];
  166.             int maxr = 0;
  167.             for (int Y = 2 * R; --Y >= 0;) {
  168.                 int x0 = (int) (Math.sqrt(R * R - (Y - R) * (Y - R)) + 0.5);
  169.                 int p = Y * (R * 2) + R - x0;
  170.                 for (int X = -x0; X < x0; X++) {
  171.                     int x = X + 15;
  172.                     int y = Y - R + 15;
  173.                     int r = (int) (Math.sqrt(x * x + y * y) + 0.5);
  174.                     if (r > maxr) {
  175.                         maxr = r;
  176.                     }
  177.                     data[p++] = r <= 0 ? 1 : (byte) r;
  178.                 }
  179.             }
  180.     
  181.             imgs = new BufferedImage[nImgs];
  182.     
  183.             int bg = 255;
  184.             byte red[] = new byte[256];
  185.             red[0] = (byte) bg;
  186.             byte green[] = new byte[256];
  187.             green[0] = (byte) bg;
  188.             byte blue[] = new byte[256];
  189.             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) blend(blend(color.getRed(), 255, d), bg, b);
  196.                     green[i] = (byte) blend(blend(color.getGreen(), 255, d), bg, b);
  197.                     blue[i] = (byte) blend(blend(color.getBlue(), 255, d), bg, b);
  198.                 }
  199.                 IndexColorModel icm = new IndexColorModel(8, maxr + 1,
  200.                             red, green, blue, 0);
  201.                 DataBufferByte dbb = new DataBufferByte(data, data.length);
  202.                 int bandOffsets[] = {0};
  203.                 WritableRaster wr = Raster.createInterleavedRaster(dbb,
  204.                     R*2,R*2,R*2,1, bandOffsets,null);
  205.                 imgs[r] = new BufferedImage(icm, wr,icm.isAlphaPremultiplied(),null);
  206.             }
  207.         }
  208.     
  209.     
  210.         private final int blend(int fg, int bg, float fgfactor) {
  211.             return (int) (bg + (fg - bg) * fgfactor);
  212.         }
  213.     
  214.     
  215.         public void step(long deltaT, int w, int h) {
  216.             collision_x = false;
  217.             collision_y = false;
  218.     
  219.             jitter = (float) Math.random() * .01f - .005f;
  220.     
  221.             x += Vx * deltaT + (Ax / 2.0) * deltaT * deltaT;
  222.             y += Vy * deltaT + (Ay / 2.0) * deltaT * deltaT;
  223.             if (x <= 0.0f) {
  224.                 x = 0.0f;
  225.                 Vx = -Vx * inelasticity + jitter;
  226.                 collision_x = true;
  227.             }
  228.             if (x + bsize >= w) {
  229.                 x = w - bsize;
  230.                 Vx = -Vx * inelasticity + jitter;
  231.                 collision_x = true;
  232.             }
  233.             if (y <= 0) {
  234.                 y = 0;
  235.                 Vy = -Vy * inelasticity + jitter;
  236.                 collision_y = true;
  237.             }
  238.             if (y + bsize >= h) {
  239.                 y = h - bsize;
  240.                 Vx *= inelasticity;
  241.                 Vy = -Vy * inelasticity + jitter;
  242.                 collision_y = true;
  243.             }
  244.             Vy = Vy + Ay * deltaT;
  245.             Vx = Vx + Ax * deltaT;
  246.     
  247.             if (indexDirection == UP) {
  248.                 index++; 
  249.             }
  250.             if (indexDirection == DOWN) {
  251.                 --index; 
  252.             }
  253.             if (index+1 == nImgs) {
  254.                 indexDirection = DOWN;
  255.             }
  256.             if (index == 0) {
  257.                 indexDirection = UP;
  258.             }
  259.         }
  260.     }  // End class Ball
  261.     static class DemoControls extends JPanel implements ActionListener, Runnable {
  262.         Balls demo;
  263.         JToolBar toolbar;
  264.         JComboBox combo;
  265.         Thread thread;
  266.         public DemoControls(Balls demo) {
  267.             this.demo = demo;
  268.             setBackground(Color.gray);
  269.             add(toolbar = new JToolBar());
  270.             toolbar.setFloatable(false);
  271.             addTool("Clear", true);
  272.             addTool("R", demo.balls[0].isSelected);
  273.             addTool("O", demo.balls[1].isSelected);
  274.             addTool("Y", demo.balls[2].isSelected);
  275.             addTool("G", demo.balls[3].isSelected);
  276.             addTool("B", demo.balls[4].isSelected);
  277.             addTool("I", demo.balls[5].isSelected);
  278.             addTool("V", demo.balls[6].isSelected);
  279.             add(combo = new JComboBox());
  280.             combo.addItem("10");
  281.             combo.addItem("20");
  282.             combo.addItem("30");
  283.             combo.addItem("40");
  284.             combo.addItem("50");
  285.             combo.addItem("60");
  286.             combo.addItem("70");
  287.             combo.addItem("80");
  288.             combo.setSelectedIndex(2);
  289.             combo.addActionListener(this);
  290.             addMouseListener(new MouseAdapter() {
  291.                 public void mouseClicked(MouseEvent e) {
  292.                     if (thread == null) start(); else stop();
  293.                 }
  294.             });
  295.         }
  296.         public void addTool(String str, boolean state) {
  297.             JButton b = (JButton) toolbar.add(new JButton(str));
  298.             b.setBackground(state ? Color.green : Color.lightGray);
  299.             b.setSelected(state);
  300.             b.addActionListener(this);
  301.         }
  302.         public void actionPerformed(ActionEvent e) {
  303.             if (e.getSource() instanceof JComboBox) {
  304.                 int size = Integer.parseInt((String) combo.getSelectedItem());
  305.                 for (int i = 0; i < demo.balls.length; i++) {
  306.                     demo.balls[i].makeImages(size);
  307.                 }
  308.                 return;
  309.             }
  310.             JButton b = (JButton) e.getSource();
  311.             b.setSelected(!b.isSelected());
  312.             b.setBackground(b.isSelected() ? Color.green : Color.lightGray);
  313.             if (b.getText().equals("Clear")) {
  314.                 demo.clearSurface = b.isSelected();
  315.             } else {
  316.                 int index = toolbar.getComponentIndex(b)-1;
  317.                 demo.balls[index].isSelected = b.isSelected();
  318.             }
  319.         }
  320.         public Dimension getPreferredSize() {
  321.             return new Dimension(200,37);
  322.         }
  323.         public void start() {
  324.             if (thread != null) {
  325.                 return;
  326.             }
  327.             thread = new Thread(this);
  328.             thread.setPriority(Thread.MIN_PRIORITY);
  329.             thread.setName("Mix.Balls DemoControls Thread");
  330.             thread.start();
  331.         }
  332.         public synchronized void stop() {
  333.             if (thread != null) {
  334.                 thread.interrupt();
  335.             }
  336.             thread = null;
  337.             notifyAll();
  338.         }
  339.         public void run() {
  340.             try { thread.sleep(999); } catch (Exception e) { return; }
  341.             Thread me = Thread.currentThread();
  342.             ((JButton) toolbar.getComponentAtIndex(2)).doClick();
  343.             while (thread == me) {
  344.                 try {
  345.                     thread.sleep(222);
  346.                 } catch (InterruptedException e) { return; }
  347.                 if (demo.clearToggle) {
  348.                     if (demo.clearSurface) {
  349.                         combo.setSelectedIndex((int) (Math.random()*5));
  350.                     }
  351.                     ((JButton) toolbar.getComponentAtIndex(0)).doClick();
  352.                     demo.clearToggle = false;
  353.                 }
  354.             }
  355.             thread = null;
  356.         }
  357.     } // End DemoControls
  358. } // End Balls