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