Esempio n. 1
0
int
main(void)
{
  asteroids.lives         = START_LIVES;
  asteroids.display       = NULL;
  asteroids.timer         = NULL;
  asteroids.event_queue   = NULL;
  SHIP *ship;

  bool redraw = true;
  bool quit   = false;
  bool key[7] = { false };

  seed_rand();
  atexit(shutdown);

  if(!init())
    exit(EXIT_FAILURE);

  if((asteroids.high_score = get_config_value("high_score")) == NULL)
    asteroids.high_score = "0";

  asteroids.level = level_create(0, 0);

  if(!(ship = ship_create()))
    exit(EXIT_FAILURE);

  al_flip_display();
  al_start_timer(asteroids.timer);

  while(!quit) {
    ALLEGRO_EVENT ev;
    al_wait_for_event(asteroids.event_queue, &ev);

    if(ev.type == ALLEGRO_EVENT_TIMER) {
      /* start game */
      if(asteroids.level->number == 0 && key[KEY_S]) {
        start();
        continue;
      }

      /* are we out of asteroids to destroy? */
      if(list_length(asteroids.level->asteroids) == 0)
        asteroids.level = level_next(asteroids.level);

      /* update objects */
      ship = ship_update(ship, key, asteroids.timer);
      explosions_update();
      asteroids.level = level_update(asteroids.level, ship, key, asteroids.timer);

      /* ship->asteroid collisions. */
      check_ship_asteroid_collisions(ship, asteroids.level->asteroids);

      /* ship[missile] -> asteroid collisions. */
      check_ship_missile_asteroid_collisions(asteroids.level, ship);

      /* ship[missile] -> saucer collisions. */
      check_ship_missile_saucer_collisions(asteroids.level, ship);

      /* saucer[missile] -> ship collisions. */
      check_saucer_missile_ship_collisions(asteroids.level, ship);

      /* saucer[missile] -> asteroid collisions. */
      check_saucer_missile_asteroids_collisions(asteroids.level);

      /* saucer->asteroid collisions. */
      check_saucer_asteroid_collisions(asteroids.level);

      redraw = true;
    } else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
      keydown(ev, key);
      quit = key[KEY_ESCAPE];
    } else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
      keyup(ev, key);
      ship->fire_debounce  = key[KEY_SPACE];
      ship->hyper_debounce = key[KEY_LCONTROL];
    }

    if(redraw && al_is_event_queue_empty(asteroids.event_queue)) {
      redraw = false;
      al_clear_to_color(al_map_rgb(BLACK));

      level_draw(asteroids.level);
      draw_lives();
      draw_high_score();
      animation_draw_list(asteroids.explosions);

      if(asteroids.level->number == 0) {
        draw_home();
        al_flip_display();
        continue;
      }

      if(asteroids.lives > 0) {
        ship_draw(ship, key[KEY_UP]);
        missile_draw_list(ship->missiles);
      } else {
        if(ship->explosion)
          ship_draw(ship, false);
        draw_gameover();
      }

      al_flip_display();
    }
  };

  /* FIXME: cleanup */
  if(asteroids.timer != NULL)
    al_destroy_timer(asteroids.timer);
  if(asteroids.event_queue != NULL)
    al_destroy_event_queue(asteroids.event_queue);
  if(asteroids.display != NULL)
    al_destroy_display(asteroids.display);

  LIST *head = list_first(asteroids.level->asteroids);
  while(head != NULL) {
    ASTEROID *rock = (ASTEROID *) head->data;
    asteroid_free(rock);
    head = head->next;
  }
  ship_free(ship);

  al_destroy_bitmap(asteroids.lives_sprite);
  ship_shutdown();
  missile_shutdown();
  asteroid_shutdown();
  explosion_shutdown();

  al_uninstall_keyboard();

  exit(EXIT_SUCCESS);
}
Esempio n. 2
0
static void play_game(struct thread_data *data)
{
    int status;
    input_t input;
    int did_user_quit = 0;    /* 0 if game-over, otherwise if user quits */

    while (1) {
        /* take user input */
        input = fetch_user_input();
        if (input == INPUT_INVALID)
            continue;

        pthread_mutex_lock(&data->lock);

        /* check if the game is still going on */
        if (data->game_over) {
            pthread_mutex_unlock(&data->lock);
            break;
        }

        /* in case there's no "current block", don't do anything */
        if (input != INPUT_PAUSE_QUIT && 
                (data->block_dropped_ignore_input || !data->current)) {
            pthread_mutex_unlock(&data->lock);
            continue;
        }

        /* take appropriate action based on user input */
        switch (input) {
            case INPUT_MOVE_LEFT:
                status = move_block(data->current, ACTION_MOVE_LEFT);
                if (status == SUCCESS)
                    draw_game_board(data->current);
                break;
            case INPUT_MOVE_RIGHT:
                status = move_block(data->current, ACTION_MOVE_RIGHT);
                if (status == SUCCESS)
                    draw_game_board(data->current);
                break;
            case INPUT_MOVE_DOWN:
                status = move_block(data->current, ACTION_MOVE_DOWN);
                if (status == SUCCESS)
                    draw_game_board(data->current);
                break;
            case INPUT_MOVE_UP_DROP:
                status = move_block(data->current, ACTION_MOVE_UP_DROP);
                if (status == SUCCESS) {
                    data->block_dropped_ignore_input = 1;
                    draw_game_board(data->current);
                }
                break;
            case INPUT_ROTATE_LEFT:
                status = move_block(data->current, ACTION_ROTATE_LEFT);
                if (status == SUCCESS)
                    draw_game_board(data->current);
                break;
            case INPUT_ROTATE_RIGHT:
                status = move_block(data->current, ACTION_ROTATE_RIGHT);
                if (status == SUCCESS)
                    draw_game_board(data->current);
                break;
            case INPUT_PAUSE_QUIT:
                status = display_quit_dialog();
                draw_game_board(data->current);
                if (status == FAILURE) {    /* if the user chooses to quit */
                    data->game_over = 1;
                    did_user_quit = 1;
                }
                break;
            case INPUT_TIMEOUT:     /* nothing to do */
                break;
            default:
                break;
        }

        pthread_mutex_unlock(&data->lock);
    }

    draw_gameover(did_user_quit);
}