Mercurial > MadButterfly
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 } |