C:\__todo__\tecaj.www\src\Epsilon_05\Level.java
  1  /**
  2   *  Level contains the Level load and paint 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   */
 13 
 14 import java.io.*;
 15 import java.util.Vector;
 16 
 17 import javax.microedition.lcdui.Graphics;
 18 
 19 class Level
 20 {
 21 
 22         public static final byte MAX_LEVELS = 2;
 23 
 24         public static final byte LEVEL_WIDTH = 16;
 25         public static final byte LEVEL_HEIGHT = 64;
 26 
 27         public static final byte LEVEL_WIDTH_SHIFT_FACTOR = 4;
 28         public static final byte LEVEL_HEIGHT_SHIFT_FACTOR = 6;
 29         public static final byte TILE_SIZE_SHIFT_FACTOR = 4;
 30 
 31         public static final byte TILE_SIZE = 16;
 32         public static final byte TILES_PER_IMAGE_LINE = 5;
 33 
 34         // space background position and scroll speed
 35         public static int space_scroll_y;
 36         public static int space_scroll_vy;
 37 
 38         // tiled background position and scroll speed
 39         public static int tiles_scroll_y;
 40         public static int tiles_scroll_vy;
 41         public static int tiles_scroll_x;
 42 
 43         public static byte levelno;
 44 
 45         public static byte[] tileMap;
 46 
 47         //  a translation table for level tile text representation
 48         //  to tile index in the tile image 
 49         public static char[] tileTextToImageIndex = 
 50         {
 51                 "J", "L","^","<",">",
 52                 "\\","/","v","O","G",
 53         };
 54         
 55         public static final byte SPRITE_ID_PLAYER = 0;                          // "P"
 56         public static final byte SPRITE_ID_ENEMY1_SHOOTING = 1;         // "A"
 57         public static final byte SPRITE_ID_ENEMY1 = 2;                          // "a"
 58         public static final byte SPRITE_ID_ENEMY2_SHOOTING = 3;         // "V"
 59         public static final byte SPRITE_ID_ENEMY2 = 4;                          // "v"
 60         public static final byte SPRITE_ID_ENEMY3 = 5;                          // "O"
 61         public static final byte SPRITE_ID_ENEMY3_SINUS = 6;            // "s"
 62         public static final byte SPRITE_ID_ENEMY3_SINUS_SHOOTING = 7;// "S"
 63         public static final byte SPRITE_ID_ENEMY4_SHOOTING = 8;         // "T"
 64         public static final byte SPRITE_ID_BOSS1 = 9;                           // "B"
 65         public static final byte SPRITE_ID_BOSS2 = 10;                          // "C"
 66         public static final byte SPRITE_ID_EXPLOSION = 11;
 67         public static final byte SPRITE_ID_FIRE1 = 12;
 68         public static final byte SPRITE_ID_FIRE2 = 13;
 69         public static final byte SPRITE_ID_FIRE3 = 14;
 70 
 71           
 72         // the coordinate above the screen, when enemy sprites reach it, they start moving, shooting and other AIi tricks..
 73         public static final byte ENEMY_AI_ACTIVATION_ZONE_Y = - 2*TILE_SIZE;
 74         
 75         public static GameSprite boss;
 76         public static Vector enemySprites;
 77         
 78         //  a translation table for level sprite text representation
 79         //  to sprite id
 80         public static char[] spriteTextToSpriteId = 
 81         {
 82                 "P","A","a","V","v","O","s","S","T","B","C"
 83         };
 84 
 85         public static byte getTileIndex(char t)
 86         {
 87                 byte idx = 0;
 88                 // find tile index
 89                 while ( idx < tileTextToImageIndex.length && tileTextToImageIndex[idx] != t )
 90                         idx++;
 91                 
 92                 // handle unexisting or empty tiles
 93                 if (idx > tileTextToImageIndex.length)
 94                         idx = -1;
 95                 
 96                 return idx;
 97         }
 98         
 99         public static byte getSpriteId(char t)
100         {
101                 byte idx = 0;
102                 // find sprite id
103                 while ( idx < spriteTextToSpriteId.length && spriteTextToSpriteId[idx] != t )
104                         idx++;
105                 
106                 // handle unexisting sprites
107                 if (idx > spriteTextToSpriteId.length)
108                         idx = -1;
109                 
110                 return idx;
111         }
112 
113         public static void loadLevel(byte level_no)
114         {
115                 levelno = level_no;
116 
117                 // intialize the scrolling background
118                 space_scroll_y = 0;
119                 space_scroll_vy = (1 << GameSprite.SHIFT_FACTOR) >> 1;
120                 tiles_scroll_vy = -(1 << GameSprite.SHIFT_FACTOR);
121                 
122                 // initialize the enemy sprites list
123                 enemySprites = new Vector();
124 
125                 // temp sprite for creating enemy sprites
126                 GameSprite new_enemy;
127                 
128                 InputStream inputstream = null;
129                 DataInputStream datainputstream = null;
130         
131                 tileMap = new byte[LEVEL_HEIGHT * LEVEL_WIDTH];
132                 int map_row = 0;
133                 int tile_map_col = 0;
134                 int sprite_map_col = 0;
135                 try
136                 {
137                         inputstream = new Object().getClass().getResourceAsStream( "/stage"+ level_no +".txt" );
138                         datainputstream = new DataInputStream(inputstream);
139         
140                         char ch;
141             boolean eof = false;
142             while(!eof)
143             {
144                 // read level text file lines
145                 try
146                 {
147                                 // load a row of tiles
148                         tile_map_col = 0;
149                         ch = " ";
150                         while (ch != ";")
151                         {
152                                 ch = (char) datainputstream.readByte();
153                                 //System.out.print(ch);
154                                 
155                                 if (ch != ";")
156                                 {
157                                         tileMap[ map_row * LEVEL_WIDTH + tile_map_col ] = getTileIndex(ch);
158 
159                                         tile_map_col++;
160                                 }
161                                 else
162                                 {
163                                         break;
164                                 }
165                         }
166                         // load a row of sprites
167                         sprite_map_col = 0;
168                         ch = " ";
169                         while (ch != ";")
170                         {
171                                 ch = (char) datainputstream.readByte();
172                                 //System.out.print(ch);
173 
174                                 int level_x = sprite_map_col * TILE_SIZE;
175                                 int level_y = map_row * TILE_SIZE;
176                                 if (ch != ";")
177                                 {
178                                         byte sprite_id = getSpriteId(ch);
179                                         switch (sprite_id)
180                                         {
181                                         case SPRITE_ID_PLAYER:
182 
183                                                                 // initialize player sprite
184                                                                 GameCanvas.player = new GameSprite( SPRITE_ID_PLAYER );
185                                                                 
186 //                                                              GameCanvas.player.x = GameCanvas.canvasWidth / 2 - GameCanvas.player.w/2;
187 //                                                              GameCanvas.player.y = GameCanvas.canvasHeight - GameCanvas.player.h - GameCanvas.player.h/2;
188                                                                 
189                                                                 GameCanvas.player.x = level_x << GameSprite.SHIFT_FACTOR;
190                                                                 GameCanvas.player.y = level_y << GameSprite.SHIFT_FACTOR;
191 
192                                                                 Level.tiles_scroll_x = GameCanvas.player.x + ((GameCanvas.player.w/2 - GameCanvas.canvasWidth/2) << GameSprite.SHIFT_FACTOR);
193 
194                                                                 GameCanvas.player.frameId = GameCanvas.SPRITE_FRAME_PLAYER_CENTER;
195                                                                 break;
196                                         
197                                         case SPRITE_ID_ENEMY1:
198                                         case SPRITE_ID_ENEMY1_SHOOTING:
199                                         case SPRITE_ID_ENEMY2:
200                                         case SPRITE_ID_ENEMY2_SHOOTING:
201                                         case SPRITE_ID_ENEMY3:
202                                         case SPRITE_ID_ENEMY3_SINUS:
203                                         case SPRITE_ID_ENEMY3_SINUS_SHOOTING:
204                                         case SPRITE_ID_ENEMY4_SHOOTING:
205                                         case SPRITE_ID_BOSS1:
206                                         case SPRITE_ID_BOSS2:
207                                                                 // initialize player sprite
208                                                                 new_enemy = new GameSprite( sprite_id );
209 
210                                                                 new_enemy.x = level_x << GameSprite.SHIFT_FACTOR;
211                                                                 new_enemy.y = level_y << GameSprite.SHIFT_FACTOR;
212                                                                 
213                                                                 new_enemy.vx = 0;
214 
215                                                                 switch (sprite_id) {
216 
217                                                 case SPRITE_ID_ENEMY1:
218                                                 case SPRITE_ID_ENEMY1_SHOOTING:
219                                                                 new_enemy.vy = 2 << GameSprite.SHIFT_FACTOR;
220                                                         break;
221                                                 case SPRITE_ID_ENEMY2:
222                                                 case SPRITE_ID_ENEMY2_SHOOTING:
223                                                                 new_enemy.vy = 1 << GameSprite.SHIFT_FACTOR;
224                                                         break;
225                                                 case SPRITE_ID_ENEMY3:
226                                                                 new_enemy.vy = 3 << GameSprite.SHIFT_FACTOR;
227                                                         break;
228                                                 case SPRITE_ID_ENEMY3_SINUS:
229                                                 case SPRITE_ID_ENEMY3_SINUS_SHOOTING:
230                                                         // sinusoidal movement...
231                                                                 new_enemy.vy = 2 << GameSprite.SHIFT_FACTOR;
232                                                         break;
233                                                 case SPRITE_ID_ENEMY4_SHOOTING:
234                                                         // lock this sprite to tiles, it is a gun turret!
235                                                                 new_enemy.vy = 0;
236                                                         break;
237                                                 case SPRITE_ID_BOSS1:
238                                                 case SPRITE_ID_BOSS2:
239                                                                 new_enemy.vy = 0;
240                                                                 new_enemy.vx = 1 << GameSprite.SHIFT_FACTOR;
241                                                                 
242                                                                 // save a reference to boss sprite
243                                                                 boss = new_enemy;
244                                                                 
245                                                         break;
246                                                 }
247 
248                                                                 enemySprites.addElement(new_enemy);
249                                                                 
250                                                                 //System.out.println("new enemy sprite "+ sprite_id +" at "+level_x+", "+level_y+" vy: "+ new_enemy.vy);
251                                                                 break;
252                                                                 
253                                                         }
254                                         
255                                 sprite_map_col++;
256                                 }
257                                 else
258                                 {
259                                 
260                                         //System.out.println();
261 
262                                         // read 0x0D and 0x0A  (CR, LF)
263                                         ch = (char) datainputstream.readByte();
264                                         ch = (char) datainputstream.readByte();
265 
266                                         break;
267                                 }
268                         }
269 
270                         // go to next line of text
271                         map_row++;
272                 }
273                 catch (EOFException eofex)
274                 {
275                         eof = true;
276                 }
277             }
278                         inputstream.close();
279                         inputstream = null;
280                 }
281                 catch (Exception ex)
282                 {
283                         ex.printStackTrace();
284                 }
285         }
286 
287         public static void paintTiles(Graphics g)
288         {
289                 // clip window coordinates
290                 int cx, cy, cw, ch;
291                 // image draw coordinates
292                 int dx, dy;
293                 
294                 int tsx = (tiles_scroll_x >> GameSprite.SHIFT_FACTOR);
295                 int tsy = (tiles_scroll_y >> GameSprite.SHIFT_FACTOR);
296                 
297                 int x;
298                 int y = 0;
299 
300                 while (y <= GameCanvas.canvasHeight)
301                 {
302                         x = 0;
303                         int ty = tsy + y;
304                         while (x <= GameCanvas.canvasWidth)
305                         {
306                                 // get the tileMap index of the tile, located at tx, ty
307                                 int tx = tsx + x;
308                                 int tile_idx = ((ty >> TILE_SIZE_SHIFT_FACTOR) << LEVEL_WIDTH_SHIFT_FACTOR) + (tx >> TILE_SIZE_SHIFT_FACTOR);
309 
310                                 // get tile index in image from tileMap
311                                 byte tile_image_idx = tileMap[tile_idx];
312 
313                                 if ( tile_image_idx >= 0)
314                                 {
315                                         // get tile level coordinates from tile index
316                                         int tile_idx_x = (tile_idx % LEVEL_WIDTH) << TILE_SIZE_SHIFT_FACTOR;
317                                         int tile_idx_y = (tile_idx >> LEVEL_WIDTH_SHIFT_FACTOR) << TILE_SIZE_SHIFT_FACTOR;
318 
319                                         // translate to screen coordinates
320                                         tile_idx_x -= tsx;
321                                         tile_idx_y -= tsy;
322                                         
323                                         int tile_col = tile_image_idx % TILES_PER_IMAGE_LINE;
324                                         int tile_row = tile_image_idx / TILES_PER_IMAGE_LINE;
325                                         
326                                         cx = tile_idx_x;
327                                         cy = tile_idx_y;
328                                         cw = TILE_SIZE;
329                                         ch = TILE_SIZE;
330 
331                                         //  check clip window coordinates, if out of screen
332                                         if (cx < 0)
333                                         {
334                                                 cw += cx;
335                                                 cx = 0;
336                                         }
337                                         if (cy < 0)
338                                         {
339                                                 ch += cy;
340                                                 cy = 0;
341                                         }
342 
343                                         //  check clip window size, if out of screen
344                                         if (cx + cw > GameCanvas.canvasWidth)
345                                                 cw -= (cx + cw) - GameCanvas.canvasWidth; 
346                                         if (cy + ch > GameCanvas.canvasHeight)
347                                                 ch -= (cy + ch) - GameCanvas.canvasHeight; 
348                                         
349                                         dx = tile_idx_x - (tile_col << TILE_SIZE_SHIFT_FACTOR);
350                                         dy = tile_idx_y - (tile_row << TILE_SIZE_SHIFT_FACTOR);
351                                         
352                                         g.setClip(cx, cy, cw, ch);
353                                         g.drawImage(GameCanvas.tileImage, dx, dy, Graphics.TOP | Graphics.LEFT);
354                                 }
355 
356                                 x += TILE_SIZE;
357                         }
358                 
359                         y += TILE_SIZE;
360                 }
361                 g.setClip(0, 0, GameCanvas.canvasWidth, GameCanvas.canvasHeight);
362         }
363 
364         public static void paintSpaceBackground(Graphics g)
365         {
366                 if (GameCanvas.mode == GameCanvas.MODE_GAME && GameCanvas.player_nuke_counter > 0)
367                 {
368                         // nuke explosion fx
369                         int R = (GameCanvas.player_nuke_counter*16-1);
370                         int G = (GameCanvas.player_nuke_counter*16-1);
371                         int B = (GameCanvas.player_nuke_counter*16-1);
372                         if (R < 0) R = 0;
373                         if (G < 0) G = 0;
374                         if (B < 0) B = 0;
375                         g.setColor(R, G, B);
376                         g.fillRect(0, 0, GameCanvas.canvasWidth, GameCanvas.canvasHeight);
377                 }
378                 else
379                 {
380                         // fill the vast space
381                         g.setColor(0x000000);
382                         g.fillRect(0, 0, GameCanvas.canvasWidth, GameCanvas.canvasHeight);
383                         
384                         // init scrolling background image tiling
385                         int x = 0;
386                         int y = (space_scroll_y >> GameSprite.SHIFT_FACTOR) % GameCanvas.imgBackground.getHeight() - GameCanvas.imgBackground.getHeight();
387         
388                         // image is wide enough, so we only need to tile it in the vertical (y) direction
389                         while (y < GameCanvas.canvasHeight)
390                         {
391                                 g.drawImage(GameCanvas.imgBackground, x, y, Graphics.TOP | Graphics.LEFT);
392                         
393                                 y += GameCanvas.imgBackground.getHeight();
394                         }
395                 }
396         }
397 
398 }
399