001: /*
002: * @(#)GameDemo.java 1.6 06/10/10
003: *
004: * Copyright 1990-2006 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: package basis.demos;
027:
028: import java.awt.*;
029: import java.awt.event.*;
030: import java.io.*;
031: import java.util.*;
032: import basis.Builder;
033:
034: public class GameDemo extends Demo implements KeyListener,
035: FocusListener {
036: private static final int OUTSIDE = 0;
037: private static final int INSIDE = 1;
038: private static final int ACTIVE = 2;
039: private static final int FIXED = 3;
040: private static final int SPARE = 4;
041: private static final int BLANK = 5;
042: private static final Color COLOR_OUTSIDE = Builder.SUN_YELLOW;
043: private static final Color COLOR_INSIDE = Builder.SUN_BLUE;
044: private static final Color COLOR_ACTIVE = Builder.SUN_RED;
045: private static final Color COLOR_SPARE = Builder.SUN_LIGHTBLUE;
046: private static final Color COLOR_BLANK = Color.white;
047: private static final int DEFAULT_DELAY = 101;
048: private static final int DELAY_INCREMENT = 10;
049: private static final int DEFAULT_LIVES = 3;
050: private static final Color[] winnerColors = { Builder.SUN_RED,
051: Builder.SUN_BLUE };
052: private int demoWidth;
053: private int demoHeight;
054: private int rows = 30;
055: private int cols = 30;
056: private int[][] cells = new int[rows][cols];
057: private int cellWidth;
058: private int cellHeight;
059: private int target;
060: private int level = 1;
061: private int total;
062: private int delay = DEFAULT_DELAY;
063: private int lives = DEFAULT_LIVES;
064: private boolean initialized;
065: private boolean stopped; // player stopped by user
066: private boolean paused; // game paused by user
067: private boolean aborted; // game aborted by user
068: private boolean halted; // game halted by system
069: private boolean crashed;
070: private boolean gameover;
071: private boolean showHighScores;
072: private boolean showHelpStrings;
073: private Animator animator = new Animator();
074: private Player player;
075: private ArrayList enemies;
076: private ArrayList highScores = new ArrayList();
077: private ArrayList helpStrings = new ArrayList();
078: private Image pausedImage;
079: private Image abortedImage;
080: private Image gameoverImage;
081: private boolean newGame;
082: private boolean winner;
083: private int percentageArea;
084: private int percentageTime;
085: private long startTime;
086: private long pausedTime;
087: private long haltedTime;
088: private boolean warmed;
089:
090: public GameDemo() {
091: // start early to "warm up"
092: animator.start();
093: pausedImage = ImageDemo.loadImage(this , "images/paused.gif");
094: abortedImage = ImageDemo.loadImage(this , "images/aborted.gif");
095: gameoverImage = ImageDemo
096: .loadImage(this , "images/gameover.gif");
097: addKeyListener(this );
098: addFocusListener(this );
099: addMouseListener(new MouseAdapter() {
100: public void mousePressed(MouseEvent e) {
101: requestFocus();
102: }
103: });
104: helpStrings.add("n/1-9 New game");
105: helpStrings.add("arrows Move");
106: helpStrings.add("i/j/k/l Move");
107: helpStrings.add("space Stop");
108: helpStrings.add("p Pause");
109: helpStrings.add("a/ESC Abort");
110: helpStrings.add("s/- Slower");
111: helpStrings.add("d/= Default");
112: helpStrings.add("f/+ Faster");
113: helpStrings.add("z Highscores");
114: helpStrings.add("h Help");
115: loadHighScores();
116: }
117:
118: public void paint(Graphics g) {
119: requestFocus();
120: if (winner) {
121: return;
122: }
123: Dimension d = getSize();
124: demoWidth = d.width;
125: demoHeight = d.height;
126: cellWidth = demoWidth / cols;
127: cellHeight = demoHeight / (rows + 1);
128: if (!initialized) {
129: play(false);
130: halted = true;
131: showHelpStrings = true;
132: initialized = true;
133: }
134: if (showHelpStrings) {
135: drawStrings(g, "Jonix", helpStrings);
136: return;
137: }
138: if (showHighScores) {
139: loadHighScores();
140: drawStrings(g, "High Scores", highScores, 10);
141: return;
142: }
143: for (int row = 0; row < rows; row++) {
144: for (int col = 0; col < cols; col++) {
145: if (cells[row][col] == OUTSIDE) {
146: g.setColor(COLOR_OUTSIDE);
147: }
148: if (cells[row][col] == INSIDE) {
149: g.setColor(COLOR_INSIDE);
150: }
151: if (cells[row][col] == ACTIVE) {
152: g.setColor(COLOR_ACTIVE);
153: }
154: if (cells[row][col] == SPARE) {
155: g.setColor(COLOR_SPARE);
156: }
157: if (cells[row][col] == BLANK) {
158: g.setColor(COLOR_BLANK);
159: }
160: g.fillRect(col * cellWidth, row * cellHeight,
161: cellWidth, cellHeight);
162: if (cells[row][col] == SPARE) {
163: g.setColor(COLOR_BLANK);
164: g.drawRect(col * cellWidth, row * cellHeight,
165: cellWidth - 1, cellHeight - 1);
166: }
167: }
168: }
169: player.draw(g);
170: for (int i = 0; i < enemies.size(); i++) {
171: Enemy enemy = (Enemy) enemies.get(i);
172: enemy.draw(g);
173: }
174: if (paused || aborted || gameover) {
175: Image image = pausedImage;
176: if (aborted) {
177: image = abortedImage;
178: }
179: if (gameover) {
180: image = gameoverImage;
181: }
182: ((Graphics2D) g).setComposite(AlphaComposite.getInstance(
183: AlphaComposite.SRC_OVER, 0.5f));
184: g.drawImage(image, demoWidth / 10, 4 * demoHeight / 9,
185: 8 * demoWidth / 10, demoHeight / 9, this );
186: }
187: drawPercentageTime();
188: }
189:
190: private void drawStrings(Graphics g, String heading,
191: ArrayList strings) {
192: drawStrings(g, heading, strings, strings.size());
193: }
194:
195: private void drawStrings(Graphics g, String heading,
196: ArrayList strings, int number) {
197: g.setColor(COLOR_OUTSIDE);
198: g.fillRect(0, 0, demoWidth, demoHeight);
199: String longest = "";
200: for (int i = 0; i < strings.size(); i++) {
201: String s = (String) strings.get(i);
202: if (s.length() > longest.length()) {
203: longest = s;
204: }
205: }
206: int fontSize = demoHeight / (number + 2) - 2;
207: g.setColor(Builder.SUN_RED);
208: int headingFontSize = 2 * fontSize;
209: int fw = 0;
210: while (true) {
211: Font font = new Font("Monospaced", Font.BOLD,
212: headingFontSize);
213: g.setFont(font);
214: FontMetrics fm = g.getFontMetrics(font);
215: fw = fm.stringWidth(heading);
216: if (fw < demoWidth) {
217: break;
218: }
219: headingFontSize -= 4;
220: }
221: g.drawString(heading, (demoWidth - fw) / 2, headingFontSize);
222: g.setColor(Builder.SUN_BLUE);
223: Font font = new Font("Monospaced", Font.PLAIN, fontSize);
224: g.setFont(font);
225: FontMetrics fm = g.getFontMetrics(font);
226: fw = fm.stringWidth(longest);
227: for (int i = 0; i < strings.size() && i < number; i++) {
228: String s = (String) strings.get(i);
229: g.drawString(s, (demoWidth - fw) / 2, (i + 3) * fontSize);
230: }
231: }
232:
233: private void play(boolean preserve) {
234: if (preserve) {
235: for (int row = 0; row < rows; row++) {
236: for (int col = 0; col < cols; col++) {
237: if (cells[row][col] == ACTIVE) {
238: cells[row][col] = INSIDE;
239: }
240: }
241: }
242: } else {
243: target = 0;
244: for (int row = 0; row < rows; row++) {
245: for (int col = 0; col < cols; col++) {
246: if (row < rows / 10 || row > 9 * rows / 10
247: || row < 3 || row >= rows - 3
248: || col < cols / 10 || col > 9 * cols / 10
249: || col < 3 || col >= cols - 3) {
250: cells[row][col] = OUTSIDE;
251: } else {
252: cells[row][col] = INSIDE;
253: target++;
254: }
255: }
256: }
257: int col = cols / 2 - DEFAULT_LIVES / 2;
258: for (int c = 0; c < DEFAULT_LIVES; c++) {
259: if (c < lives) {
260: cells[0][col + c] = SPARE;
261: } else {
262: cells[0][col + c] = BLANK;
263: }
264: }
265: }
266: player = new Player();
267: ArrayList newEnemies = new ArrayList();
268: if (preserve) {
269: for (int i = 0; i < enemies.size(); i++) {
270: Enemy enemy = (Enemy) enemies.get(i);
271: if (enemy.inside) {
272: newEnemies.add(enemy);
273: }
274: }
275: }
276: for (int i = 0; i < level; i++) {
277: newEnemies.add(new Enemy(false));
278: if (!preserve) {
279: newEnemies.add(new Enemy(true));
280: }
281: }
282: enemies = newEnemies;
283: percentageArea = percentageArea();
284: setStatus("Level " + level + " Score "
285: + (total + percentageArea));
286: startTime = System.currentTimeMillis();
287: percentageTime = 100;
288: crashed = false;
289: aborted = false;
290: gameover = false;
291: }
292:
293: private void crash() {
294: halted = true;
295: lives--;
296: percentageArea = percentageArea();
297: setStatus("Level " + level + " Score "
298: + (total + percentageArea));
299: if (lives > 0) {
300: repaint();
301: sleep(3000);
302: // In case user aborted during delay...
303: if (!aborted) {
304: play(true);
305: halted = false;
306: repaint();
307: }
308: return;
309: }
310: total += percentageArea;
311: if (total > 0) {
312: String scoreString = "" + total;
313: while (scoreString.length() < 3) {
314: scoreString = " " + scoreString;
315: }
316: boolean newHighScore = false;
317: boolean inserted = false;
318: for (int i = 0; i < highScores.size(); i++) {
319: String s = (String) highScores.get(i);
320: s = s.trim();
321: try {
322: int score = Integer.parseInt(s);
323: if (total >= score) {
324: highScores.add(i, scoreString);
325: inserted = true;
326: if (i == 0) {
327: newHighScore = true;
328: }
329: break;
330: }
331: } catch (NumberFormatException nfe) {
332: }
333: }
334: if (!inserted) {
335: highScores.add(scoreString);
336: if (highScores.size() == 1) {
337: newHighScore = true;
338: }
339: }
340: while (highScores.size() > 10) {
341: highScores.remove(highScores.size() - 1);
342: }
343: saveHighScores();
344: if (newHighScore) {
345: sleep(1000);
346: winner();
347: showHighScores = true;
348: repaint();
349: }
350: }
351: level = 1;
352: gameover = true;
353: repaint();
354: }
355:
356: private int percentageArea() {
357: if (target == 0) {
358: return 0;
359: }
360: int todo = 0;
361: for (int row = 0; row < rows; row++) {
362: for (int col = 0; col < cols; col++) {
363: if (cells[row][col] == INSIDE
364: || cells[row][col] == ACTIVE) {
365: todo++;
366: }
367: }
368: }
369: return (target - todo) * 100 / target;
370: }
371:
372: private int percentageTime() {
373: long currentTime = System.currentTimeMillis();
374: int lapsedTime = (int) ((currentTime - startTime) / 1000);
375: int totalTime = 60 * level;
376: int x = 100 * (totalTime - lapsedTime) / totalTime;
377: x = x < 0 ? 0 : x;
378: return x;
379: }
380:
381: private void fix(int row, int col) {
382: if (row < 0 || row >= rows) {
383: return;
384: }
385: if (col < 0 || col >= cols) {
386: return;
387: }
388: if (cells[row][col] != INSIDE) {
389: return;
390: }
391: cells[row][col] = FIXED;
392: fix(row - 1, col - 1);
393: fix(row - 1, col);
394: fix(row - 1, col + 1);
395: fix(row, col - 1);
396: fix(row, col + 1);
397: fix(row + 1, col - 1);
398: fix(row + 1, col);
399: fix(row + 1, col + 1);
400: }
401:
402: private void winner() {
403: winner = true;
404: Graphics g = getGraphics();
405: String string = "High Score!";
406: int fontSize = demoWidth / string.length();
407: fontSize = fontSize > demoHeight / 2 ? demoHeight / 2
408: : fontSize;
409: int fw = 0;
410: while (true) {
411: Font font = new Font("SansSerif", Font.BOLD, fontSize);
412: g.setFont(font);
413: FontMetrics fm = g.getFontMetrics(font);
414: fw = fm.stringWidth(string);
415: if (fw < demoWidth) {
416: break;
417: }
418: fontSize -= 4;
419: }
420: int color = 0;
421: for (int i = 0; i < 300; i++) {
422: if (!hasFocus()) {
423: break;
424: }
425: if (i % 10 == 0) {
426: g.setColor(winnerColors[color++ % winnerColors.length]);
427: g.fillRect(0, 0, demoWidth, demoHeight);
428: }
429: g.setColor(randomColor());
430: g.drawString(string, demoWidth / 2 - fw / 2, demoHeight / 2
431: + fontSize / 2);
432: sleep(10);
433: }
434: winner = false;
435: }
436:
437: private Color randomColor() {
438: float min = 0.3f;
439: float red = (float) (Math.random() + min);
440: float green = (float) (Math.random() + min);
441: float blue = (float) (Math.random() + min);
442: red = red > 1.0f ? 1.0f : red;
443: green = green > 1.0f ? 1.0f : green;
444: blue = blue > 1.0f ? 1.0f : blue;
445: return new Color(red, green, blue);
446: }
447:
448: private void sleep(int millis) {
449: try {
450: Thread.sleep(millis);
451: } catch (InterruptedException ie) {
452: }
453: startTime += millis;
454: }
455:
456: public void keyPressed(KeyEvent e) {
457: char keyChar = e.getKeyChar();
458: int keyCode = e.getKeyCode();
459: long currentTime = e.getWhen();
460: if (keyChar == 'n') {
461: level = 1;
462: newGame = true;
463: }
464: try {
465: int value = Integer.parseInt("" + keyChar);
466: if (value >= 1 && value <= 9) {
467: level = value;
468: }
469: newGame = true;
470: } catch (NumberFormatException nfe) {
471: }
472: if (newGame) {
473: warmed = true;
474: // all the fields animator waits on...
475: paused = false;
476: aborted = false;
477: halted = false;
478: gameover = false;
479: showHelpStrings = false;
480: showHighScores = false;
481: if (animator.isAlive()) {
482: animator.interrupt();
483: }
484: return;
485: }
486: int dir = Player.NONE;
487: if (keyChar == 'i' || keyCode == KeyEvent.VK_UP) {
488: dir = Player.UP;
489: }
490: if (keyChar == 'k' || keyCode == KeyEvent.VK_DOWN) {
491: dir = Player.DOWN;
492: }
493: if (keyChar == 'j' || keyCode == KeyEvent.VK_LEFT) {
494: dir = Player.LEFT;
495: }
496: if (keyChar == 'l' || keyCode == KeyEvent.VK_RIGHT) {
497: dir = Player.RIGHT;
498: }
499: if (dir == Player.UP || dir == Player.DOWN
500: || dir == Player.LEFT || dir == Player.RIGHT) {
501: if (player != null) {
502: player.dir = dir;
503: stopped = false;
504: }
505: return;
506: }
507: if (keyChar == 'p') {
508: paused = paused ? false : true;
509: if (paused) {
510: pausedTime = currentTime;
511: } else {
512: if (pausedTime > 0) {
513: startTime += (currentTime - pausedTime);
514: }
515: }
516: repaint();
517: return;
518: }
519: if (keyCode == KeyEvent.VK_ENTER) {
520: showHelpStrings = false;
521: showHighScores = false;
522: if (halted && haltedTime > 0) {
523: startTime += (currentTime - haltedTime);
524: halted = false;
525: }
526: repaint();
527: }
528: if (keyChar == ' ') {
529: stopped = true;
530: return;
531: }
532: if (keyChar == '+' || keyChar == 'f') {
533: delay -= DELAY_INCREMENT;
534: if (delay <= 0) {
535: delay = 1;
536: }
537: return;
538: }
539: if (keyChar == '=' || keyChar == 'd') {
540: delay = DEFAULT_DELAY;
541: return;
542: }
543: if (keyChar == '-' || keyChar == 's') {
544: delay += DELAY_INCREMENT;
545: if (delay > 201) {
546: delay = 201;
547: }
548: return;
549: }
550: if (keyChar == 'z') {
551: showHighScores = true;
552: showHelpStrings = false;
553: if (!halted) {
554: halted = true;
555: haltedTime = currentTime;
556: }
557: repaint();
558: return;
559: }
560: if (keyChar == 'h') {
561: showHelpStrings = true;
562: showHighScores = false;
563: repaint();
564: if (!halted) {
565: halted = true;
566: haltedTime = currentTime;
567: }
568: return;
569: }
570: if (keyChar == 'a' || keyCode == KeyEvent.VK_ESCAPE) {
571: lives = 0;
572: aborted = true;
573: animator.interrupt();
574: repaint();
575: return;
576: }
577: }
578:
579: public void keyReleased(KeyEvent e) {
580: }
581:
582: public void keyTyped(KeyEvent e) {
583: }
584:
585: public void focusGained(FocusEvent e) {
586: long currentTime = System.currentTimeMillis();
587: if (!paused && halted && haltedTime > 0) {
588: startTime += currentTime - haltedTime;
589: haltedTime = 0;
590: halted = false;
591: }
592: }
593:
594: public void focusLost(FocusEvent e) {
595: long currentTime = System.currentTimeMillis();
596: if (!paused && !halted) {
597: halted = true;
598: haltedTime = currentTime;
599: }
600: }
601:
602: private void loadHighScores() {
603: ArrayList newHighScores = new ArrayList();
604: try {
605: FileInputStream fis = new FileInputStream("highscores");
606: BufferedReader br = new BufferedReader(
607: new InputStreamReader(fis));
608: while (true) {
609: String s = br.readLine();
610: if (s == null || s.length() <= 0) {
611: break;
612: }
613: newHighScores.add(s);
614: }
615: br.close();
616: } catch (IOException ioe) {
617: } catch (SecurityException se) {
618: }
619: highScores = newHighScores;
620: }
621:
622: private void saveHighScores() {
623: try {
624: FileOutputStream fos = new FileOutputStream("highscores");
625: PrintWriter pw = new PrintWriter(
626: new OutputStreamWriter(fos));
627: for (int i = 0; i < highScores.size(); i++) {
628: String s = (String) highScores.get(i);
629: pw.println(s);
630: }
631: pw.flush();
632: pw.close();
633:
634: } catch (IOException ioe) {
635: }
636: }
637:
638: private void drawPercentageTime() {
639: Graphics g = getGraphics();
640: if (g == null) {
641: return;
642: }
643: int x = 0;
644: int y = rows * cellHeight;
645: int w = cols * cellWidth;
646: int h = demoHeight - y;
647: g.setColor(Color.white);
648: g.fillRect(x, y, w, h);
649: g.setColor(Builder.SUN_RED);
650: g.fillRect(x, y, percentageTime * w / 100, h);
651: g.setColor(Color.black);
652: g.drawRect(x, y, w - 1, h - 1);
653: }
654:
655: class Animator extends Thread {
656: public void run() {
657: setPriority(MAX_PRIORITY);
658: while (true) {
659: while (!warmed) {
660: try {
661: Thread.sleep(delay);
662: } catch (InterruptedException ie) {
663: }
664: }
665: if (newGame) {
666: total = 0;
667: lives = DEFAULT_LIVES;
668: play(false);
669: repaint();
670: newGame = false;
671: }
672: if (player != null) {
673: player.move();
674: }
675: if (enemies != null) {
676: for (int i = 0; i < enemies.size(); i++) {
677: Enemy enemy = (Enemy) enemies.get(i);
678: enemy.move();
679: }
680: }
681: int x = percentageTime();
682: if (x < percentageTime) {
683: percentageTime = x;
684: drawPercentageTime();
685: }
686: if (percentageTime <= 0) {
687: crash();
688: }
689: do {
690: try {
691: Thread.sleep(delay);
692: } catch (InterruptedException ie) {
693: }
694: } while (paused || aborted || halted || gameover
695: || showHelpStrings || showHighScores);
696: }
697: }
698: }
699:
700: class Player {
701: static final int NONE = 0;
702: static final int UP = 1;
703: static final int DOWN = 2;
704: static final int LEFT = 3;
705: static final int RIGHT = 4;
706: Color color = Builder.SUN_RED;
707: int row;
708: int col;
709: int dir = UP;
710: boolean inside;
711:
712: public Player() {
713: stopped = true;
714: for (int row = 0; row < rows; row++) {
715: for (int col = cols - 1; col >= 0; col--) {
716: if (cells[row][col] == SPARE) {
717: cells[row][col] = BLANK;
718: this .row = row;
719: this .col = col;
720: break;
721: }
722: }
723: }
724: }
725:
726: public void move() {
727: if (crashed) {
728: crash();
729: crashed = false;
730: return;
731: }
732: if (stopped || paused || aborted || halted || gameover
733: || showHelpStrings || showHighScores) {
734: return;
735: }
736: int oldRow = row;
737: int oldCol = col;
738: if (dir == UP) {
739: row = oldRow > 0 ? oldRow - 1 : oldRow;
740: }
741: if (dir == DOWN) {
742: row = oldRow < rows - 1 ? oldRow + 1 : oldRow;
743: }
744: if (dir == LEFT) {
745: col = oldCol > 0 ? oldCol - 1 : oldCol;
746: }
747: if (dir == RIGHT) {
748: col = oldCol < cols - 1 ? oldCol + 1 : oldCol;
749: }
750: if (row != oldRow || col != oldCol) {
751: Graphics g = getGraphics();
752: if (cells[oldRow][oldCol] == ACTIVE) {
753: g.setColor(COLOR_ACTIVE);
754: }
755: if (cells[oldRow][oldCol] == OUTSIDE) {
756: g.setColor(COLOR_OUTSIDE);
757: }
758: if (cells[oldRow][oldCol] == SPARE) {
759: g.setColor(COLOR_SPARE);
760: }
761: if (cells[oldRow][oldCol] == BLANK) {
762: g.setColor(COLOR_BLANK);
763: }
764: g.fillRect(oldCol * cellWidth, oldRow * cellHeight,
765: cellWidth, cellHeight);
766: if (cells[oldRow][oldCol] == SPARE) {
767: g.setColor(COLOR_BLANK);
768: g.drawRect(oldCol * cellWidth, oldRow * cellHeight,
769: cellWidth - 1, cellHeight - 1);
770: }
771: draw(g);
772: }
773: if (cells[row][col] == ACTIVE) {
774: crashed = true;
775: crash();
776: return;
777: }
778: if (cells[row][col] == INSIDE) {
779: inside = true;
780: cells[row][col] = ACTIVE;
781: }
782: if (inside && cells[row][col] == OUTSIDE) {
783: percentageTime = percentageTime();
784: stopped = true;
785: inside = false;
786: halted = true;
787: for (int i = 0; i < enemies.size(); i++) {
788: Enemy enemy = (Enemy) enemies.get(i);
789: fix(enemy.row, enemy.col);
790: }
791: for (int row = 0; row < rows; row++) {
792: for (int col = 0; col < cols; col++) {
793: if (cells[row][col] == ACTIVE) {
794: cells[row][col] = OUTSIDE;
795: }
796: if (cells[row][col] == INSIDE) {
797: cells[row][col] = OUTSIDE;
798: }
799: if (cells[row][col] == FIXED) {
800: cells[row][col] = INSIDE;
801: }
802: }
803: }
804: repaint();
805: percentageArea = percentageArea();
806: setStatus("Level " + level + " Score "
807: + (total + percentageArea));
808: if (percentageArea >= 75) {
809: total += percentageArea + percentageTime;
810: setStatus("Level " + level + " Score " + total);
811: level++;
812: sleep(3000);
813: play(false);
814: repaint();
815: }
816: halted = false;
817: }
818: }
819:
820: void draw(Graphics g) {
821: g.setColor(color);
822: g.fillRect(col * cellWidth, row * cellHeight, cellWidth,
823: cellHeight);
824: g.setColor(Color.black);
825: g.drawRect(col * cellWidth, row * cellHeight,
826: cellWidth - 1, cellHeight - 1);
827: }
828:
829: }
830:
831: class Enemy {
832: static final int SE = 0;
833: static final int SW = 1;
834: static final int NW = 2;
835: static final int NE = 3;
836: int[][] array = { { SE, NE, SW, NW }, { SW, SE, NW, NE },
837: { NW, SW, NE, SE }, { NE, NW, SE, SW } };
838: Color color;
839: boolean inside;
840: int row;
841: int col;
842: int dir = (int) (Math.random() * 4);
843:
844: public Enemy(boolean inside) {
845: this .inside = inside;
846: if (inside) {
847: color = COLOR_OUTSIDE;
848: } else {
849: color = COLOR_INSIDE;
850: }
851: while (true) {
852: row = (int) (Math.random() * rows);
853: col = (int) (Math.random() * cols);
854: if (!inside
855: && ((row > rows / 10 && row < 9 * rows / 10) || (col > cols / 10 && col < 9 * cols / 10))) {
856: continue;
857: }
858: if (inside && cells[row][col] == INSIDE) {
859: break;
860: }
861: if (!inside && cells[row][col] == OUTSIDE) {
862: break;
863: }
864: }
865: }
866:
867: public void move() {
868: if (paused || aborted || halted || crashed || gameover
869: || showHelpStrings || showHighScores) {
870: return;
871: }
872: int oldRow = row;
873: int oldCol = col;
874: int oldDir = dir;
875: for (int i = 0; i < 4; i++) {
876: dir = array[oldDir][i];
877: if (dir == SE) {
878: row = oldRow + 1;
879: col = oldCol + 1;
880: }
881: if (dir == SW) {
882: row = oldRow + 1;
883: col = oldCol - 1;
884: }
885: if (dir == NW) {
886: row = oldRow - 1;
887: col = oldCol - 1;
888: }
889: if (dir == NE) {
890: row = oldRow - 1;
891: col = oldCol + 1;
892: }
893: if (row < 0 || row >= rows || col < 0 || col >= cols) {
894: continue;
895: }
896: if (inside && cells[row][col] != OUTSIDE) {
897: break;
898: }
899: if (!inside && cells[row][col] == OUTSIDE) {
900: break;
901: }
902: }
903: Graphics g = getGraphics();
904: boolean hit = false;
905: if (inside && cells[player.row][player.col] == INSIDE
906: || !inside
907: && cells[player.row][player.col] == OUTSIDE) {
908: if (row == player.row && col == player.col
909: || row - 1 == player.row && col == player.col
910: || row + 1 == player.row && col == player.col
911: || row == player.row && col - 1 == player.col
912: || row == player.row && col + 1 == player.col) {
913: hit = true;
914: }
915: }
916: if (inside) {
917: if (cells[row][col] == ACTIVE || row > 0
918: && cells[row - 1][col] == ACTIVE
919: || row < rows - 1
920: && cells[row + 1][col] == ACTIVE || col > 0
921: && cells[row][col - 1] == ACTIVE
922: || col < cols - 1
923: && cells[row][col + 1] == ACTIVE) {
924: hit = true;
925: }
926: }
927: draw(g);
928: if (inside) {
929: g.setColor(COLOR_INSIDE);
930: } else {
931: g.setColor(COLOR_OUTSIDE);
932: }
933: g.fillRect(oldCol * cellWidth, oldRow * cellHeight,
934: cellWidth, cellHeight);
935: if (hit) {
936: crashed = true;
937: }
938: }
939:
940: void draw(Graphics g) {
941: g.setColor(color);
942: g.fillRect(col * cellWidth, row * cellHeight, cellWidth,
943: cellHeight);
944: g.setColor(Color.black);
945: g.drawRect(col * cellWidth, row * cellHeight,
946: cellWidth - 1, cellHeight - 1);
947: }
948: }
949: }
|