001: /*
002: *
003: * Copyright (c) 2007, Sun Microsystems, Inc.
004: *
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * * Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * * Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * * Neither the name of Sun Microsystems nor the names of its contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032: package example.manyballs;
033:
034: import javax.microedition.lcdui.Graphics;
035:
036: /**
037: * A SmallBall is a lightweight animated ball that runs in it's own thread.
038: * It moves within a rectangular region, bouncing off the walls.
039: */
040: class SmallBall implements Runnable {
041: // random number generator
042: static java.util.Random random = new java.util.Random();
043:
044: // controls the speed of all balls; delay in centiseconds
045: static int delay = 20;
046:
047: // the matrix to transform the direction based on the
048: // current direction and which wall was hit
049: static int[][] matrix = { { 1, -1, -1, 1, 1, 1 },
050: { -1, -1, 1, 1, -1, 1 }, null, { 1, 1, -1, -1, 1, -1 },
051: { -1, 1, 1, -1, -1, -1 } };
052:
053: // the region in which the ball moves
054: int top;
055:
056: // the region in which the ball moves
057: int left;
058:
059: // the region in which the ball moves
060: int width;
061:
062: // the region in which the ball moves
063: int height;
064:
065: // the position and radius of the ball
066: int posX;
067:
068: // the position and radius of the ball
069: int posY;
070: int radius = 5;
071: int ballSize = radius * 2;
072:
073: // the direction of the ball is controlled by these two variables
074: int deltaX;
075: int deltaY;
076:
077: // a handle onto the singleton Graphics object
078: Graphics g;
079: ManyCanvas canvas;
080:
081: // public variables to control the behaviour of the thread
082: public boolean stop;
083:
084: /**
085: * Constructor defines the region in which the ball moves as well
086: * as its starting position.
087: */
088: SmallBall(ManyCanvas c, int left, int top, int width, int height) {
089: super ();
090: canvas = c;
091:
092: this .left = left + 1;
093: this .top = top + 1;
094: this .width = width - ((2 * radius) + 2);
095: this .height = height - ((2 * radius) + 2);
096:
097: // use positive random #s
098: this .posX = ((random.nextInt() >>> 1) % (this .width - 20)) + 10;
099: this .posY = ((random.nextInt() >>> 1) % (this .height - 20)) + 10;
100:
101: deltaX = random.nextInt() & 1;
102: deltaY = random.nextInt() & 1;
103:
104: if (deltaX == 0) {
105: deltaX = -1;
106: }
107:
108: if (deltaY == 0) {
109: deltaY = -1;
110: }
111: }
112:
113: static void slower() {
114: delay += 10;
115:
116: if (delay > 100) {
117: delay = 100;
118: }
119: }
120:
121: static void faster() {
122: delay -= 10;
123:
124: if (delay < 0) {
125: delay = 0;
126: }
127: }
128:
129: public void run() {
130: canvas.notifyBallThreadStarted();
131:
132: stop = false;
133:
134: int right = left + width;
135: int bottom = top + height;
136:
137: try {
138: while (!stop) {
139: moveBall(right, bottom);
140:
141: // use the delay to control the speed of the ball
142: Thread.sleep(delay);
143: }
144: } catch (Exception e) {
145: e.printStackTrace();
146: }
147:
148: canvas.notifyBallThreadStopped();
149: }
150:
151: private void moveBall(int right, int bottom) {
152: ballSize = radius * 2;
153:
154: // calculate a direction of the ball
155: // as an integer in the range
156: // -2 .. 2 (excluding 0)
157: int direction = deltaX + deltaY;
158:
159: if (direction == 0) {
160: direction = deltaX + (2 * deltaY);
161: }
162:
163: // is the current position colliding with any wall
164: int collision = 0;
165:
166: if ((posX <= left) || (posX >= right)) {
167: collision++;
168: }
169:
170: if ((posY <= top) || (posY >= bottom)) {
171: collision += 2;
172: }
173:
174: // change the direction appropriately
175: // if there was a collision
176: if (collision != 0) {
177: collision = (collision - 1) * 2;
178:
179: deltaX = matrix[direction + 2][collision];
180: deltaY = matrix[direction + 2][collision + 1];
181: }
182:
183: // calculate the new position and queue a repaint
184: posX += deltaX;
185: posY += deltaY;
186: canvas.repaint(posX - 1, posY - 1, ballSize + 2, ballSize + 2);
187: }
188:
189: /**
190: * Paint the ball.
191: */
192: void paint(Graphics g) {
193: g.setColor(0);
194: g.fillArc(posX, posY, ballSize, ballSize, 0, 360);
195: }
196:
197: boolean inside(int x1, int y1, int x2, int y2) {
198: return (posX <= x2) && (posY <= y2)
199: && ((posX + ballSize) >= x1)
200: && ((posY + ballSize) >= y1);
201: }
202:
203: public String toString() {
204: return super .toString() + " x = " + posX + ", y = " + posY;
205: }
206: }
|