Revision 309
finally done with zombies!
proj/include/ent.h | ||
---|---|---|
71 | 71 |
int (map_collides_bullet)(const map_t *p, const bullet_t *bullet); |
72 | 72 |
int16_t (map_get_width) (const map_t *p); |
73 | 73 |
int16_t (map_get_height) (const map_t *p); |
74 |
int (map_make_dijkstra)(map_t *p, uint16_t x, uint16_t y); |
|
74 |
int (map_make_dijkstra)(map_t *p, int16_t x, int16_t y); |
|
75 |
int (map_where_to_follow)(const map_t *p, float x, float y, float *theta); |
|
75 | 76 |
int (gunner_collides_bullet)(const gunner_t *shooter, const bullet_t *bull); |
76 | 77 |
double (distance_gunners)(const gunner_t *shooter1, const gunner_t *shooter2); |
77 | 78 |
int (gunner_collides_gunner)(const gunner_t *shooter1, const gunner_t *shooter2); |
proj/include/proj_macros.h | ||
---|---|---|
29 | 29 |
#define MELEE_RANGE 80 |
30 | 30 |
#define MELEE_DAMAGE 1 |
31 | 31 |
|
32 |
#define ZOMBIE_SPEED 1.0 |
|
33 |
|
|
32 | 34 |
#endif /* end of include guard: PROJ_MACROS_H_INCLUDED */ |
proj/src/ent.c | ||
---|---|---|
216 | 216 |
basic_sprite_t *bsp_background; |
217 | 217 |
sprite_t *background; |
218 | 218 |
uint8_t *collide; |
219 |
int *x_prev; |
|
220 |
int *y_prev; |
|
219 |
uint8_t *collide_gunner; |
|
220 |
int32_t *prev; |
|
221 |
uint8_t *visited; |
|
221 | 222 |
}; |
223 |
static int (map_collides_gunner_pos)(const map_t *p, double shooter_x, double shooter_y, double radius) { |
|
224 |
for (double x = -radius; x <= radius; x += 1) { |
|
225 |
double y1 = sqrt(radius*radius - x*x); |
|
226 |
double y2 = -y1; |
|
227 |
if (map_collides_point(p, shooter_x + x, shooter_y + y1) || map_collides_point(p, shooter_x + x, shooter_y + y2)) return 1; |
|
228 |
} |
|
229 |
return 0; |
|
230 |
} |
|
222 | 231 |
map_t* (map_ctor)(const char **background, const char **collide){ |
223 | 232 |
map_t *ret = malloc(sizeof(map_t)); |
224 | 233 |
if(ret == NULL) return NULL; |
... | ... | |
226 | 235 |
ret->bsp_background = NULL; |
227 | 236 |
ret->background = NULL; |
228 | 237 |
ret->collide = NULL; |
229 |
ret->x_prev = NULL;
|
|
230 |
ret->y_prev = NULL;
|
|
238 |
ret->prev = NULL;
|
|
239 |
ret->visited = NULL;
|
|
231 | 240 |
|
232 | 241 |
ret->bsp_background = basic_sprite_ctor(background, 0, 0); |
233 | 242 |
ret->background = sprite_ctor(ret->bsp_background); |
... | ... | |
246 | 255 |
} |
247 | 256 |
basic_sprite_dtor(bsp_collide); |
248 | 257 |
|
249 |
ret->x_prev = malloc(W*H*sizeof(int)); |
|
250 |
ret->y_prev = malloc(W*H*sizeof(int)); |
|
258 |
ret->collide_gunner = malloc(W*H*sizeof(uint8_t)); |
|
259 |
if(ret->collide_gunner == NULL){ map_dtor(ret); return NULL; } |
|
260 |
for(size_t i = 0; i < W*H; ++i){ |
|
261 |
int16_t x = i%W, y = i/W; |
|
262 |
ret->collide_gunner[i] = (map_collides_gunner_pos(ret, x, y, 36) ? 1 : 0); |
|
263 |
} |
|
251 | 264 |
|
252 |
if(ret->x_prev == NULL || ret->y_prev == NULL){ |
|
265 |
ret->prev = malloc(W*H*sizeof(int32_t)); |
|
266 |
ret->visited = malloc(W*H*sizeof(uint8_t)); |
|
267 |
|
|
268 |
if(ret->prev == NULL || ret->visited == NULL){ |
|
253 | 269 |
map_dtor(ret); |
254 | 270 |
return NULL; |
255 | 271 |
} |
... | ... | |
260 | 276 |
sprite_dtor(p->background); |
261 | 277 |
basic_sprite_dtor(p->bsp_background); |
262 | 278 |
free(p->collide); |
263 |
free(p->x_prev);
|
|
264 |
free(p->y_prev);
|
|
279 |
free(p->prev); |
|
280 |
free(p->visited);
|
|
265 | 281 |
free(p); |
266 | 282 |
} |
267 | 283 |
int16_t (map_get_x_screen)(const map_t *p){ return (-x_origin)*scale; } |
... | ... | |
275 | 291 |
uint32_t pos = x_ + y_*w; |
276 | 292 |
return p->collide[pos]; |
277 | 293 |
} |
278 |
int (map_make_dijkstra)(map_t *p, uint16_t x, uint16_t y){ |
|
294 |
int (map_collides_gunner)(const map_t *p, const gunner_t *shooter) { |
|
295 |
double radius = max(sprite_get_w(shooter->dude), sprite_get_h(shooter->dude))/2.0; |
|
296 |
return map_collides_gunner_pos(p, gunner_get_x(shooter), gunner_get_y(shooter), radius); |
|
297 |
} |
|
298 |
int (map_make_dijkstra)(map_t *p, int16_t x, int16_t y){ |
|
299 |
|
|
279 | 300 |
const uint16_t W = basic_sprite_get_w(p->bsp_background), |
280 | 301 |
H = basic_sprite_get_h(p->bsp_background); |
281 |
for(size_t i = 0; i < W*H; ++i) |
|
282 |
p->x_prev[i] = p->y_prev[i] = -1; |
|
302 |
|
|
303 |
static uint8_t first_time = true; |
|
304 |
if(first_time){ |
|
305 |
for(size_t i = 0; i < W*H; ++i) p->prev[i] = -1; |
|
306 |
first_time = false; |
|
307 |
} |
|
283 | 308 |
/// ACTUAL DIJKSTRA |
284 | 309 |
queue_t *q = queue_ctor(); |
310 |
|
|
311 |
memset(p->visited, false, W*H*sizeof(uint8_t)); |
|
312 |
|
|
285 | 313 |
int *ptr; |
286 |
p->x_prev[y*W+x] = x; p->x_prev[y*W+x] = y; |
|
287 |
ptr = malloc(sizeof(int)); *ptr = y*W+x; queue_push(q, ptr); |
|
314 |
int32_t c, pos; |
|
315 |
c = y*W+x; p->prev[c] = c; ptr = malloc(sizeof(int)); *ptr = c; queue_push(q, ptr); |
|
316 |
|
|
288 | 317 |
while(!queue_empty(q)){ |
289 |
int c = *(int*)list_node_val(queue_top(q)); free(queue_top(q)); queue_pop(q); |
|
290 |
if(p->collide[c]){ p->x_prev[c] = p->y_prev[c] = -1; continue; } |
|
291 |
uint16_t x = c%W, y = c/W; |
|
292 |
if(0 <= x-1){ int pos = y*W+(x-1); if(p->x_prev[pos] == -1){ p->x_prev[pos] = x; p->y_prev[pos] = y; ptr = malloc(sizeof(int)); *ptr = pos; queue_push(q, ptr); }} |
|
293 |
if(x+1 < W ){ int pos = y*W+(x+1); if(p->x_prev[pos] == -1){ p->x_prev[pos] = x; p->y_prev[pos] = y; ptr = malloc(sizeof(int)); *ptr = pos; queue_push(q, ptr); }} |
|
294 |
if(0 <= y-1){ int pos = (y-1)*W+x; if(p->x_prev[pos] == -1){ p->x_prev[pos] = x; p->y_prev[pos] = y; ptr = malloc(sizeof(int)); *ptr = pos; queue_push(q, ptr); }} |
|
295 |
if(y+1 < H ){ int pos = (y+1)*W+x; if(p->x_prev[pos] == -1){ p->x_prev[pos] = x; p->y_prev[pos] = y; ptr = malloc(sizeof(int)); *ptr = pos; queue_push(q, ptr); }} |
|
318 |
c = *(int*)queue_top(q); free(queue_top(q)); queue_pop(q); |
|
319 |
x = c%W, y = c/W; |
|
320 |
if(p->visited[c]) continue; |
|
321 |
p->visited[c] = true; |
|
322 |
if(p->collide_gunner[c]) continue; |
|
323 |
if(0 <= x-1){ pos = y*W+(x-1); if(!p->visited[pos] && p->prev[pos] != c){ p->prev[pos] = c; ptr = malloc(sizeof(int)); *ptr = pos; queue_push(q, ptr); }} |
|
324 |
if(x+1 < W ){ pos = y*W+(x+1); if(!p->visited[pos] && p->prev[pos] != c){ p->prev[pos] = c; ptr = malloc(sizeof(int)); *ptr = pos; queue_push(q, ptr); }} |
|
325 |
if(0 <= y-1){ pos = (y-1)*W+x; if(!p->visited[pos] && p->prev[pos] != c){ p->prev[pos] = c; ptr = malloc(sizeof(int)); *ptr = pos; queue_push(q, ptr); }} |
|
326 |
if(y+1 < H ){ pos = (y+1)*W+x; if(!p->visited[pos] && p->prev[pos] != c){ p->prev[pos] = c; ptr = malloc(sizeof(int)); *ptr = pos; queue_push(q, ptr); }} |
|
296 | 327 |
} |
297 |
return SUCCESS; |
|
298 |
} |
|
299 | 328 |
|
329 |
queue_dtor(q); |
|
300 | 330 |
|
301 |
int (map_collides_gunner)(const map_t *p, const gunner_t *shooter) { |
|
302 |
double radius = max(sprite_get_w(shooter->dude), sprite_get_h(shooter->dude))/2.0; |
|
303 |
double shooter_x = gunner_get_x(shooter); |
|
304 |
double shooter_y = gunner_get_y(shooter); |
|
305 |
for (double x = -radius; x < radius; x += 1) { |
|
306 |
double y1 = sqrt(radius*radius - x*x); |
|
307 |
double y2 = -y1; |
|
308 |
if (map_collides_point(p, shooter_x + x, shooter_y + y1) || map_collides_point(p, shooter_x + x, shooter_y + y2)) return 1; |
|
309 |
} |
|
310 |
return 0; |
|
331 |
return SUCCESS; |
|
311 | 332 |
} |
333 |
int (map_where_to_follow)(const map_t *p, float x, float y, float *theta){ |
|
334 |
const uint16_t W = basic_sprite_get_w(p->bsp_background); |
|
335 |
int x_ = x, y_ = y; |
|
336 |
int pos = y_*W+x_; |
|
337 |
//printf("Is in %d,%d\n", x_, y_); |
|
338 |
int newx = p->prev[pos]%W, newy = p->prev[pos]/W; |
|
339 |
//printf("from %d,%d to %d,%d\n", x_, y_, newx, newy); |
|
340 |
*theta = atan2(-(newy-y_), newx-x_); |
|
341 |
return SUCCESS; |
|
342 |
} |
|
312 | 343 |
|
313 | 344 |
int (map_collides_bullet)(const map_t *p, const bullet_t *bull){ |
314 | 345 |
double radius = max(sprite_get_w(bull->b), sprite_get_h(bull->b))/2.0; |
proj/src/proj.c | ||
---|---|---|
83 | 83 |
{ |
84 | 84 |
graph_clear_screen(); |
85 | 85 |
text_t *txt = text_ctor(consolas, "Loading..."); |
86 |
text_set_pos(txt, graph_get_XRes()/2, graph_get_YRes()/2); |
|
87 |
text_set_valign(txt, text_valign_center); |
|
88 |
text_set_halign(txt, text_halign_center); |
|
89 |
text_set_color(txt, TEXT_COLOR); |
|
86 | 90 |
text_draw(txt); |
87 | 91 |
text_dtor(txt); |
88 | 92 |
graph_draw(); |
... | ... | |
362 | 366 |
/* Get a request message. */ |
363 | 367 |
if((r = get_interrupts_vector(&int_vector))) return r; |
364 | 368 |
for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) { |
369 |
if(!good) break; |
|
365 | 370 |
if (int_vector & n) { |
366 | 371 |
interrupt_handler(i); |
367 | 372 |
switch (i) { |
... | ... | |
394 | 399 |
case KBC_IRQ: |
395 | 400 |
if ((scancode[0]) == ESC_BREAK_CODE) { |
396 | 401 |
good = false; |
397 |
// reset game |
|
398 |
while(list_size(bullet_list) > 0){ |
|
399 |
bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list)); |
|
400 |
bullet_dtor(p); |
|
401 |
} |
|
402 |
list_node_t *it = list_begin(shooter_list); |
|
403 |
while (it != list_end(shooter_list)) { |
|
404 |
gunner_t *p = *(gunner_t**)list_node_val(it); |
|
405 |
get_random_spawn(map1, p, shooter_list); |
|
406 |
gunner_set_curr_health(p, gunner_get_health(p)); |
|
407 |
it = list_node_next(it); |
|
408 |
} |
|
409 |
timer_reset(in_game_timer); |
|
410 | 402 |
} |
411 | 403 |
break; |
412 | 404 |
case MOUSE_IRQ: |
... | ... | |
445 | 437 |
|
446 | 438 |
#define ZOMBIES_NUM 5 |
447 | 439 |
#define ZOMBIE_HEALTH_FACTOR 1.1 |
448 |
|
|
449 | 440 |
static int (zombies)(void){ |
450 | 441 |
|
451 | 442 |
int r; |
... | ... | |
478 | 469 |
|
479 | 470 |
int health = 50; |
480 | 471 |
|
472 |
/** #DEV */ /* { |
|
473 |
gunner_t *zombie = gunner_ctor(bsp_zombie, bsp_nothing, gunner_melee | gunner_follow, 3); |
|
474 |
gunner_set_health(zombie, health); |
|
475 |
gunner_set_curr_health(zombie, health); |
|
476 |
health *= ZOMBIE_HEALTH_FACTOR; |
|
477 |
gunner_set_pos(zombie, 1100, 75); |
|
478 |
list_push_back(shooter_list, zombie); |
|
479 |
}*/ //\#DEV |
|
480 |
|
|
481 |
map_make_dijkstra(map1, gunner_get_x(shooter1), gunner_get_y(shooter1)); |
|
482 |
|
|
481 | 483 |
while (good && !dead) { |
482 | 484 |
/* Get a request message. */ |
483 | 485 |
if((r = get_interrupts_vector(&int_vector))) return r; |
484 | 486 |
for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) { |
487 |
if(!good || dead) break; |
|
485 | 488 |
if (int_vector & n) { |
486 | 489 |
interrupt_handler(i); |
487 | 490 |
switch (i) { |
488 | 491 |
case TIMER0_IRQ: |
489 | 492 |
if (no_interrupts % 60 == 0) timer_update(in_game_timer); |
493 |
if (no_interrupts % 6 == 0){ |
|
494 |
map_make_dijkstra(map1, gunner_get_x(shooter1), gunner_get_y(shooter1)); |
|
495 |
} |
|
490 | 496 |
|
491 | 497 |
update_movement(map1, shooter1, keys, shooter_list); |
492 | 498 |
|
... | ... | |
504 | 510 |
ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0, |
505 | 511 |
gunner_get_y(shooter1)-ent_get_YLength()/2.0); |
506 | 512 |
|
507 |
while(list_size(shooter_list) < ZOMBIES_NUM){ |
|
513 |
while(list_size(shooter_list) < ZOMBIES_NUM+1){
|
|
508 | 514 |
gunner_t *zombie = gunner_ctor(bsp_zombie, bsp_nothing, gunner_melee | gunner_follow, 3); |
509 | 515 |
gunner_set_health(zombie, health); |
510 | 516 |
gunner_set_curr_health(zombie, health); |
proj/src/proj_func.c | ||
---|---|---|
83 | 83 |
} |
84 | 84 |
|
85 | 85 |
// Update zombie positions |
86 |
map_make_dijkstra(map, gunner_get_x(p), gunner_get_y(p)); |
|
87 | 86 |
list_node_t *it = list_begin(shooter_list); |
88 | 87 |
while(it != list_end(shooter_list)){ |
89 | 88 |
gunner_t *g = *(gunner_t**)list_node_val(it); |
90 | 89 |
if(gunner_get_type(g) & gunner_follow){ |
91 |
//float theta = 0.0; |
|
92 |
//map_where_to_follow(map, &theta); |
|
93 |
//float c = fm_cos(theta), s = fm_sin(theta); |
|
94 |
|
|
90 |
float theta = 0.0; |
|
91 |
map_where_to_follow(map, gunner_get_x(g), gunner_get_y(g), &theta); |
|
92 |
float c = fm_cos(theta), s = fm_sin(theta); |
|
93 |
float dx = ZOMBIE_SPEED*c, dy = -ZOMBIE_SPEED*s; |
|
94 |
double x = gunner_get_x(g); |
|
95 |
double y = gunner_get_y(g); |
|
96 |
gunner_set_pos(g, x+dx, y+dy); |
|
97 |
if (map_collides_gunner(map, g)){ |
|
98 |
//printf("Zombie colliding with map\n"); |
|
99 |
gunner_set_pos(g, x, y); |
|
100 |
} else { |
|
101 |
list_node_t *it = list_begin(shooter_list); |
|
102 |
while (it != list_end(shooter_list)) { |
|
103 |
gunner_t *p2 = *(gunner_t**)list_node_val(it); |
|
104 |
if (g != p2 && gunner_collides_gunner(g, p2)) { |
|
105 |
//printf("Zombie colliding with zombie\n"); |
|
106 |
gunner_set_pos(g, x, y); |
|
107 |
break; |
|
108 |
} |
|
109 |
it = list_node_next(it); |
|
110 |
} |
|
111 |
} |
|
112 |
gunner_set_angle(g, theta-M_PI_2); /*printf("angle: %d.%d\n", (int)theta, abs((int)(theta*1000)%1000));*/ |
|
95 | 113 |
} |
96 | 114 |
it = list_node_next(it); |
97 | 115 |
} |
Also available in: Unified diff