001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.demos.manyballs;
028:
029: import javax.microedition.lcdui.*;
030:
031: /**
032: * A SmallBall is a lightweight animated ball that runs in it's own thread.
033: * It moves within a rectangular region, bouncing off the walls.
034: */
035: class SmallBall implements Runnable {
036:
037: // random number generator
038: static java.util.Random random = new java.util.Random();
039:
040: // controls the speed of all balls; delay in centiseconds
041: static int delay = 20;
042:
043: static void slower() {
044: delay += 10;
045: if (delay > 100)
046: delay = 100;
047: }
048:
049: static void faster() {
050: delay -= 10;
051: if (delay < 0)
052: delay = 0;
053: }
054:
055: // the matrix to transform the direction based on the
056: // current direction and which wall was hit
057: static int[][] matrix = { { 1, -1, -1, 1, 1, 1 },
058: { -1, -1, 1, 1, -1, 1 }, null, { 1, 1, -1, -1, 1, -1 },
059: { -1, 1, 1, -1, -1, -1 } };
060:
061: // the region in which the ball moves
062: int top, left, width, height;
063:
064: // the position and radius of the ball
065: int posX, posY;
066: int radius = 5, ballSize = radius * 2;
067:
068: // the direction of the ball is controlled by these two variables
069: int deltaX;
070: int deltaY;
071:
072: // a handle onto the singleton Graphics object
073: Graphics g;
074: Canvas canvas;
075:
076: // public variables to control the behaviour of the thread
077: public boolean stop;
078:
079: /**
080: * Constructor defines the region in which the ball moves as well
081: * as its starting position.
082: */
083: SmallBall(Canvas c, int left, int top, int width, int height) {
084: super ();
085: canvas = c;
086:
087: this .left = left + 1;
088: this .top = top + 1;
089: this .width = width - (2 * radius + 2);
090: this .height = height - (2 * radius + 2);
091:
092: // use positive random #s
093: this .posX = (random.nextInt() >>> 1) % (this .width - 20) + 10;
094: this .posY = (random.nextInt() >>> 1) % (this .height - 20) + 10;
095:
096: deltaX = random.nextInt() & 1;
097: deltaY = random.nextInt() & 1;
098:
099: if (deltaX == 0)
100: deltaX = -1;
101: if (deltaY == 0)
102: deltaY = -1;
103: }
104:
105: /**
106: * Starts the ball running.
107: */
108: public void run() {
109: // System.out.println("starting... " + this);
110: int right = left + width;
111: int bottom = top + height;
112:
113: stop = false;
114: while (!stop) {
115:
116: ballSize = radius * 2;
117:
118: // calculate a direction of the ball
119: // as an integer in the range
120: // -2 .. 2 (excluding 0)
121: int direction = deltaX + deltaY;
122: if (direction == 0)
123: direction = deltaX + 2 * deltaY;
124:
125: // is the current position colliding with any wall
126: int collision = 0;
127: if (posX <= left || posX >= right)
128: collision++;
129: if (posY <= top || posY >= bottom)
130: collision += 2;
131:
132: // change the direction appropriately
133: // if there was a collision
134: if (collision != 0) {
135: collision = (collision - 1) * 2;
136:
137: deltaX = matrix[direction + 2][collision];
138: deltaY = matrix[direction + 2][collision + 1];
139: }
140:
141: // calculate the new position and queue a repaint
142: posX = posX + deltaX;
143: posY = posY + deltaY;
144: canvas.repaint(posX - 1, posY - 1, ballSize + 2,
145: ballSize + 2);
146:
147: // use the delay to control the speed of the ball
148: try {
149: Thread.sleep(delay);
150: } catch (InterruptedException e) {
151: }
152: }
153: }
154:
155: /**
156: * Paint the ball.
157: */
158: void paint(Graphics g) {
159: g.setColor(0);
160: g.fillArc(posX, posY, ballSize, ballSize, 0, 360);
161: }
162:
163: boolean inside(int x1, int y1, int x2, int y2) {
164: return (posX <= x2) && (posY <= y2)
165: && ((posX + ballSize) >= x1)
166: && ((posY + ballSize) >= y1);
167: }
168:
169: public String toString() {
170: return super .toString() + " x = " + posX + ", y = " + posY;
171: }
172:
173: }
|