comparison examples/tank/tank_main.c @ 154:6ce68c1f7405

Tank can fire bullet. 1. Add the redraw subject on redraw_man_t. 2. mb_c_source.m4 & mb_c_header.m4 are changed to free & remove shapes. 3. Add rdman_coord_subtree_free() to remove a subtree of coords. 4. Fix bug of rdman_remove_shape().
author Thinker K.F. Li <thinker@branda.to>
date Tue, 30 Sep 2008 02:44:06 +0800
parents 9870b049b7f6
children 6749f6639924
comparison
equal deleted inserted replaced
153:9870b049b7f6 154:6ce68c1f7405
38 38
39 /*! \defgroup tank_elf Tank Elf 39 /*! \defgroup tank_elf Tank Elf
40 * \brief Tank elf module provides control functions of tanks in game. 40 * \brief Tank elf module provides control functions of tanks in game.
41 * @{ 41 * @{
42 */ 42 */
43 struct _tank_bullet {
44 redraw_man_t *rdman;
45 coord_t *coord_pos;
46 coord_t *coord_rot;
47 bullet_t *bullet_obj;
48 int start_map_x, start_map_y;
49 int direction;
50 mb_progm_t *progm;
51 mb_timeval_t start_time;
52 observer_t *ob_redraw;
53 };
54 typedef struct _tank_bullet tank_bullet_t;
55 enum { BU_UP = 0, BU_RIGHT, BU_DOWN, BU_LEFT };
56
43 struct _tank { 57 struct _tank {
44 coord_t *coord_pos; /*!< \brief coordinate for position */ 58 coord_t *coord_pos; /*!< \brief coordinate for position */
45 coord_t *coord_rot; /*!< \brief coordinate for rotation */ 59 coord_t *coord_rot; /*!< \brief coordinate for rotation */
60 coord_t *coord_center;
46 int map_x, map_y; 61 int map_x, map_y;
47 int direction; 62 int direction;
48 mb_progm_t *progm; 63 mb_progm_t *progm;
64 tank_bullet_t *bullet;
49 }; 65 };
50 typedef struct _tank tank_t; 66 typedef struct _tank tank_t;
51 enum { TD_UP = 0, TD_RIGHT, TD_DOWN, TD_LEFT }; 67 enum { TD_UP = 0, TD_RIGHT, TD_DOWN, TD_LEFT };
52
53 68
54 /* @} */ 69 /* @} */
55 70
56 typedef struct _tank_rt tank_rt_t; 71 typedef struct _tank_rt tank_rt_t;
57 72
90 tank->coord_rot = coord_rot; 105 tank->coord_rot = coord_rot;
91 tank->map_x = map_x; 106 tank->map_x = map_x;
92 tank->map_y = map_y; 107 tank->map_y = map_y;
93 tank->direction = TD_UP; 108 tank->direction = TD_UP;
94 tank->progm = NULL; 109 tank->progm = NULL;
110 tank->bullet = NULL;
95 111
96 memset(coord_pos->matrix, 0, sizeof(co_aix[6])); 112 memset(coord_pos->matrix, 0, sizeof(co_aix[6]));
97 coord_pos->matrix[0] = 1; 113 coord_pos->matrix[0] = 1;
98 coord_pos->matrix[2] = map_x * 50; 114 coord_pos->matrix[2] = map_x * 50;
99 coord_pos->matrix[4] = 1; 115 coord_pos->matrix[4] = 1;
231 mb_progm_start(progm, tman, &now); 247 mb_progm_start(progm, tman, &now);
232 } 248 }
233 249
234 /* @} */ 250 /* @} */
235 251
252 /*! \brief Make coord objects for bullet elfs. */
253 static void make_bullet_elf_coords(redraw_man_t *rdman, coord_t **coord_pos,
254 coord_t **coord_rot,
255 coord_t **coord_center) {
256 coord_t *coord_back;
257
258 *coord_pos = rdman_coord_new(rdman, rdman->root_coord);
259
260 coord_back = rdman_coord_new(rdman, *coord_pos);
261 coord_back->matrix[2] = 25;
262 coord_back->matrix[5] = 25;
263 rdman_coord_changed(rdman, coord_back);
264
265 *coord_rot = rdman_coord_new(rdman, coord_back);
266
267 *coord_center = rdman_coord_new(rdman, *coord_rot);
268 (*coord_center)->matrix[2] = -5;
269 (*coord_center)->matrix[5] = +15;
270 rdman_coord_changed(rdman, *coord_center);
271 }
272
273 static tank_bullet_t *tank_bullet_new(redraw_man_t *rdman,
274 int map_x, int map_y,
275 int direction) {
276 tank_bullet_t *bullet;
277 coord_t *coord_center;
278 co_aix *matrix;
279 static float _sins[] = { 0, 1, 0, -1};
280 static float _coss[] = { 1, 0, -1, 0};
281 float _sin, _cos;
282
283 bullet = O_ALLOC(tank_bullet_t);
284 bullet->rdman = rdman;
285
286 make_bullet_elf_coords(rdman, &bullet->coord_pos,
287 &bullet->coord_rot,
288 &coord_center);
289 bullet->bullet_obj = bullet_new(rdman, coord_center);
290
291 bullet->start_map_x = map_x;
292 bullet->start_map_y = map_y;
293 bullet->direction = direction;
294 bullet->progm = NULL;
295
296 matrix = bullet->coord_pos->matrix;
297 matrix[2] = map_x * 50;
298 matrix[5] = map_y * 50;
299 rdman_coord_changed(rdman, bullet->coord_pos);
300
301 _sin = _sins[direction];
302 _cos = _coss[direction];
303 matrix = bullet->coord_rot->matrix;
304 matrix[0] = _cos;
305 matrix[1] = -_sin;
306 matrix[3] = _sin;
307 matrix[4] = _cos;
308
309 return bullet;
310 }
311
312 static void tank_bullet_free(tank_bullet_t *bullet) {
313 bullet_free(bullet->bullet_obj);
314 rdman_coord_subtree_free(bullet->rdman, bullet->coord_pos);
315 }
316
317 static void bullet_go_out_map_and_redraw(event_t *event, void *arg) {
318 tank_t *tank = (tank_t *)arg;
319 tank_bullet_t *bullet;
320 ob_factory_t *factory;
321 subject_t *redraw;
322
323 bullet = tank->bullet;
324 mb_progm_free(bullet->progm);
325 rdman_force_clean(bullet->rdman);
326 factory = rdman_get_ob_factory(bullet->rdman);
327 redraw = rdman_get_redraw_subject(bullet->rdman);
328 subject_remove_observer(factory, redraw, bullet->ob_redraw);
329 tank_bullet_free(tank->bullet);
330 tank->bullet = NULL;
331 }
332
333 static void bullet_go_out_map(event_t *event, void *arg) {
334 tank_t *tank = (tank_t *)arg;
335 tank_bullet_t *bullet;
336 redraw_man_t *rdman;
337 subject_t *redraw;
338 ob_factory_t *factory;
339
340 /*! \todo Simplify the procdure of using observer pattern. */
341 bullet = tank->bullet;
342 rdman = bullet->rdman;
343 factory = rdman_get_ob_factory(rdman);
344 redraw = rdman_get_redraw_subject(rdman);
345 bullet->ob_redraw =
346 subject_add_observer(factory, redraw,
347 bullet_go_out_map_and_redraw, tank);
348 }
349
350 static void tank_fire_bullet(tank_rt_t *tank_rt, tank_t *tank) {
351 X_MB_runtime_t *xmb_rt;
352 redraw_man_t *rdman;
353 int map_x, map_y;
354 int shift_x, shift_y;
355 int shift_len;
356 int dir;
357 tank_bullet_t *bullet;
358 mb_progm_t *progm;
359 mb_word_t *word;
360 mb_action_t *act;
361 mb_timeval_t start, playing;
362 mb_timeval_t now;
363 ob_factory_t *factory;
364 mb_tman_t *tman;
365 subject_t *subject;
366 static int map_xy_adj[][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
367
368 if(tank->bullet != NULL)
369 return;
370
371 xmb_rt = tank_rt->mb_rt;
372 rdman = X_MB_rdman(xmb_rt);
373 tman = X_MB_tman(xmb_rt);
374
375 dir = tank->direction;
376 map_x = tank->map_x + map_xy_adj[dir][0];
377 map_y = tank->map_y + map_xy_adj[dir][1];
378 tank->bullet = tank_bullet_new(rdman, map_x, map_y, dir);
379 bullet = tank->bullet;
380
381 switch(dir) {
382 case TD_UP:
383 shift_len = map_y + 1;
384 shift_x = 0;
385 shift_y = -shift_len * 50;
386 break;
387 case TD_RIGHT:
388 shift_len = 16 - map_x;
389 shift_x = shift_len * 50;
390 shift_y = 0;
391 break;
392 case TD_DOWN:
393 shift_len = 12 - map_y;
394 shift_x = 0;
395 shift_y = shift_len * 50;
396 break;
397 case TD_LEFT:
398 shift_len = map_x + 1;
399 shift_x = -shift_len * 50;
400 shift_y = 0;
401 break;
402 }
403
404 progm = mb_progm_new(2, rdman);
405 MB_TIMEVAL_SET(&start, 0, 0);
406 MB_TIMEVAL_SET(&playing, shift_len / 4, (shift_len % 4) * 250000);
407 word = mb_progm_next_word(progm, &start, &playing);
408 act = mb_shift_new(shift_x, shift_y, bullet->coord_pos, word);
409 bullet->progm = progm;
410
411 subject = mb_progm_get_complete(progm);
412 factory = rdman_get_ob_factory(rdman);
413 subject_add_observer(factory, subject, bullet_go_out_map, tank);
414
415 get_now(&now);
416 MB_TIMEVAL_CP(&bullet->start_time, &now);
417 mb_progm_start(progm, tman, &now);
418 }
419
236 #define CHANGE_POS(g, x, y) do { \ 420 #define CHANGE_POS(g, x, y) do { \
237 (g)->root_coord->matrix[0] = 1.0; \ 421 (g)->root_coord->matrix[0] = 1.0; \
238 (g)->root_coord->matrix[2] = x; \ 422 (g)->root_coord->matrix[2] = x; \
239 (g)->root_coord->matrix[4] = 1.0; \ 423 (g)->root_coord->matrix[4] = 1.0; \
240 (g)->root_coord->matrix[5] = y; \ 424 (g)->root_coord->matrix[5] = y; \
269 direction = TD_DOWN; 453 direction = TD_DOWN;
270 tank_move(tank_rt->tank1, direction, tank_rt); 454 tank_move(tank_rt->tank1, direction, tank_rt);
271 break; 455 break;
272 456
273 case 0x20: /* space */ 457 case 0x20: /* space */
458 tank_fire_bullet(tank_rt, tank_rt->tank1);
274 break; 459 break;
275 case 0xff0d: /* enter */ 460 case 0xff0d: /* enter */
276 default: 461 default:
277 return; 462 return;
278 } 463 }