| C:\__todo__\tecaj.www\src\Epsilon_02\GameCanvas.java |
1 /**
2 * GameCanvas contains the Canvas for the Epsilon game.
3 * Epsilon is a simple space-shooter-vertical-scroller game.
4 *
5 * Epsilon is available for non-commercial use only!
6 * You can learn from this sources and you can modify them
7 * for learning purposes.
8 *
9 * @author Ziga Hajdukovic
10 * @version 1.0
11 *
12 * CHANGES (01 --> 02)
13 * + new player sprite, p.png
14 * + added boss sprite boss1.png
15 * + added tileset t04.png
16 * + added enemy sprites e1.png, e2.png, e3.png
17 * + added fire.png, removed pf.png
18 * + added explosion sprite, exp.png
19 * + moved Image objects for sprites to spriteImage array
20 * + added tileImage
21 * + moved image loading to loadImages()
22 * + setClip in paintSprite
23 * + player sprite frames for left and right movement
24 * + multiple fire sprites + fire_cooldown_wait_frames
25 * + 20 FPS fixed frame rate
26 * + Vector explosionSprites
27 * + updateExplosionSprites()
28 * + doCollision() -> add explosion on collision
29 * + paint explosionSprites
30 * + Level class
31 * + loadLevel(), tile map, and sprite positions
32 * + space and tiles y and vy
33 * + load sprites positions
34 * + level paint
35 * + (scrolling background space layer)
36 * + (scrolling tile layer)
37 * + new (but still random) enemies
38 * + player game over explosion
39 *
40 */
41
42 import java.util.*;
43
44 import javax.microedition.lcdui.*;
45
46 //import com.nokia.mid.ui.FullCanvas;
47 //
48 //class GameCanvas extends FullCanvas implements Runnable
49 class GameCanvas extends Canvas implements Runnable
50 {
51 private final Game midlet;
52
53 public static int canvasWidth;
54 public static int canvasHeight;
55
56 public static boolean gameRunning;
57
58 public static final int SOFTKEY_1 = -6;
59 public static final int SOFTKEY_2 = -7;
60
61 public static boolean menu_command_1;
62 public static boolean menu_command_2;
63
64 public static boolean command_up;
65 public static boolean command_down;
66 public static boolean command_left;
67 public static boolean command_right;
68 public static boolean command_fire;
69
70 public static byte mode;
71 public static final byte MODE_INTRO = 0;
72 public static final byte MODE_GAME = 1;
73 public static final byte MODE_MENU = 2;
74
75 public static int loadingCounter;
76
77 public static Image imgIntro;
78 public static Image imgBackground;
79
80 public static Image[] spriteImages;
81 public static final byte SPRITE_IMAGE_PLAYER = 0;
82 public static final byte SPRITE_IMAGE_FIRE = 1;
83 public static final byte SPRITE_IMAGE_BOSS1 = 2;
84 public static final byte SPRITE_IMAGE_ENEMY1 = 3;
85 public static final byte SPRITE_IMAGE_ENEMY2 = 4;
86 public static final byte SPRITE_IMAGE_ENEMY3 = 5;
87 public static final byte SPRITE_IMAGE_EXPLOSION = 6;
88 public static final byte SPRITE_IMAGE_MAX = 7;
89
90 public static final byte SPRITE_FRAME_PLAYER_LEFT = 0;
91 public static final byte SPRITE_FRAME_PLAYER_CENTER = 1;
92 public static final byte SPRITE_FRAME_PLAYER_RIGHT = 2;
93
94 public static final byte FIRE_COOLDOWN_WAIT_FRAMES = 10;
95 public static byte fire_cooldown_wait_frames_counter;
96
97 public static Image tileImage;
98
99 public static int menuScreen;
100 public static final byte MENU_SCR_MAIN = 0;
101 public static final byte MENU_SCR_TEXT_ABOUT = 1;
102 public static final byte MENU_SCR_TEXT_HELP = 2;
103 public static final byte MENU_SCR_TEXT_GAME_OVER = 3;
104
105 public static int menuSelectedOption;
106 public static final byte MENU_OPTION_MAIN_NEW_GAME = 0;
107 public static final byte MENU_OPTION_MAIN_ABOUT = 1;
108 public static final byte MENU_OPTION_MAIN_HELP = 2;
109 public static final byte MENU_OPTION_MAIN_MAX = 2;
110
111 public static final String[] menuScreenMainOptions = { "New game", "About", "Help"};
112
113 public static final String[][] menuScreensTextLines = {
114 { "" },
115 { "About", "", "Epsilon v0.1", "(c) 2005 zigah." },
116 { "Help", "", "Press LEFT, RIGHT, ", "UP or DOWN", "to move and", "FIRE to shoot." },
117 { "Game Over", "", "Well done!"},
118 };
119
120 public static GameSprite player;
121 public static Vector playerFireSprites;
122 public static int player_score;
123 public static int player_gameover_explosion_counter;
124 public static int PLAYER_GAMEOVER_EXPLOSION_COUNTER = 40;
125
126 public static final byte MAX_ENERGY_PLAYER = 100;
127 public static final byte MAX_ENERGY_PLAYER_FIRE = 10;
128 public static final byte MAX_ENERGY_ENEMY = 10;
129
130 public static Vector enemySprites;
131
132 public static Vector explosionSprites;
133
134 public static byte max_enemy_sprites = 3;
135
136 public static final short FIXED_FRAME_TIME = 60;
137
138 public static int global_frame_counter;
139
140 public static Random random = new Random();
141
142 GameCanvas(Game midlet)
143 {
144 this.midlet = midlet;
145
146 canvasWidth = this.getWidth();
147 canvasHeight = this.getHeight();
148
149 loadingCounter = 0;
150 menuScreen = MENU_SCR_MAIN;
151 menuSelectedOption = MENU_OPTION_MAIN_NEW_GAME;
152 mode = MODE_INTRO;
153 gameRunning = true;
154 }
155
156 public void run()
157 {
158 while(gameRunning)
159 {
160 long frameStartTime = System.currentTimeMillis();
161 global_frame_counter++;
162
163 repaint();
164 serviceRepaints();
165
166 switch (mode) {
167 case MODE_INTRO:
168
169 try
170 {
171 if (loadingCounter == 0)
172 {
173 imgIntro = Image.createImage("/intro.png");
174 }
175 else if (loadingCounter == 1)
176 {
177 loadImages();
178 }
179 else
180 {
181 // view the intro splash image for a while
182 // it would be better to let user skip intro by pressing a key
183 // but, in a full game project, loading would take forever, anyway, so...
184 try {
185 Thread.sleep(1000);
186 } catch (Exception e) {};
187 // switch mode
188 mode = MODE_MENU;
189 }
190 loadingCounter++;
191 }
192 catch (Exception e) {
193 // ignore loading exception
194 };
195 break;
196
197 case MODE_MENU:
198
199 if (command_up) {
200 command_up = false;
201 menuSelectedOption--;
202 if (menuSelectedOption < 0)
203 menuSelectedOption = 0;
204 }
205 if (command_down) {
206 command_down = false;
207 menuSelectedOption++;
208 if ((menuScreen == MENU_SCR_MAIN) &&
209 (menuSelectedOption > MENU_OPTION_MAIN_MAX))
210 menuSelectedOption = MENU_OPTION_MAIN_MAX;
211 }
212
213 if (menu_command_1)
214 {
215 menu_command_1 = false;
216 if (menuScreen == MENU_SCR_MAIN)
217 {
218 switch(menuSelectedOption)
219 {
220 case MENU_OPTION_MAIN_NEW_GAME:
221 startGame();
222 break;
223
224 case MENU_OPTION_MAIN_ABOUT:
225 menuScreen = MENU_SCR_TEXT_ABOUT;
226 break;
227
228 case MENU_OPTION_MAIN_HELP:
229 menuScreen = MENU_SCR_TEXT_HELP;
230 break;
231 }
232 } else {
233 // all other menu screens go to main menu when OK is selected
234 menuScreen = MENU_SCR_MAIN;
235 }
236 }
237 if (menu_command_2)
238 {
239 menu_command_2 = false;
240
241 // exit when in main menu
242 if (menuScreen == MENU_SCR_MAIN)
243 midlet.exitRequested();
244 }
245
246 // delay, so the keypress events get their turn...
247 try {
248 Thread.sleep(40);
249 } catch (Exception e) {};
250 break;
251
252 case MODE_GAME:
253
254 // scroll space and tile background
255 Level.space_scroll_y += Level.space_scroll_vy;
256 Level.tiles_scroll_y += Level.tiles_scroll_vy;
257
258 // top of the level (boss) reached, stop scrolling
259 if (Level.tiles_scroll_y < 0)
260 Level.tiles_scroll_y = 0;
261
262 int tiles_scroll_x_range = (Level.LEVEL_WIDTH * Level.TILE_SIZE - canvasWidth);
263 int player_x_range = canvasWidth - player.w;
264 Level.tiles_scroll_x = player.x * tiles_scroll_x_range / player_x_range;
265 // System.out.print("tx: "+Level.tiles_scroll_x);
266 // System.out.println(", ty: "+Level.tiles_scroll_y);
267
268 updateEnemySprites();
269
270 updatePlayerSprite();
271
272 updatePlayerFireSprites();
273
274 updateExplosionSprites();
275
276 // check player <-> enemy <-> player fire collision
277 doCollision();
278
279 // check for game end
280 if (menu_command_2 ||
281 ( (player.energy <= 0) &&
282 (player_gameover_explosion_counter == 0))
283 )
284 {
285 menu_command_2 = false;
286 // on softkey_2 end game and return to main menu..
287 endGame();
288 }
289
290 // calc. delay
291 long frameTime = System.currentTimeMillis() - frameStartTime;
292 if (frameTime < FIXED_FRAME_TIME)
293 {
294 try {
295 Thread.sleep( FIXED_FRAME_TIME - frameTime );
296 } catch (Exception e) {};
297 }
298 break;
299 }
300 }
301 }
302
303 public void paint(Graphics g)
304 {
305 switch(mode)
306 {
307 case MODE_INTRO:
308
309 g.setColor(0x000000);
310 g.fillRect(0, 0, canvasWidth, canvasHeight);
311 if (imgIntro != null) {
312 g.drawImage(imgIntro, canvasWidth/2, canvasHeight/2, Graphics.VCENTER | Graphics.HCENTER);
313 }
314
315 // g.setColor(0xFFFFFF);
316 // g.drawString(""+loadingCounter,0,0,Graphics.LEFT | Graphics.TOP);
317
318 break;
319
320 case MODE_MENU:
321
322 Level.paintSpaceBackground(g);
323
324 switch(menuScreen)
325 {
326 case MENU_SCR_MAIN:
327 paintMainMenu(g);
328 break;
329
330 case MENU_SCR_TEXT_ABOUT:
331 case MENU_SCR_TEXT_HELP:
332 case MENU_SCR_TEXT_GAME_OVER:
333 paintTextMenu(g, menuScreen);
334 break;
335 }
336 break;
337
338 case MODE_GAME:
339
340 Level.paintSpaceBackground(g);
341 Level.paintTiles(g);
342
343 paintSprite( g, player );
344
345 for (int i=0; i < playerFireSprites.size(); i++)
346 paintSprite( g, (GameSprite) playerFireSprites.elementAt(i));
347
348 for (int i=0; i < enemySprites.size(); i++)
349 paintSprite( g, (GameSprite) enemySprites.elementAt(i) );
350
351 for (int i=0; i < explosionSprites.size(); i++)
352 paintSprite( g, (GameSprite) explosionSprites.elementAt(i) );
353
354 paintStatusBars(g);
355
356 break;
357 }
358 }
359
360 public void keyPressed(int key)
361 {
362 switch(key) {
363 case SOFTKEY_1:
364 menu_command_1 = true;
365 break;
366
367 case SOFTKEY_2:
368 menu_command_2 = true;
369 break;
370 }
371
372 int game_action = getGameAction(key);
373
374 switch(game_action)
375 {
376 case UP:
377 command_up = true;
378 break;
379
380 case DOWN:
381 command_down = true;
382 break;
383
384 case LEFT:
385 command_left = true;
386 break;
387
388 case RIGHT:
389 command_right = true;
390 break;
391
392 case FIRE:
393 command_fire = true;
394 menu_command_1 = true;
395 break;
396 }
397 }
398
399 public void keyReleased(int key)
400 {
401 int game_action = getGameAction(key);
402
403 switch(game_action)
404 {
405 case UP:
406 command_up = false;
407 break;
408
409 case DOWN:
410 command_down = false;
411 break;
412
413 case LEFT:
414 command_left = false;
415 break;
416
417 case RIGHT:
418 command_right = false;
419 break;
420
421 case FIRE:
422 command_fire = false;
423 menu_command_1 = false;
424 break;
425 }
426 }
427
428 public void paintMainMenu(Graphics g)
429 {
430 // init font
431 g.setFont(Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_LARGE));
432 int menu_y = canvasHeight/2 - 45;
433 for(int i=0; i <= MENU_OPTION_MAIN_MAX; i++)
434 {
435 // paint the main menu options
436 if (i == menuSelectedOption) {
437 g.setColor(0xFFCC00);
438 } else {
439 g.setColor(0xFFFFFF);
440 }
441
442 g.drawString(menuScreenMainOptions[i], canvasWidth/2, menu_y, Graphics.HCENTER | Graphics.TOP);
443
444 menu_y += 30;
445 }
446 g.setFont(Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
447 g.setColor(0xFFFFFF);
448 // paint softkey_1 label
449 g.drawString("Select", 2, canvasHeight-2, Graphics.LEFT | Graphics.BOTTOM);
450 // paint softkey_2 label
451 g.drawString("Exit", canvasWidth-2, canvasHeight-2, Graphics.RIGHT | Graphics.BOTTOM);
452 }
453
454 public void paintTextMenu(Graphics g, int screen)
455 {
456 g.setFont(Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
457 g.setColor(0xFFFFFF);
458 int text_line_y = 10;
459 for(int line=0; line < menuScreensTextLines[screen].length; line++)
460 {
461 // paint all the lines of text in this menu screen
462 g.drawString(menuScreensTextLines[screen][line], canvasWidth/2, text_line_y, Graphics.HCENTER | Graphics.TOP);
463
464 text_line_y += 15;
465 }
466 if (screen == MENU_SCR_TEXT_GAME_OVER)
467 {
468 // print score in the game over screen
469 text_line_y += 15;
470 g.drawString("Score: "+ player_score, canvasWidth/2, text_line_y, Graphics.HCENTER | Graphics.TOP);
471 }
472
473 g.setFont(Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
474 // paint softkey_1 label
475 g.drawString("Ok", 1, canvasHeight-1, Graphics.LEFT | Graphics.BOTTOM);
476 }
477
478 public static void paintSprite(Graphics g, GameSprite spr)
479 {
480 // set the clip window
481 int cx = spr.x;
482 int cy = spr.y;
483 int cw = GameSprite.spriteImageFrameWidths[spr.imageId];
484 int ch = spr.h;
485 g.setClip(cx, cy, cw, ch);
486
487 // calculate the x coordinate of where to start the image paint, so our frame will be seen through the clip window
488 int dx = spr.x - spr.frameId * GameSprite.spriteImageFrameWidths[spr.imageId];
489
490 // paint the sprites image at the calculated coordinates
491 g.drawImage(spriteImages[spr.imageId], dx, spr.y, Graphics.TOP | Graphics.LEFT);
492
493 // restore the clip window
494 g.setClip(0, 0, canvasWidth, canvasHeight);
495 }
496
497 public static void paintStatusBars(Graphics g)
498 {
499 int max_energy_bar_width = canvasWidth/2;
500
501 // paint the energy bar
502 g.setColor(0xFFFFFF);
503 g.drawRect(5, 10, max_energy_bar_width + 1, 4);
504 g.setColor(0xFFCC00);
505 g.fillRect(6, 11, player.energy * max_energy_bar_width / player.energyMax, 3);
506
507 // paint the score count
508 g.setColor(0xFFFFFF);
509 g.setFont(Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_SMALL));
510 g.drawString(""+player_score, canvasWidth-4, 8, Graphics.TOP | Graphics.RIGHT);
511 }
512
513 public void startGame()
514 {
515 // switch to game mode
516 mode = MODE_GAME;
517
518 player_score = 0;
519 player_gameover_explosion_counter = -1;
520
521 // initialize the enemy sprites list
522 enemySprites = new Vector();
523
524 // initialize the explosion sprite list
525 explosionSprites = new Vector();
526
527 // initialize the player fire list
528 playerFireSprites = new Vector();
529
530 Level.loadLevel((byte) 1);
531
532 // init level tiles position to horizontal center and vertical bottom
533 Level.tiles_scroll_x = Level.LEVEL_WIDTH * Level.TILE_SIZE / 2 - canvasWidth /2;
534 Level.tiles_scroll_y = Level.LEVEL_HEIGHT * Level.TILE_SIZE - canvasHeight - 1;
535
536 }
537
538 public void endGame()
539 {
540 // back to menu mode, set the game over text screen
541 mode = MODE_MENU;
542 menuScreen = MENU_SCR_TEXT_GAME_OVER;
543
544 // clean up
545 player = null;
546 enemySprites = null;
547 }
548
549 public void updateEnemySprites()
550 {
551 // check if a new enemy has to be generated
552 if( enemySprites.size() < max_enemy_sprites )
553 {
554 GameSprite new_enemy;
555
556 // create a new enemy
557 // which one?
558 byte img_id = (byte) (SPRITE_IMAGE_ENEMY1 + Math.abs(random.nextInt() % 3));
559
560 new_enemy = new GameSprite(img_id, MAX_ENERGY_ENEMY);
561 switch (img_id)
562 {
563 case SPRITE_IMAGE_ENEMY1:
564 new_enemy.vx = 0;
565 new_enemy.vy = 3;
566 break;
567 case SPRITE_IMAGE_ENEMY2:
568 new_enemy.vx = 0;
569 new_enemy.vy = 6;
570 break;
571 case SPRITE_IMAGE_ENEMY3:
572 new_enemy.vx = random.nextInt() % 2;
573 new_enemy.vy = 3 + random.nextInt() % 2;
574 break;
575 }
576 new_enemy.x = Math.abs(random.nextInt()) % canvasWidth;
577 new_enemy.y = -new_enemy.h;
578
579 // add the new enemy to the enemy sprites list
580 enemySprites.addElement(new_enemy);
581 }
582
583 // move enemy sprites
584 for (int i=0; i < enemySprites.size(); i++)
585 {
586 GameSprite enemy = (GameSprite) enemySprites.elementAt(i);
587
588 // animate sprite to next sprite frame every 3 frames
589 if (global_frame_counter % 3 == 0)
590 enemy.frameId = (byte) ( (enemy.frameId + 1) % (enemy.frameIdMax+1));
591
592 // move the enemy
593 enemy.x += enemy.vx;
594 enemy.y += enemy.vy;
595
596 // if enemy is out of screen
597 if ( (enemy.x > canvasWidth) || (enemy.x+enemy.w < 0) ||
598 (enemy.y > canvasHeight) || (enemy.y+enemy.h < 0) )
599 {
600 enemySprites.removeElementAt(i);
601 }
602 }
603 }
604
605 public void updatePlayerSprite()
606 {
607 if (player_gameover_explosion_counter > 0)
608 {
609 player_gameover_explosion_counter--;
610 }
611 else
612 {
613 // move player sprite on command, and check player <-> screen edge collision
614 if (command_up)
615 {
616 player.y -= player.vy;
617 if (player.y < 0)
618 player.y = 0;
619 }
620 if (command_down)
621 {
622 player.y += player.vy;
623 if (player.y > canvasHeight - player.h)
624 player.y = canvasHeight - player.h;
625 }
626 player.frameId = SPRITE_FRAME_PLAYER_CENTER;
627 if (command_left)
628 {
629 player.x -= player.vx;
630 if (player.x < 0)
631 player.x = 0;
632 player.frameId = SPRITE_FRAME_PLAYER_LEFT;
633 }
634 if (command_right)
635 {
636 player.x += player.vx;
637 if (player.x > canvasWidth - player.w)
638 player.x = canvasWidth - player.w;
639 player.frameId = SPRITE_FRAME_PLAYER_RIGHT;
640 }
641 if (command_fire)
642 {
643 if (fire_cooldown_wait_frames_counter <= 0)
644 {
645 GameSprite fire = new GameSprite(SPRITE_IMAGE_FIRE, MAX_ENERGY_PLAYER_FIRE);
646 fire.x = player.x + player.w/2 - fire.w/2;
647 fire.y = player.y;
648 fire.vy = -4;
649 playerFireSprites.addElement(fire);
650
651 fire_cooldown_wait_frames_counter = FIRE_COOLDOWN_WAIT_FRAMES;
652 }
653 }
654 if (fire_cooldown_wait_frames_counter > 0)
655 fire_cooldown_wait_frames_counter--;
656 }
657 }
658
659 public void doCollision()
660 {
661
662 int i = 0;
663 while (i < enemySprites.size())
664 {
665 GameSprite enemy = (GameSprite) enemySprites.elementAt(i);
666
667 // check player <-> enemy collision
668 if (player.collidesWith(enemy))
669 {
670 // add explosion
671 addExplosion(enemy);
672 addExplosion(player);
673
674 // player loses energy
675 player.energy -= player.energyMax/4;
676 if (player.energy <= 0 && player_gameover_explosion_counter < 0)
677 {
678 player_gameover_explosion_counter = PLAYER_GAMEOVER_EXPLOSION_COUNTER;
679 }
680
681 // enemy sprite is destroyed
682 enemySprites.removeElementAt(i);
683 // only increase counter, if not removed from list
684 i--;
685
686 }
687 i++;
688 }
689
690 i = 0;
691 while (i < enemySprites.size())
692 {
693 GameSprite enemy = (GameSprite) enemySprites.elementAt(i);
694
695 // check the player fire sprites <-> enemy collision
696 int j = 0;
697 while (j < playerFireSprites.size())
698 {
699 GameSprite fire = (GameSprite) playerFireSprites.elementAt(j);
700 if (fire.collidesWith(enemy) && i < enemySprites.size())
701 {
702 // add explosions
703 addExplosion(enemy);
704
705 // destroy player fire
706 playerFireSprites.removeElementAt(j);
707 // only increase counter, if not removed from list
708 j--;
709
710 // enemy sprite is destroyed
711 enemySprites.removeElementAt(i);
712 // only increase counter, if not removed from list
713 i--;
714
715 // increase player score
716 player_score += 10;
717 }
718 j++;
719 }
720 i++;
721 }
722 }
723
724 public void updatePlayerFireSprites()
725 {
726 for (int i=0; i < playerFireSprites.size(); i++)
727 {
728 GameSprite fire = (GameSprite) playerFireSprites.elementAt(i);
729 fire.y += fire.vy;
730
731 // destroy player fire when out of screen
732 if (fire.y + fire.h < 0)
733 {
734 playerFireSprites.removeElementAt(i);
735 // only increase counter, if not removed from list
736 i--;
737 }
738 }
739 }
740
741 public void updateExplosionSprites()
742 {
743 for (int i=0; i < explosionSprites.size(); i++)
744 {
745 GameSprite exp = (GameSprite) explosionSprites.elementAt(i);
746
747 // animate explosion!
748 exp.frameId++;
749
750 if (exp.frameId > exp.frameIdMax)
751 {
752 explosionSprites.removeElementAt(i);
753 // only increase counter, if not removed from list
754 i--;
755 }
756 }
757 // create a big bada boom player gameover explosion
758 // 7 - max explosion frames
759 // 2 - add an explosion every 2nd frame
760 if (player_gameover_explosion_counter > 7 &&
761 player_gameover_explosion_counter % 2 == 0
762 )
763 {
764 GameSprite new_exp = addExplosion(player);
765 new_exp.x += random.nextInt() % player.w;
766 new_exp.y += random.nextInt() % player.h;
767 }
768 }
769
770 public static void loadImages()
771 {
772 try {
773
774 spriteImages = new Image[SPRITE_IMAGE_MAX];
775 spriteImages[SPRITE_IMAGE_PLAYER] = Image.createImage("/p.png");
776 spriteImages[SPRITE_IMAGE_FIRE] = Image.createImage("/fire.png");
777 spriteImages[SPRITE_IMAGE_BOSS1] = Image.createImage("/boss1.png");
778 spriteImages[SPRITE_IMAGE_ENEMY1] = Image.createImage("/e1.png");
779 spriteImages[SPRITE_IMAGE_ENEMY2] = Image.createImage("/e2.png");
780 spriteImages[SPRITE_IMAGE_ENEMY3] = Image.createImage("/e3.png");
781 spriteImages[SPRITE_IMAGE_EXPLOSION] = Image.createImage("/exp.png");
782
783 tileImage = Image.createImage("/t04.png");
784
785 imgBackground = Image.createImage("/bg.png");
786
787 } catch (Exception e) {};
788 }
789
790 public static GameSprite addExplosion(GameSprite exp_spr)
791 {
792 // add explosion
793 GameSprite exp = new GameSprite(SPRITE_IMAGE_EXPLOSION, (byte) 0);
794 // center the explosion position on the exploded sprite
795 exp.x = exp_spr.x + exp_spr.w/2 - exp.w/2;
796 exp.y = exp_spr.y + exp_spr.h/2 - exp.h/2;
797 exp.vx = exp_spr.vx;
798 exp.vy = exp_spr.vy;
799 explosionSprites.addElement(exp);
800
801 return exp;
802 }
803 }
804