Project

General

Profile

Revision 309

finally done with zombies!

View differences:

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