comparison examples/tank/tank_main.c @ 131:6a8588df68af

Tank can change direction and navigate on the mud area
author Thinker K.F. Li <thinker@branda.to>
date Wed, 17 Sep 2008 01:30:25 +0800
parents 3a4d6179e6a9
children c65b30e2eda9
comparison
equal deleted inserted replaced
130:3a4d6179e6a9 131:6a8588df68af
1 #include <sys/time.h> 1 #include <sys/time.h>
2 #include <string.h>
2 #include <mb/mb.h> 3 #include <mb/mb.h>
4 #include <mb/tools.h>
3 #include "svgs.h" 5 #include "svgs.h"
4 6
5 enum { MUD, ROC, BRI, BSH }; 7 enum { MUD, ROC, BRI, BSH };
6 8
7 static char map[12][16] = { 9 static char map[12][16] = {
29 MUD, BRI, MUD, MUD, MUD, BRI, BRI, MUD}, 31 MUD, BRI, MUD, MUD, MUD, BRI, BRI, MUD},
30 { MUD, MUD, MUD, MUD, MUD, MUD, BRI, MUD, 32 { MUD, MUD, MUD, MUD, MUD, MUD, BRI, MUD,
31 MUD, BRI, MUD, BRI, MUD, MUD, MUD, MUD} 33 MUD, BRI, MUD, BRI, MUD, MUD, MUD, MUD}
32 }; 34 };
33 35
36 #define MAP_W 16
37 #define MAP_H 12
38
39 /*! \defgroup tank_elf Tank Elf
40 * \brief Tank elf module provides control functions of tanks in game.
41 * @{
42 */
43 struct _tank {
44 coord_t *coord_pos; /*!< \brief coordinate for position */
45 coord_t *coord_rot; /*!< \brief coordinate for rotation */
46 int map_x, map_y;
47 int direction;
48 mb_progm_t *progm;
49 };
50 typedef struct _tank tank_t;
51 enum { TD_UP = 0, TD_RIGHT, TD_DOWN, TD_LEFT };
52
53 static tank_t *tank_new(coord_t *coord_pos,
54 coord_t *coord_rot,
55 int map_x, int map_y,
56 X_MB_runtime_t *mb_rt) {
57 tank_t *tank;
58 redraw_man_t *rdman;
59
60 tank = O_ALLOC(tank_t);
61 if(tank == NULL)
62 return NULL;
63
64 rdman = X_MB_rdman(mb_rt);
65
66 tank->coord_pos = coord_pos;
67 tank->coord_rot = coord_rot;
68 tank->map_x = map_x;
69 tank->map_y = map_y;
70 tank->direction = TD_UP;
71 tank->progm = NULL;
72
73 memset(coord_pos->matrix, 0, sizeof(co_aix[6]));
74 coord_pos->matrix[0] = 1;
75 coord_pos->matrix[2] = map_x * 50;
76 coord_pos->matrix[4] = 1;
77 coord_pos->matrix[5] = map_y * 50;
78 rdman_coord_changed(rdman, coord_pos);
79
80 return tank;
81 }
82
83 static void tank_free(tank_t *tank, X_MB_runtime_t *xmb_rt) {
84 mb_tman_t *tman;
85
86 if(tank->progm) {
87 tman = X_MB_tman(xmb_rt);
88 mb_progm_abort(tank->progm, tman);
89 }
90 free(tank);
91 }
92
93 /*! \brief Clean program for a tank.
94 *
95 * It is called when the program is completed.
96 */
97 static void clean_tank_progm_handler(event_t *event, void *arg) {
98 tank_t *tank = (tank_t *)arg;
99
100 mb_progm_free(tank->progm);
101 tank->progm = NULL;
102 }
103
104 #define PI 3.1415926
105
106 static void tank_move(tank_t *tank, int direction,
107 X_MB_runtime_t *xmb_rt) {
108 redraw_man_t *rdman;
109 mb_tman_t *tman;
110 ob_factory_t *factory;
111 /* for the program */
112 mb_progm_t *progm;
113 subject_t *comp_sub;
114 mb_word_t *word;
115 mb_timeval_t start, playing;
116 mb_timeval_t now;
117 /* for position */
118 co_aix sh_x, sh_y;
119 /* for direction */
120 float ang1, ang2;
121 float rot_diff;
122 static co_aix shift_xy[][2] = {{0, -50}, {50, 0}, {0, 50}, {-50, 0}};
123 static int map_shift[4][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
124 static float angles[4] = {0, PI / 2, PI , PI * 3 / 2};
125 static float rotations[7] = {PI / 2, PI , -PI / 2,
126 0, PI / 2, PI , -PI / 2};
127
128 if(tank->progm != NULL)
129 return;
130
131 /*
132 * Keep inside the map.
133 */
134 if(direction == tank->direction) {
135 switch(direction) {
136 case TD_UP:
137 if(tank->map_y == 0)
138 return;
139 if(map[tank->map_y - 1][tank->map_x] != MUD)
140 return;
141 break;
142 case TD_RIGHT:
143 if(tank->map_x >= (MAP_W - 1))
144 return;
145 if(map[tank->map_y][tank->map_x + 1] != MUD)
146 return;
147 break;
148 case TD_DOWN:
149 if(tank->map_y >= (MAP_H - 1))
150 return;
151 if(map[tank->map_y + 1][tank->map_x] != MUD)
152 return;
153 break;
154 case TD_LEFT:
155 if(tank->map_x == 0)
156 return;
157 if(map[tank->map_y][tank->map_x - 1] != MUD)
158 return;
159 break;
160 }
161 }
162
163 rdman = X_MB_rdman(xmb_rt);
164 tman = X_MB_tman(xmb_rt);
165 factory = X_MB_ob_factory(xmb_rt);
166
167 progm = mb_progm_new(1, rdman);
168 tank->progm = progm;
169
170 MB_TIMEVAL_SET(&start, 0, 0);
171 MB_TIMEVAL_SET(&playing, 0, 500000);
172 word = mb_progm_next_word(progm, &start, &playing);
173
174 if(direction == tank->direction) {
175 /* Shift/move */
176 sh_x = shift_xy[direction][0];
177 sh_y = shift_xy[direction][1];
178 mb_shift_new(sh_x, sh_y, tank->coord_pos, word);
179 tank->map_x += map_shift[direction][0];
180 tank->map_y += map_shift[direction][1];
181 } else {
182 /* Change direction */
183 rot_diff = rotations[3 - tank->direction + direction];
184 ang1 = angles[tank->direction];
185 ang2 = ang1 + rot_diff;
186 mb_rotate_new(ang1, ang2, tank->coord_rot, word);
187 tank->direction = direction;
188 }
189
190 /* Clean program when it is completed. */
191 comp_sub = mb_progm_get_complete(progm);
192 subject_add_observer(factory, comp_sub,
193 clean_tank_progm_handler, tank);
194
195 get_now(&now);
196 mb_progm_start(progm, tman, &now);
197 }
198
199 /* @} */
200
34 typedef struct _tank_rt tank_rt_t; 201 typedef struct _tank_rt tank_rt_t;
35 202
36 struct _tank_rt { 203 struct _tank_rt {
37 tank1_t *tank1; 204 tank_t *tank1;
38 tank2_t *tank2; 205 tank1_t *tank1_o;
206 tank_t *tank2;
207 tank2_t *tank2_o;
39 int n_enemy; 208 int n_enemy;
40 tank_en_t *tank_enemies[10]; 209 tank_t *tank_enemies[10];
210 tank_en_t *tank_enemies_o[10];
41 void *map[12][16]; 211 void *map[12][16];
42 X_MB_runtime_t *mb_rt; 212 X_MB_runtime_t *mb_rt;
43
44 mb_progm_t *tank1_progm;
45
46 observer_t *kb_observer; 213 observer_t *kb_observer;
47 }; 214 };
48 215
49 #define CHANGE_POS(g, x, y) do { \ 216 #define CHANGE_POS(g, x, y) do { \
50 (g)->root_coord->matrix[0] = 1.0; \ 217 (g)->root_coord->matrix[0] = 1.0; \
52 (g)->root_coord->matrix[4] = 1.0; \ 219 (g)->root_coord->matrix[4] = 1.0; \
53 (g)->root_coord->matrix[5] = y; \ 220 (g)->root_coord->matrix[5] = y; \
54 rdman_coord_changed(rdman, (g)->root_coord); \ 221 rdman_coord_changed(rdman, (g)->root_coord); \
55 } while(0) 222 } while(0)
56 223
57 static void free_progm_handler(event_t *event, void *arg) {
58 tank_rt_t *tank_rt = (tank_rt_t *)arg;
59
60 mb_progm_free(tank_rt->tank1_progm);
61 tank_rt->tank1_progm = NULL;
62 }
63
64 static void keyboard_handler(event_t *event, void *arg) { 224 static void keyboard_handler(event_t *event, void *arg) {
65 X_kb_event_t *xkey = (X_kb_event_t *)event; 225 X_kb_event_t *xkey = (X_kb_event_t *)event;
66 tank_rt_t *tank_rt = (tank_rt_t *)arg; 226 tank_rt_t *tank_rt = (tank_rt_t *)arg;
67 redraw_man_t *rdman; 227 int direction;
68 mb_tman_t *tman; 228
69 mb_word_t *word; 229 if(xkey->event.type != EVT_KB_PRESS)
70 ob_factory_t *factory;
71 subject_t *comp_sub;
72 mb_timeval_t start_tm, playing, now;
73
74 if(tank_rt->tank1_progm != NULL)
75 return; 230 return;
76
77 rdman = X_MB_rdman(tank_rt->mb_rt);
78 tman = X_MB_tman(tank_rt->mb_rt);
79
80 tank_rt->tank1_progm = mb_progm_new(2, rdman);
81 comp_sub = mb_progm_get_complete(tank_rt->tank1_progm);
82 factory = rdman_get_ob_factory(rdman);
83 subject_add_observer(factory, comp_sub,
84 free_progm_handler,
85 tank_rt);
86
87 MB_TIMEVAL_SET(&start_tm, 0, 0);
88 MB_TIMEVAL_SET(&playing, 0, 500000);
89 word = mb_progm_next_word(tank_rt->tank1_progm,
90 &start_tm, &playing);
91 231
92 switch(xkey->sym) { 232 switch(xkey->sym) {
93 case 0xff51: /* left */ 233 case 0xff51: /* left */
94 mb_shift_new(-50, 0, tank_rt->tank1->root_coord, word); 234 direction = TD_LEFT;
95 break; 235 break;
96 236
97 case 0xff52: /* up */ 237 case 0xff52: /* up */
98 mb_shift_new(0, -50, tank_rt->tank1->root_coord, word); 238 direction = TD_UP;
99 break; 239 break;
100 240
101 case 0xff53: /* right */ 241 case 0xff53: /* right */
102 mb_shift_new(50, 0, tank_rt->tank1->root_coord, word); 242 direction = TD_RIGHT;
103 break; 243 break;
104 244
105 case 0xff54: /* down */ 245 case 0xff54: /* down */
106 mb_shift_new(0, 50, tank_rt->tank1->root_coord, word); 246 direction = TD_DOWN;
107 break; 247 break;
108 248
109 case 0x20: /* space */ 249 case 0x20: /* space */
110 case 0xff0d: /* enter */ 250 case 0xff0d: /* enter */
111 break; 251 default:
112 } 252 return;
113 get_now(&now); 253 }
114 mb_progm_start(tank_rt->tank1_progm, tman, &now); 254
255 tank_move(tank_rt->tank1, direction, tank_rt->mb_rt);
115 } 256 }
116 257
117 static void init_keyboard(tank_rt_t *tank_rt) { 258 static void init_keyboard(tank_rt_t *tank_rt) {
118 X_MB_runtime_t *mb_rt; 259 X_MB_runtime_t *mb_rt;
119 subject_t *kbevents; 260 subject_t *kbevents;
128 269
129 tank_rt->kb_observer = 270 tank_rt->kb_observer =
130 subject_add_observer(factory, kbevents, keyboard_handler, tank_rt); 271 subject_add_observer(factory, kbevents, keyboard_handler, tank_rt);
131 } 272 }
132 273
274 /*! \brief Make coord objects for elfs (tanks). */
275 static void make_elf_coords(redraw_man_t *rdman, coord_t **coord_pos,
276 coord_t **coord_rot, coord_t **coord_center) {
277 coord_t *coord_back;
278
279 *coord_pos = rdman_coord_new(rdman, rdman->root_coord);
280
281 coord_back = rdman_coord_new(rdman, *coord_pos);
282 coord_back->matrix[2] = 25;
283 coord_back->matrix[5] = 25;
284 rdman_coord_changed(rdman, coord_back);
285
286 *coord_rot = rdman_coord_new(rdman, coord_back);
287
288 *coord_center = rdman_coord_new(rdman, *coord_rot);
289 (*coord_center)->matrix[2] = -25;
290 (*coord_center)->matrix[5] = -25;
291 rdman_coord_changed(rdman, *coord_center);
292 }
293
133 void 294 void
134 initial_tank(tank_rt_t *tank_rt, X_MB_runtime_t *mb_rt) { 295 initial_tank(tank_rt_t *tank_rt, X_MB_runtime_t *mb_rt) {
135 redraw_man_t *rdman; 296 redraw_man_t *rdman;
136 mb_tman_t *tman; 297 /* for map areas */
137 mud_t *mud; 298 mud_t *mud;
138 brick_t *brick; 299 brick_t *brick;
139 rock_t *rock; 300 rock_t *rock;
140 bush_t *bush; 301 bush_t *bush;
141 mb_word_t *word; 302 /* for tanks */
142 mb_timeval_t start, playing; 303 coord_t *coord_center, *coord_pos, *coord_rot;
143 mb_timeval_t mbtv; 304 tank1_t *tank1_o;
144 subject_t *comp_sub; 305 tank2_t *tank2_o;
145 ob_factory_t *factory; 306 tank_en_t *tank_en_o;
146 int i, j; 307 int i, j;
147 308
148 rdman = X_MB_rdman(mb_rt); 309 rdman = X_MB_rdman(mb_rt);
149 310
150 tank_rt->mb_rt = mb_rt; 311 tank_rt->mb_rt = mb_rt;
173 break; 334 break;
174 } 335 }
175 } 336 }
176 } 337 }
177 338
178 tank_rt->tank1 = tank1_new(rdman, rdman->root_coord); 339 make_elf_coords(rdman, &coord_pos, &coord_rot, &coord_center);
179 CHANGE_POS(tank_rt->tank1, 5 * 50, 11 * 50); 340 tank1_o = tank1_new(rdman, coord_center);
180 tank_rt->tank2 = tank2_new(rdman, rdman->root_coord); 341 tank_rt->tank1 = tank_new(coord_pos, coord_rot, 5, 11, mb_rt);
181 CHANGE_POS(tank_rt->tank2, 10 * 50, 11 * 50); 342 tank_rt->tank1_o = tank1_o;
343
344 make_elf_coords(rdman, &coord_pos, &coord_rot, &coord_center);
345 tank2_o = tank2_new(rdman, coord_center);
346 tank_rt->tank2 = tank_new(coord_pos, coord_rot, 10, 11, mb_rt);
347 tank_rt->tank2_o = tank2_o;
348
182 for(i = 0; i < 3; i++) { 349 for(i = 0; i < 3; i++) {
183 tank_rt->tank_enemies[i] = tank_en_new(rdman, rdman->root_coord); 350 make_elf_coords(rdman, &coord_pos, &coord_rot, &coord_center);
184 CHANGE_POS(tank_rt->tank_enemies[i], (2 + i * 3) * 50, 0); 351 tank_en_o = tank_en_new(rdman, coord_center);
352 tank_rt->tank_enemies[i] = tank_new(coord_pos, coord_rot,
353 i * 3 + 3, 0, mb_rt);
354 tank_rt->tank_enemies_o[i] = tank_en_o;
185 } 355 }
186 tank_rt->n_enemy = i; 356 tank_rt->n_enemy = i;
187
188 tank_rt->tank1_progm = mb_progm_new(4, rdman);
189
190 MB_TIMEVAL_SET(&start, 1, 0);
191 MB_TIMEVAL_SET(&playing, 3, 0);
192 word = mb_progm_next_word(tank_rt->tank1_progm, &start, &playing);
193
194 mb_shift_new(0, -150, tank_rt->tank1->root_coord, word);
195 mb_shift_new(0, -150, tank_rt->tank2->root_coord, word);
196
197 MB_TIMEVAL_SET(&start, 5, 0);
198 MB_TIMEVAL_SET(&playing, 3, 0);
199 word = mb_progm_next_word(tank_rt->tank1_progm, &start, &playing);
200
201 mb_shift_new(0, 150, tank_rt->tank1->root_coord, word);
202 mb_shift_new(0, 150, tank_rt->tank2->root_coord, word);
203
204 /* Free program after program completed. */
205 comp_sub = mb_progm_get_complete(tank_rt->tank1_progm);
206 factory = rdman_get_ob_factory(rdman);
207 subject_add_observer(factory, comp_sub, free_progm_handler, tank_rt);
208
209 tman = X_MB_tman(mb_rt);
210 get_now(&mbtv);
211 mb_progm_start(tank_rt->tank1_progm, tman, &mbtv);
212 357
213 init_keyboard(tank_rt); 358 init_keyboard(tank_rt);
214 } 359 }
215 360
216 int 361 int