/* advances the player to the next attack wave */ void advance_player(int cycle) { char buf[80]; int bonus = 0; int old_score = score; int i; for (i=0; i<SEGMENTS; i++) { if (ganja[i]) bonus++; else ganja[i] = TRUE; } if (bonus == SEGMENTS) { message("Bonus: 100"); score += 100; } if (cycle) { message("Bonus: 1000"); score += 1000; } sprintf(buf, "Score: %d", bonus); message(buf); score += bonus; if ((get_hiscore() > 0) && (score > get_hiscore()) && (old_score <= get_hiscore())) { message("New Record Score!"); sfx_ping(3); } else if ((bonus == SEGMENTS) || (cycle)) { sfx_ping(1); } }
/* the main game function */ static int play_game() { ALLEGRO_TIMER *inc_counter; int gameover = 0; int cyclenum = 0; /* init */ score = 0; init_view(); init_player(); init_badguys(); init_bullets(); init_explode(); init_message(); #define TIMER_SPEED ALLEGRO_BPS_TO_SECS(30*(cyclenum+2)) inc_counter = al_create_timer(TIMER_SPEED); al_start_timer(inc_counter); while (!gameover) { /* move everyone */ while ((al_get_timer_count(inc_counter) > 0) && (!gameover)) { update_view(); update_bullets(); update_explode(); update_message(); if (update_badguys()) { if (advance_view()) { cyclenum++; al_set_timer_count(inc_counter, 0); lay_attack_wave(TRUE); advance_player(TRUE); } else { lay_attack_wave(FALSE); advance_player(FALSE); } } gameover = update_player(); al_set_timer_count(inc_counter, al_get_timer_count(inc_counter)-1); } /* take a screenshot? */ if (key[ALLEGRO_KEY_PRINTSCREEN]) { static int ss_count = 0; char fname[80]; sprintf(fname, "speed%03d.tga", ++ss_count); al_save_bitmap(fname, al_get_backbuffer(screen)); while (key[ALLEGRO_KEY_PRINTSCREEN]) poll_input_wait(); al_set_timer_count(inc_counter, 0); } /* toggle fullscreen window */ if (key[ALLEGRO_KEY_F]) { int flags = al_get_display_flags(screen); al_set_display_flag(screen, ALLEGRO_FULLSCREEN_WINDOW, !(flags & ALLEGRO_FULLSCREEN_WINDOW)); while (key[ALLEGRO_KEY_F]) poll_input_wait(); } /* draw everyone */ draw_view(); } /* cleanup */ al_destroy_timer(inc_counter); shutdown_view(); shutdown_player(); shutdown_badguys(); shutdown_bullets(); shutdown_explode(); shutdown_message(); if (gameover < 0) { sfx_ping(1); return FALSE; } return TRUE; }
/* updates the badguy position */ int update_badguys() { BADGUY **p = &evildudes; BADGUY *b = evildudes; BADGUY *tmp1, *tmp2; void *bullet; float x, y, d; int dead; /* testcode: enter clears the level */ if ((cheat) && (key[ALLEGRO_KEY_ENTER])) { shutdown_badguys(); b = NULL; while (key[ALLEGRO_KEY_ENTER]) poll_input_wait(); } while (b) { dead = FALSE; if (b->aggro) { /* attack the player */ d = player_pos() - b->x; if (d < -0.5) d += 1; else if (d > 0.5) d -= 1; if (b->y < 0.5) d = -d; b->v *= 0.99; b->v += SGN(d) * 0.00025; } else if (b->evade) { /* evade the player */ if (b->y < 0.75) d = player_pos() + 0.5; else d = b->x; if (b->move) d += SGN(b->move) / 16.0; d = find_target(d) - b->x; if (d < -0.5) d += 1; else if (d > 0.5) d -= 1; b->v *= 0.96; b->v += SGN(d) * 0.0004; } /* horizontal move */ b->x += b->move + sin(b->t * b->sin_speed) * b->sin_depth + b->v; if (b->x < 0) b->x += 1; else if (b->x > 1) b->x -= 1; /* vertical move */ b->y += b->speed; if ((b->y > 0.5) && (b->y - b->speed <= 0.5) && (b->split)) { /* split ourselves */ tmp1 = malloc(sizeof(BADGUY)); tmp2 = malloc(sizeof(BADGUY)); *tmp1 = *tmp2 = *b; tmp1->move -= 0.001; tmp2->move += 0.001; b->speed += 0.001; tmp1->t = rand() & 255; tmp2->t = rand() & 255; tmp1->next = tmp2; tmp2->next = evildudes; evildudes = tmp1; } b->t++; if (b->y > 0) { if (kill_player(b->x, b->y)) { /* did we hit someone? */ dead = TRUE; } else { /* or did someone else hit us? */ bullet = get_first_bullet(&x, &y); while (bullet) { x = x - b->x; if (x < -0.5) x += 1; else if (x > 0.5) x -= 1; x = ABS(x); y = ABS(y - b->y); if (x < y) d = y/2 + x; else d = x/2 + y; if (d < 0.025) { kill_bullet(bullet); explode(b->x, b->y, 0); sfx_explode_alien(); dead = TRUE; break; } bullet = get_next_bullet(bullet, &x, &y); } } } /* advance to the next dude */ if (dead) { *p = b->next; tmp1 = b; b = b->next; free(tmp1); } else { p = &b->next; b = b->next; } } if ((!evildudes) && (!player_dying())) { if (!finished_counter) { message("Wave Complete"); sfx_ping(0); } finished_counter++; if (finished_counter > 64) return TRUE; } return FALSE; }