int main() { //struct timeval lastTime; WINDOW *win = initscr(); keypad(win, true); curs_set(0); raw(); noecho(); timeout(gSpeed); start_color(); // gGame.width = getmaxx(win); gGame.height = getmaxy(win); level_load(0); //gettimeofday(&gGame.lastTime, NULL); while ((gGame.input = getch()) != 'q') { level_draw(); /*gettimeofday(&lastTime, NULL); gGame.elapsedTime = 1000 * (gGame.lastTime.tv_sec - lastTime.tv_sec) + (gGame.lastTime.tv_usec - lastTime.tv_usec); gGame.lastTime = lastTime;*/ } level_unload(true); keypad(win, false); curs_set(1); echo(); noraw(); delwin(win); endwin(); return 0; }
void PortalCollision(unsigned int x, unsigned int y) { for (portal = 0; portal < gLevel.portalsCount; ++portal) { if (gLevel.portals[portal].x == x && gLevel.portals[portal].y == y) { unsigned int destination = gLevel.portals[portal].destination; level_load(gLevel.portals[portal].level); gPlayer.x = gLevel.portals[destination].x; gPlayer.y = gLevel.portals[destination].y; // TODO: Without setting (input = 0), input gets processed twice. // I kind of like that, but it may need to be changed later. level_draw(); return; } } }
void blink(SDL_Renderer *renderer, int* lines, int line_nb, fontmap *p_fontmap){ bool done=false; timer* p_timer = timer_init(); timer_start(p_timer); //number of times the lines must blink int blink_time = 5; //number of times the lines has blinked int blink_cur = 0; //time in milliseconds of the blink speed int blink_duration = 200; //show full line or empty line char show=1; int i; while (!done){ if(timer_get_ticks(p_timer) >= blink_duration){ if(blink_cur == blink_time)done = true; else{ show = (blink_cur%2 == 0)?1:0; for(i=0;i<line_nb;i++){ memset(level+lines[i], show, sizeof(char) * LEVEL_WIDTH); } blink_cur++; p_timer->start_ticks = SDL_GetTicks(); } } //draw the level SDL_RenderClear(renderer); SDL_SetRenderDrawColor(renderer, 0, 42, 0, 255); level_draw(renderer, NULL, p_fontmap); SDL_RenderPresent(renderer); } free(p_timer); }
game_status state_in_game(SDL_Renderer* renderer, game* p_game) { bool done=false; //the return code is always GAME_OVER, the player try to beat his hi-score //until his demise game_status ret_code = GAME_OVER; long timelastcall=SDL_GetTicks(); //initialize the states of completed lines to 0 memset(p_game->state, 0, STATE_NUM * sizeof(int)); p_game->score = 0; int level_cur = 0; int level_max = 10; level_init(); //declare two shapes, one controled by the player, the other to indicates //the type of the next shape shape o_falling_shape, o_preview_shape; //set the falling shape type randomly shape_set(&o_falling_shape, rand() % SHAPE_NB); shape_default_coord(&o_falling_shape); shape_type next_shape_type = rand() % SHAPE_NB; shape_set(&o_preview_shape, next_shape_type); //put the preview shape on the side of the board o_preview_shape.x = LEVEL_WIDTH + 1; o_preview_shape.y = o_preview_shape.len - SHAPE_SIZE / 2 + 2; while (!done){ //drawing SDL_SetRenderDrawColor(renderer, 0, 42, 0, 255); SDL_RenderClear(renderer); //draw the falling shape shape_draw(&o_falling_shape, p_game->p_fontmap, renderer); //draw the next shape as a preview shape_draw(&o_preview_shape, p_game->p_fontmap, renderer); //draw the level (empty blocks and alderly placed shapes) level_draw(renderer, &o_falling_shape, p_game->p_fontmap); int game_speed = level_max * 100 - level_cur * 100; int total=0; for(int i=0;i<3;i++)total += p_game->state[i]; //draw a line between the board and the score / next shape area SDL_SetRenderDrawColor( renderer, 0x00, 0x00, 0xFF, 0xFF ); SDL_RenderDrawLine(renderer, TILE_SIZE * 12, 0, TILE_SIZE * 12, SCREEN_HEIGHT); //draw the score fontmap_printf(p_game->p_fontmap, SCREEN_WIDTH - 7*5, SCREEN_HEIGHT - 120, renderer, "%d", p_game->score); SDL_Event event; while (SDL_PollEvent(&event)){ if((event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_RETURN)|| (event.type == SDL_JOYBUTTONDOWN && event.jbutton.button == 5)){ ret_code = state_paused(renderer); if(ret_code!=STAY){ done = 1; } } if(event.type == SDL_QUIT){ exit(EXIT_SUCCESS); } switch ( event.type ) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_RIGHT: if(shape_move(&o_falling_shape, 1, 0))o_falling_shape.x++; break; case SDLK_LEFT: if(shape_move(&o_falling_shape, -1, 0))o_falling_shape.x--; break; case SDLK_DOWN: if(shape_move(&o_falling_shape, 0, 1)) timelastcall=SDL_GetTicks()+game_speed; break; case SDLK_SPACE: while(shape_move(&o_falling_shape, 0, 1)) o_falling_shape.y++; timelastcall=SDL_GetTicks()+game_speed; break; case SDLK_f: shape_rotate(&o_falling_shape, 0); break; case SDLK_d: shape_rotate(&o_falling_shape, 1); break; case SDLK_q: exit(EXIT_SUCCESS); break; default: break; } break; case SDL_JOYBUTTONDOWN: switch(event.jbutton.button) { case 0: while(shape_move(&o_falling_shape, 0, 1)) o_falling_shape.y++; timelastcall=SDL_GetTicks()+game_speed; break; case 2: shape_rotate(&o_falling_shape, 1); break; case 3: shape_rotate(&o_falling_shape, 0); break; case 6: done=true; ret_code = QUIT; break; case 19: done=true; ret_code = QUIT; break; default: break; } break; } } if(SDL_GetTicks() - timelastcall > game_speed) { //check if the falling shape can move if(shape_move(&o_falling_shape, 0, 1)){ //update coord o_falling_shape.y++; }else{ //the shape can not move int i; level_add_shape(&o_falling_shape); int lines_in_a_row=0; //tab of line index to remove int rem_tab[SHAPE_SIZE]; int line_nb = level_check_line(rem_tab); for(i=1;i<line_nb;i++){ if(rem_tab[i] == rem_tab[i-1]+1)lines_in_a_row++; else lines_in_a_row = 0; } if(line_nb){ //blink completed line(s) blink(renderer, rem_tab, line_nb, p_game->p_fontmap); for(i=0;i<line_nb;i++)level_remove_line(rem_tab[i]); //remove completed line(s) p_game->score += line_nb * (lines_in_a_row + 1); //update score p_game->state[lines_in_a_row]++; //update game states if(line_nb == 2 && lines_in_a_row == 0)p_game->state[0]++; level_cur = p_game->score / 1000; //eventually update level number if(level_cur >= level_max)level_cur = level_max; } if(level_check_game_over()){ done = 1; ret_code = GAME_OVER; } else{ //"create" a new falling block by chaning the falling shape type //to the next shape and reseting the coords shape_set(&o_falling_shape, next_shape_type); shape_default_coord(&o_falling_shape); //pick a next shape type randomly for the preview and the next falling //block next_shape_type = rand() % SHAPE_NB; shape_set(&o_preview_shape, next_shape_type); } } //update timer timelastcall=SDL_GetTicks(); } SDL_RenderPresent(renderer); } return ret_code; }
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); }