void collision_detect() // called from game_loop() in Run.cpp - check for basic collision detection { if ( ( rPlayer.x == rExit.x ) && ( rPlayer.y == rExit.y ) ) // if the player coordinates meet the exit coordinates { play_fx("res/audio/finish.wav"); // play finish level sound effect running = false; // stop the game loop SDL_Delay(3000); // 3 seconds delay for the audio effect release_level(); // free the level resources menu_loop(); // reinitialize the menu } for ( int i = 0; i < 32; i++ ) for ( int j = 0; j < 24; j++ ) if ( ( rPlayer.x == rTiles[i][j].x ) && ( rPlayer.y == rTiles[i][j].y ) ) // check the tile to which the player's coordinates equal { if ( tiles[i][j] == 9 ) // if the current tile is a checkpoint { // player will respawn at the checkpoint's coordinates death_x = rTiles[i][j].x; death_y = rTiles[i][j].y; } if ( tiles[i][j] == 14 ) // if the current tile is a jump pad { play_fx("res/audio/jump_pad.wav"); for ( int i = 0; i < 8; i++ ) { rPlayer.y -= 32; // jump high for ( int i = 0; i < 32; i++ ) // unoptimized check for traps for ( int j = 0; j < 24; j++ ) if ( ( rPlayer.x == rTiles[i][j].x ) && ( rPlayer.y == rTiles[i][j].y ) ) if ( ( ( ( tiles[i][j] == 3 ) || ( tiles[i][j] == 4 ) ) || ( ( tiles[i][j] == 5 ) || ( tiles[i][j] == 6 ) ) ) || ( ( ( tiles[i][j] == 7 ) || ( tiles[i][j] == 8 ) ) || ( ( tiles[i][j] == 10 ) || ( tiles[i][j] == 11 ) ) ) || ( tiles[i][j] == 13 ) ) goto trap; // bad jump } } // if the tile is a trap(death situation): if ( ( ( ( tiles[i][j] == 3 ) || ( tiles[i][j] == 4 ) ) || ( ( tiles[i][j] == 5 ) || ( tiles[i][j] == 6 ) ) ) || ( ( ( tiles[i][j] == 7 ) || ( tiles[i][j] == 8 ) ) || ( ( tiles[i][j] == 10 ) || ( tiles[i][j] == 11 ) ) ) || ( tiles[i][j] == 13 ) ) trap: // bad goto if ( !god_mode ) // if we are not in cheating/testing mode { ghost_fx(); // located below, shows a death effect texture // move the player either at the beginning of the level, either at some checkpoint if reached already rPlayer.x = death_x; rPlayer.y = death_y; // reset moving and jumping jump = dir_left = dir_right = false; jump = false; jcounter = 0; // shord delay for esthetic reasons SDL_Delay(300); } } }
static int update_stats_table(void) { struct game_over_stat_bonus *p; ++stat_tic_counter; for (p = game_over_stat_bonus; p->count; p++) { if (*p->display_count < *p->count) break; } if (p->count) { if (stat_tic_counter >= p->tics_per_update) { stat_tic_counter = 0; game_over_stats.bonus += p->bonus; (*p->display_count)++; play_fx(FX_SHOT_1); } return 1; } else { /* gc.score += game_over_stats.bonus; set_inner_state(IS_RANK); */ return 0; } }
void AudioManager::play_audio(AudioClip *inClip) { if (_init && inClip) { if (inClip->type == TEXENG_AUDIO_FX) play_fx(inClip); else play_music(inClip); } }
void ghost_fx() // called if the player collides with deathly tile { // set the ghost texture's coordinates rGhost.x = rPlayer.x; rGhost.y = rPlayer.y; play_fx("res/audio/death.wav"); // play a daeth sound effect SDL_RenderCopy(render, texture_ghost, NULL, &rGhost); // display the death effect texture at it's rectangle location on the renderer SDL_RenderPresent(render); // show the updated screen }
static void foe_common_gen_explosion(struct foe_common *f, float scale) { int i; particle *p; int ndebris, nballs; ndebris = scale*(40 + irand(30)); /* debris */ for (i = 0; i < ndebris; i++) { p = add_particle(); if (!p) break; p->ttl = 20 + irand(15); p->t = 0; p->width = scale*.4f*(.6f + .15f*frand()); p->height = scale*.3f*(2.8f + .4f*frand()); p->pos = f->pos; p->palette = PAL_YELLOW; p->friction = .9; vec2_set(&p->dir, frand() - .5f, frand() - .5f); vec2_normalize(&p->dir); p->speed = scale*(PARTICLE_SPEED + .05f*frand()); } #define RADIUS .4f /* fireballs */ nballs = scale*(8 + irand(8)); for (i = 0; i < nballs; i++) { vector2 pos; float r, l; l = 1.2*scale; pos.x = f->pos.x + l*frand() - .5f*l; pos.y = f->pos.y + l*frand() - .5f*l; r = scale*(.2f + .15f*frand()); add_explosion(&pos, r, EFF_EXPLOSION, 13 + irand(4)); } /* shockwave */ add_explosion(&f->pos, scale*.3f, EFF_RING, 18); /* p = add_particle(); if (p) { p->t = 0; p->ttl = 20; p->width = p->height = scale*.3f; p->pos = f->pos; p->palette = PAL_RED; p->type = PT_SHOCKWAVE; } */ perturb_water(&f->pos, scale*1200.f); play_fx(FX_EXPLOSION_1); }
static void update_inner_state(void) { static int prev_level_tics; inner_state.tics++; switch (inner_state.state) { case IS_WAVE_TITLE: if (inner_state.tics >= WAVE_TITLE_TICS) { set_inner_state(IS_IN_GAME); /* set_inner_state(IS_PRE_WAVE_CLEARED); */ } else { if (inner_state.tics == WAVE_TITLE_TICS/2) { if (!ship.is_alive) spawn_new_ship(); else reset_ship(); } } break; case IS_IN_GAME: level_stat_counters.tics++; game_stat_counters.tics++; if (gc.tics_remaining <= 0) { /* boom. */ hit_ship(&ship.pos, 1.f); trigger_game_over(); } else { gc.tics_remaining--; if (!ship.is_alive) { prev_level_tics = inner_state.tics; set_inner_state(IS_RESPAWNING_SHIP); } else if (!gc.foes_left) { level_stat_counters.waves++; game_stat_counters.waves++; if (gc.tics_remaining > TIME_BONUS_MIN_TICS) gc.score += gc.tics_remaining*TIME_BONUS_PER_TIC; set_inner_state(IS_PRE_WAVE_CLEARED); } else { spawn_new_foes(); } } break; case IS_PRE_WAVE_CLEARED: if (inner_state.tics >= PRE_WAVE_CLEARED_TICS) { gen_ship_implosion(); reset_powerups(); reset_missiles(); reset_bombs(); reset_lasers(); vec2_set(&ship.pos, 0.f, 0.f); /* HACK */ play_fx(FX_WAVE_TRANSITION); set_inner_state(IS_WAVE_CLEARED); } break; case IS_RESPAWNING_SHIP: if (inner_state.tics >= TICS_UNTIL_RESPAWN) { if (gc.ships_left) { spawn_new_ship(); set_inner_state(IS_IN_GAME); inner_state.tics = prev_level_tics; } else { trigger_game_over(); } } break; case IS_GAME_OVER: break; case IS_RANK: if (inner_state.tics >= RANK_TOTAL_TICS) { stop_music(); if (is_highscore(gc.score)) { set_inner_state(IS_HIGHSCORE_INPUT); SDL_ShowCursor(SDL_ENABLE); start_highscore_input(); } else { /* loser. */ SDL_ShowCursor(SDL_ENABLE); start_main_menu(); } } break; case IS_WAVE_CLEARED: if (gc.cur_wave == levels[gc.cur_level]->num_waves - 1 && inner_state.tics >= WAVE_CLEARED_TICS/2) { initialize_stats_table(&level_stat_counters); set_inner_state(IS_LEVEL_CLEARED); } else if (inner_state.tics >= WAVE_CLEARED_TICS) { gc.cur_wave++; assert(gc.cur_wave < levels[gc.cur_level]->num_waves); reset_wave(); set_inner_state(IS_WAVE_TITLE); } break; case IS_HIGHSCORE_INPUT: break; case IS_LEVEL_CLEARED: break; case IS_LEVEL_TRANSITION: if (inner_state.tics >= LEVEL_TRANSITION_TOTAL_TICS) { gc.cur_level = (gc.cur_level + 1)%NUM_LEVELS; set_inner_state(IS_WAVE_TITLE); reset_level(); } break; default: assert(0); } }