diff --git a/games/BelowTheSurface/behaviour.h b/games/BelowTheSurface/behaviour.h index 945dbbf9..21424718 100644 --- a/games/BelowTheSurface/behaviour.h +++ b/games/BelowTheSurface/behaviour.h @@ -152,6 +152,7 @@ class BlobBehaviour : public Behaviour this->blob_machine->set_facing_left(facing_left); fall_to_ground(); this->blob_machine->update(); + this->blob_machine->apply_next_state(); }; }; @@ -180,6 +181,7 @@ class SnakeBehaviour : public Behaviour this->snake_machine->set_facing_left(facing_left); fall_to_ground(); this->snake_machine->update(); + this->snake_machine->apply_next_state(); }; void face_player() @@ -190,8 +192,8 @@ class SnakeBehaviour : public Behaviour if(change_direction) continue; - point_2d player_center = to_screen(center_point(level_players[i]->get_player_sprite())); - point_2d enemy_center = to_screen(center_point(enemy_sprite)); + point_2d player_center = to_screen(sprite_center_point(level_players[i]->get_player_sprite())); + point_2d enemy_center = to_screen(sprite_center_point(enemy_sprite)); double dist = player_center.x - enemy_center.x; @@ -238,6 +240,7 @@ class RatBehaviour : public Behaviour this->rat_machine->set_facing_left(facing_left); fall_to_ground(); this->rat_machine->update(); + this->rat_machine->apply_next_state(); }; void random_actions() @@ -252,7 +255,7 @@ class RatBehaviour : public Behaviour if(choice1 > 990) { - this->rat_machine->change_state(new RatIdle, "Idle"); + this->rat_machine->request_state_change(new RatIdle, "Idle"); } if(choice2 > 980) { @@ -288,6 +291,7 @@ class WaterRatBehaviour : public Behaviour this->boss_machine->set_facing_left(facing_left); fall_to_ground(); this->boss_machine->update(); + this->boss_machine->apply_next_state(); }; void backwards_behaviour() @@ -313,8 +317,8 @@ class WaterRatBehaviour : public Behaviour void face_player() { - point_2d player_center = to_screen(center_point(level_players[0]->get_player_sprite())); - point_2d enemy_center = to_screen(center_point(enemy_sprite)); + point_2d player_center = to_screen(sprite_center_point(level_players[0]->get_player_sprite())); + point_2d enemy_center = to_screen(sprite_center_point(enemy_sprite)); if(enemy_center.x < player_center.x) facing_left = true; @@ -331,7 +335,7 @@ class WaterRatBehaviour : public Behaviour { if(state == 0) { - this->boss_machine->change_state(new BossDying, "Dying"); + this->boss_machine->request_state_change(new BossDying, "Dying"); } } }; @@ -374,6 +378,7 @@ class FlyBehaviour : public Behaviour this->fly_machine->set_facing_left(facing_left); this->fly_machine->set_flying_up(flying_up); this->fly_machine->update(); + this->fly_machine->apply_next_state(); if(type == "Purp") face_random_direction(); @@ -425,6 +430,7 @@ class TentacleBehaviour : public Behaviour this->tentacle_machine->set_facing_left(facing_left); fall_to_ground(); this->tentacle_machine->update(); + this->tentacle_machine->apply_next_state(); }; }; \ No newline at end of file diff --git a/games/BelowTheSurface/blobmachine.h b/games/BelowTheSurface/blobmachine.h index 3a2eb520..5ae96ca0 100644 --- a/games/BelowTheSurface/blobmachine.h +++ b/games/BelowTheSurface/blobmachine.h @@ -34,13 +34,15 @@ class BlobMachine { private: BlobMachineState *state; + BlobMachineState *next_state; + string next_state_type; sprite enemy_sprite; bool facing_left; vector> level_players; public: - BlobMachine(BlobMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr) + BlobMachine(BlobMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr), next_state(nullptr) { this->enemy_sprite = enemy_sprite; this->level_players = level_players; @@ -53,6 +55,12 @@ class BlobMachine delete state; }; + void request_state_change(BlobMachineState *new_state, string type) + { + this->next_state = new_state; + this->next_state_type = type; + }; + void change_state(BlobMachineState *new_state, string type) { if (this->state != nullptr) @@ -60,6 +68,15 @@ class BlobMachine this->state = new_state; this->state->set_state(this, type); }; + + void apply_next_state() + { + if (this->next_state != nullptr) + { + change_state(this->next_state, this->next_state_type); + this->next_state = nullptr; + } + } void update() { diff --git a/games/BelowTheSurface/bossmachine.h b/games/BelowTheSurface/bossmachine.h index 6fe7662e..6fd9a00f 100644 --- a/games/BelowTheSurface/bossmachine.h +++ b/games/BelowTheSurface/bossmachine.h @@ -35,12 +35,14 @@ class BossMachine { private: BossMachineState *state; + BossMachineState *next_state; + string next_state_type; sprite enemy_sprite; bool facing_left; vector> level_players; public: - BossMachine(BossMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr) + BossMachine(BossMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr), next_state(nullptr) { this->enemy_sprite = enemy_sprite; this->level_players = level_players; @@ -52,6 +54,12 @@ class BossMachine { delete state; }; + + void request_state_change(BossMachineState *new_state, string type) + { + this->next_state = new_state; + this->next_state_type = type; + }; void change_state(BossMachineState *new_state, string type) { @@ -60,6 +68,15 @@ class BossMachine this->state = new_state; this->state->set_state(this, type); }; + + void apply_next_state() + { + if (this->next_state != nullptr) + { + change_state(this->next_state, this->next_state_type); + this->next_state = nullptr; + } + } void update() { @@ -244,7 +261,7 @@ void BossIdle::update() //double y_dist = boss_pos.y - player_pos.y; if(abs(x_dist) < 300) { - this->boss->change_state(new BossRise(0), "Rise"); + this->boss->request_state_change(new BossRise(0), "Rise"); break; } } @@ -283,12 +300,12 @@ void BossMove::update() if(choice < 80) { sprite_set_dx(boss_sprite, 0); - this->boss->change_state(new BossRise(1), "RiseAttack"); + this->boss->request_state_change(new BossRise(1), "RiseAttack"); break; } else { - this->boss->change_state(new BossMoveBackwards, "MoveBackwards"); + this->boss->request_state_change(new BossMoveBackwards, "MoveBackwards"); } } } @@ -337,15 +354,15 @@ void BossMoveBackwards::update() if(choice < 30) { - this->boss->change_state(new BossRise(0), "Rise"); + this->boss->request_state_change(new BossRise(0), "Rise"); } else if(choice > 33 && choice < 66) { - this->boss->change_state(new BossSpotPlayer, "Spot"); + this->boss->request_state_change(new BossSpotPlayer, "Spot"); } else { - this->boss->change_state(new BossMove, "Move"); + this->boss->request_state_change(new BossMove, "Move"); } } } @@ -365,9 +382,9 @@ void BossRise::update() if(sprite_animation_has_ended(boss_sprite)) { if(rise_type == 0) - this->boss->change_state(new BossBattleCry(3), "BattleCry"); + this->boss->request_state_change(new BossBattleCry(3), "BattleCry"); if(rise_type == 1) - this->boss->change_state(new BossAttack, "Attack"); + this->boss->request_state_change(new BossAttack, "Attack"); } } @@ -384,7 +401,7 @@ void BossSpotPlayer::update() set_proper_direction(boss_sprite, "RightSpotPlayer"); if(sprite_animation_has_ended(boss_sprite)) - this->boss->change_state(new BossDescend(0), "Descend"); + this->boss->request_state_change(new BossDescend(0), "Descend"); } void BossBattleCry::update() @@ -401,13 +418,13 @@ void BossBattleCry::update() if(sprite_animation_has_ended(boss_sprite)) { if(battle_cry_type == 0) - this->boss->change_state(new BossSpotPlayer, "SpotPlayer"); + this->boss->request_state_change(new BossSpotPlayer, "SpotPlayer"); if(battle_cry_type == 1) - this->boss->change_state(new BossAttack, "Attack"); + this->boss->request_state_change(new BossAttack, "Attack"); if(battle_cry_type == 2) - this->boss->change_state(new BossDescend(1), "Descend"); + this->boss->request_state_change(new BossDescend(1), "Descend"); if(battle_cry_type == 3) - this->boss->change_state(new BossDescend(0), "Descend"); + this->boss->request_state_change(new BossDescend(0), "Descend"); } } @@ -437,19 +454,19 @@ void BossAttack::update() double choice = dist(mt); if(choice < 30) { - this->boss->change_state(new BossDescend(1), "Descend"); + this->boss->request_state_change(new BossDescend(1), "Descend"); } else if(choice > 30 && choice < 50) { - this->boss->change_state(new BossDescend(0), "Descend"); + this->boss->request_state_change(new BossDescend(0), "Descend"); } else if(choice > 50 && choice < 90) { - this->boss->change_state(new BossAttack, "Attack"); + this->boss->request_state_change(new BossAttack, "Attack"); } else { - this->boss->change_state(new BossBattleCry(2), "BattleCry"); + this->boss->request_state_change(new BossBattleCry(2), "BattleCry"); } } } @@ -466,9 +483,9 @@ void BossDescend::update() if(sprite_animation_has_ended(boss_sprite)) { if(lower_type == 0) - this->boss->change_state(new BossMove, "Move"); + this->boss->request_state_change(new BossMove, "Move"); if(lower_type == 1) - this->boss->change_state(new BossMoveBackwards, "MoveBackwards"); + this->boss->request_state_change(new BossMoveBackwards, "MoveBackwards"); } } diff --git a/games/BelowTheSurface/collision.h b/games/BelowTheSurface/collision.h index e5cab8a5..bb57c473 100644 --- a/games/BelowTheSurface/collision.h +++ b/games/BelowTheSurface/collision.h @@ -96,7 +96,7 @@ void check_solid_block_collisions(vector>> solid_blocks level_players[k]->set_player_dy(0); level_players[k]->set_on_floor(false); sprite_set_y(level_players[k]->get_player_sprite(), sprite_y(level_players[k]->get_player_sprite()) + 5); - level_players[k]->change_state(new JumpFallState, "JumpFall"); + level_players[k]->request_state_change(new JumpFallState, "JumpFall"); break; } else if (collision == "Left") @@ -158,7 +158,7 @@ void check_door_block_collisions(shared_ptr door, vectorset_player_won(true); door->open_portal(); - level_players[i]->change_state(new DanceState, "Dance"); + level_players[i]->request_state_change(new DanceState, "Dance"); } } } @@ -221,7 +221,7 @@ void check_ladder_collisions(vector>> ladders, unorder level_players[k]->set_on_ladder(true); sprite_set_y(level_players[k]->get_player_sprite(), sprite_y(level_players[k]->get_player_sprite()) - 10); level_players[k]->set_player_dx(0); - level_players[k]->change_state(new ClimbState, "Climb"); + level_players[k]->request_state_change(new ClimbState, "Climb"); level_players[k]->set_on_floor(false); break; } @@ -383,7 +383,7 @@ void check_enemy_player_collisions(vector> level_enemies, vect { level_players[j]->player_health -= 1; start_timer(damage_timer); - level_players[j]->change_state(new HurtState, "Hurt"); + level_players[j]->request_state_change(new HurtState, "Hurt"); } int time = timer_ticks(damage_timer) / 1000; @@ -416,7 +416,7 @@ void check_enemy_player_collisions(vector> level_enemies, vect level_enemies[i]->take_damage(1); } } - level_players[j]->change_state(new JumpRiseState, "JumpRise"); + level_players[j]->request_state_change(new JumpRiseState, "JumpRise"); level_players[j]->set_player_dx(0); } } diff --git a/games/BelowTheSurface/flymachine.h b/games/BelowTheSurface/flymachine.h index 6322cad0..63b42208 100644 --- a/games/BelowTheSurface/flymachine.h +++ b/games/BelowTheSurface/flymachine.h @@ -35,12 +35,14 @@ class FlyMachine { private: FlyMachineState *state; + FlyMachineState *next_state; + string next_state_type; sprite enemy_sprite; bool facing_left; bool flying_up = true; public: - FlyMachine(FlyMachineState *state, sprite enemy_sprite) : state(nullptr) + FlyMachine(FlyMachineState *state, sprite enemy_sprite) : state(nullptr), next_state(nullptr) { this->enemy_sprite = enemy_sprite; sprite_start_animation(enemy_sprite, "LeftFly"); @@ -51,6 +53,12 @@ class FlyMachine { delete state; }; + + void request_state_change(FlyMachineState *new_state, string type) + { + this->next_state = new_state; + this->next_state_type = type; + }; void change_state(FlyMachineState *new_state, string type) { @@ -59,6 +67,15 @@ class FlyMachine this->state = new_state; this->state->set_state(this, type); }; + + void apply_next_state() + { + if (this->next_state != nullptr) + { + change_state(this->next_state, this->next_state_type); + this->next_state = nullptr; + } + } void update() { diff --git a/games/BelowTheSurface/level.h b/games/BelowTheSurface/level.h index c6519a7c..ccc71250 100644 --- a/games/BelowTheSurface/level.h +++ b/games/BelowTheSurface/level.h @@ -214,6 +214,7 @@ class Level level_players[i]->update(); level_players[i]->get_input(); level_players[i]->update_hitbox(); + level_players[i]->apply_next_state(); } if (level_players[i]->has_player_won()) @@ -240,7 +241,7 @@ class Level for(int i = 0; i < level_players.size(); i++) { if(level_players[i]->get_state_type() != "Dance") - level_players[i]->change_state(new DanceState, "Dance"); + level_players[i]->request_state_change(new DanceState, "Dance"); } } } @@ -268,7 +269,7 @@ class Level //if player 1 fall out of the camera, kill them if (to_screen_y(player_pos.y) > screen_height() && level_players[i]->get_state_type() != "Dying") { if(level_players[i]->get_state_type() != "Spawn") - this->level_players[i]->change_state(new DyingState, "Dying"); + this->level_players[i]->request_state_change(new DyingState, "Dying"); } // if player 2 hit the end of the camera, both player can't move @@ -301,7 +302,7 @@ class Level if (level_players[i]->player_health < 1 && level_players[i]->get_state_type() != "Dying") { if(level_players[i]->get_state_type() != "Spawn") - this->level_players[i]->change_state(new DyingState, "Dying"); + this->level_players[i]->request_state_change(new DyingState, "Dying"); } //If players sets out of lives diff --git a/games/BelowTheSurface/player.h b/games/BelowTheSurface/player.h index 76bff091..87521fb4 100644 --- a/games/BelowTheSurface/player.h +++ b/games/BelowTheSurface/player.h @@ -47,6 +47,8 @@ class Player { private: PlayerState *state; + PlayerState *next_state; + string next_state_type; sprite player_sprite; point_2d position; bool facing_left; @@ -66,7 +68,7 @@ class Player int player_lives = 3; int player_health = 3; - Player(PlayerState *state, sprite player_sprite, point_2d initial_position, bool facing_left, player_input input) : state(nullptr) + Player(PlayerState *state, sprite player_sprite, point_2d initial_position, bool facing_left, player_input input) : state(nullptr), next_state(nullptr) { this->change_state(state, "Initial"); this->player_sprite = player_sprite; @@ -84,6 +86,12 @@ class Player delete state; }; + void request_state_change(PlayerState *new_state, string type) + { + this->next_state = new_state; + this->next_state_type = type; + }; + void change_state(PlayerState *new_state, string type) { if (this->state != nullptr) @@ -91,6 +99,15 @@ class Player this->state = new_state; this->state->set_state(this, type); }; + + void apply_next_state() + { + if (this->next_state != nullptr) + { + change_state(this->next_state, this->next_state_type); + this->next_state = nullptr; + } + } void update() { @@ -484,7 +501,7 @@ void player_draw_pipe(Player *player) { if(player->with_pipe()) { - point_2d position = center_point(player->get_player_sprite()); + point_2d position = sprite_center_point(player->get_player_sprite()); bitmap pipe = player->get_held_pipe()->get_bitmap(); drawing_options opts = option_defaults(); opts.draw_cell = player->get_held_pipe()->get_cell(); @@ -530,28 +547,28 @@ void IdleState::get_input() if (key_down(player->input.left_key)) { this->player->set_facing_left(true); - this->player->change_state(new RunState(0), "RunLeft"); + this->player->request_state_change(new RunState(0), "RunLeft"); } if (key_down(player->input.right_key)) { this->player->set_facing_left(false); - this->player->change_state(new RunState(0), "RunRight"); + this->player->request_state_change(new RunState(0), "RunRight"); } if ((key_typed(player->input.jump_key) || key_typed(player->input.jump_key2)) && player->is_on_floor()) { - this->player->change_state(new JumpRiseState, "JumpRise"); + this->player->request_state_change(new JumpRiseState, "JumpRise"); } if (key_typed(Z_KEY)) { - this->player->change_state(new DanceState, "Dance"); + this->player->request_state_change(new DanceState, "Dance"); } if (key_typed(player->input.attack_key)) { - this->player->change_state(new AttackState, "Attack"); + this->player->request_state_change(new AttackState, "Attack"); } if (key_down(player->input.crouch_key)) { - this->player->change_state(new CrouchState, "Crouch"); + this->player->request_state_change(new CrouchState, "Crouch"); } } @@ -601,11 +618,11 @@ void RunState::get_input() { if (key_released(player->input.left_key) || key_released(player->input.right_key)) { - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); } if ((key_typed(player->input.jump_key) || key_typed(player->input.jump_key2)) && player->is_on_floor()) { - this->player->change_state(new JumpRiseState, "JumpRise"); + this->player->request_state_change(new JumpRiseState, "JumpRise"); } } @@ -637,7 +654,7 @@ void JumpRiseState::update() if ((initial_y - current_y) > max_jump_height) { sprite_set_dy(player->get_player_sprite(), 0); - this->player->change_state(new JumpFallState, "JumpFall"); + this->player->request_state_change(new JumpFallState, "JumpFall"); } } @@ -674,11 +691,11 @@ void JumpFallState::update() { sprite_set_dy(player->get_player_sprite(), 0); if (player->is_facing_left() && key_down(player->input.left_key) && player->is_on_floor()) - this->player->change_state(new RunState(sprite_dx(player->get_player_sprite())), "RunLeft"); + this->player->request_state_change(new RunState(sprite_dx(player->get_player_sprite())), "RunLeft"); else if (!player->is_facing_left() && key_down(player->input.right_key) && player->is_on_floor()) - this->player->change_state(new RunState(sprite_dx(player->get_player_sprite())), "RunRight"); + this->player->request_state_change(new RunState(sprite_dx(player->get_player_sprite())), "RunRight"); else - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); } } @@ -687,11 +704,11 @@ void JumpFallState::get_input() if (player->is_on_floor()) { if (key_down(player->input.left_key) && player->is_facing_left()) - this->player->change_state(new RunState(sprite_dx(player->get_player_sprite())), "RunLeft"); + this->player->request_state_change(new RunState(sprite_dx(player->get_player_sprite())), "RunLeft"); else if (key_down(player->input.right_key) && !player->is_facing_left()) - this->player->change_state(new RunState(sprite_dx(player->get_player_sprite())), "RunRight"); + this->player->request_state_change(new RunState(sprite_dx(player->get_player_sprite())), "RunRight"); else - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); } else { @@ -726,7 +743,7 @@ void DanceState::get_input() { if (key_typed(Z_KEY)) { - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); }//this is a test please don't use this for actual actions! } @@ -751,7 +768,7 @@ void AttackState::update() sprite_fall(player->get_player_sprite()); if (sprite_animation_has_ended(player_sprite)) - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); update_sprite(player_sprite); } @@ -786,7 +803,7 @@ void CrouchState::get_input() { if (key_released(player->input.crouch_key)) { - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); } } @@ -809,7 +826,7 @@ void HurtState::update() draw_sprite(player_sprite); if (sprite_animation_has_ended(player_sprite)) - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); update_sprite(player_sprite); } @@ -834,7 +851,7 @@ void ClimbState::update() if (!player->is_on_ladder()) { - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); } } @@ -879,7 +896,7 @@ void ClimbState::get_input() if(player->is_on_floor()) { - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); } } if (key_released(player->input.jump_key) || key_released(player->input.jump_key2) || key_released(player->input.crouch_key)) @@ -928,7 +945,7 @@ void DyingState::update() else { stop_timer(dying_timer); - this->player->change_state(new SpawningState, "Spawn"); + this->player->request_state_change(new SpawningState, "Spawn"); } } @@ -969,7 +986,7 @@ void SpawningState::update() else { stop_timer(spawn_timer); - this->player->change_state(new IdleState, "Idle"); + this->player->request_state_change(new IdleState, "Idle"); } } diff --git a/games/BelowTheSurface/program.cpp b/games/BelowTheSurface/program.cpp index 98374b5a..1ede5be3 100644 --- a/games/BelowTheSurface/program.cpp +++ b/games/BelowTheSurface/program.cpp @@ -143,6 +143,7 @@ int main(int argc, char *argv[]) while (!key_typed(ESCAPE_KEY) && !quit_requested()) { screen->update(); + screen->apply_next_state(); process_events(); refresh_screen(refresh_rate); } diff --git a/games/BelowTheSurface/ratmachine.h b/games/BelowTheSurface/ratmachine.h index 2b9ee8de..3e361eec 100644 --- a/games/BelowTheSurface/ratmachine.h +++ b/games/BelowTheSurface/ratmachine.h @@ -35,13 +35,15 @@ class RatMachine { private: RatMachineState *state; + RatMachineState *next_state; + string next_state_type; sprite enemy_sprite; bool facing_left; vector> level_players; public: - RatMachine(RatMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr) + RatMachine(RatMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr), next_state(nullptr) { this->enemy_sprite = enemy_sprite; this->level_players = level_players; @@ -53,6 +55,12 @@ class RatMachine { delete state; }; + + void request_state_change(RatMachineState *new_state, string type) + { + this->next_state = new_state; + this->next_state_type = type; + }; void change_state(RatMachineState *new_state, string type) { @@ -61,6 +69,15 @@ class RatMachine this->state = new_state; this->state->set_state(this, type); }; + + void apply_next_state() + { + if (this->next_state != nullptr) + { + change_state(this->next_state, this->next_state_type); + this->next_state = nullptr; + } + } void update() { @@ -185,12 +202,12 @@ void RatMove::update() double x_dist = rat_pos.x - player_pos.x; if(abs(x_dist) < 30) { - this->rat->change_state(new RatBite, "Bite"); + this->rat->request_state_change(new RatBite, "Bite"); break; } if(abs(x_dist) > 300) { - this->rat->change_state(new RatCrawl, "Crawl"); + this->rat->request_state_change(new RatCrawl, "Crawl"); break; } } @@ -225,7 +242,7 @@ void RatIdle::update() double x_dist = rat_pos.x - player_pos.x; if(abs(x_dist) < 450) { - this->rat->change_state(new RatMove, "Move"); + this->rat->request_state_change(new RatMove, "Move"); break; } } @@ -233,7 +250,7 @@ void RatIdle::update() timer += 0.01; if(timer > timer_length) - this->rat->change_state(new RatCrawl, "Crawl"); + this->rat->request_state_change(new RatCrawl, "Crawl"); } void RatBite::update() @@ -243,7 +260,7 @@ void RatBite::update() sprite_set_dx(rat_sprite, 0); if(sprite_animation_has_ended(rat_sprite)) - this->rat->change_state(new RatCrawlAway, "CrawlAway"); + this->rat->request_state_change(new RatCrawlAway, "CrawlAway"); else { if(this->rat->get_facing_left()) @@ -278,7 +295,7 @@ void RatCrawl::update() if(abs(x_dist) < 300) { - this->rat->change_state(new RatMove, "Move"); + this->rat->request_state_change(new RatMove, "Move"); break; } } @@ -302,5 +319,5 @@ void RatCrawlAway::update() timer += 0.01; if(timer > 1) - this->rat->change_state(new RatCrawl, "Crawl"); + this->rat->request_state_change(new RatCrawl, "Crawl"); } \ No newline at end of file diff --git a/games/BelowTheSurface/screen.h b/games/BelowTheSurface/screen.h index 1567231b..d2754162 100644 --- a/games/BelowTheSurface/screen.h +++ b/games/BelowTheSurface/screen.h @@ -38,6 +38,8 @@ class Screen { private: ScreenState *state; + ScreenState *next_state = nullptr; + string next_state_type; int tile_size; int players = 1; vector cell_sheets; @@ -63,6 +65,12 @@ class Screen delete state; }; + void request_state_change(ScreenState *new_state, string type) + { + this->next_state = new_state; + this->next_state_type = type; + }; + void change_state(ScreenState *new_state, string type) { if (this->state != nullptr) @@ -71,6 +79,15 @@ class Screen this->state->set_state(this, type); }; + void apply_next_state() + { + if (this->next_state != nullptr) + { + change_state(this->next_state, this->next_state_type); + this->next_state = nullptr; + } + } + void update() { this->state->update(); @@ -229,7 +246,7 @@ class LevelScreen : public ScreenState { this->screen->level_number += 1; this->screen->current_level = get_next_level(this->screen->level_number, this->screen->get_cell_sheets(), this->screen->get_tile_size(), this->screen->get_players()); - this->screen->change_state(new PreLevelScreen, "Pre Level"); + this->screen->request_state_change(new PreLevelScreen, "Pre Level"); } } @@ -239,7 +256,7 @@ class LevelScreen : public ScreenState { this->screen->level_number -= 1; this->screen->current_level = get_next_level(this->screen->level_number, this->screen->get_cell_sheets(), this->screen->get_tile_size(), this->screen->get_players()); - this->screen->change_state(new PreLevelScreen, "Pre Level"); + this->screen->request_state_change(new PreLevelScreen, "Pre Level"); } } } @@ -434,13 +451,13 @@ void CompanyIntroScreen::update() alpha = screen_effect(alpha, screen_time, "ScreenTimer", 2); if(time_up) - this->screen->change_state(new TeamIntroScreen, "TeamIntro"); + this->screen->request_state_change(new TeamIntroScreen, "TeamIntro"); if(key_typed(RETURN_KEY) || key_typed(screen->input_key)) { stop_timer("ScreenTimer"); reset_timer("ScreenTimer"); - this->screen->change_state(new TeamIntroScreen, "TeamIntro"); + this->screen->request_state_change(new TeamIntroScreen, "TeamIntro"); } } @@ -474,13 +491,13 @@ void TeamIntroScreen::update() alpha = screen_effect(alpha, screen_time, "ScreenTimer", 2); if(time_up) - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); if(key_typed(RETURN_KEY) || key_typed(screen->input_key)) { stop_timer("ScreenTimer"); reset_timer("ScreenTimer"); - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); } } @@ -581,7 +598,7 @@ void MenuScreen::update() play_sound_effect("Select"); this->screen->set_players(1); stop_music(); - this->screen->change_state(new PreLevelScreen, "Pre Level"); + this->screen->request_state_change(new PreLevelScreen, "Pre Level"); } break; case 1: @@ -589,19 +606,19 @@ void MenuScreen::update() play_sound_effect("Select"); this->screen->set_players(2); stop_music(); - this->screen->change_state(new PreLevelScreen, "Pre Level"); + this->screen->request_state_change(new PreLevelScreen, "Pre Level"); } break; case 2: { play_sound_effect("Select"); - this->screen->change_state(new PasswordScreen, "Password"); + this->screen->request_state_change(new PasswordScreen, "Password"); } break; case 3: { play_sound_effect("Select"); - this->screen->change_state(new ExtraScreen, "Extras"); + this->screen->request_state_change(new ExtraScreen, "Extras"); } break; case 4: @@ -655,25 +672,25 @@ void ExtraScreen::update() case 0: { play_sound_effect("Select"); - this->screen->change_state(new BackstoryScreen, "Backstory"); + this->screen->request_state_change(new BackstoryScreen, "Backstory"); } break; case 1: { play_sound_effect("Select"); - this->screen->change_state(new CreditsScreen, "Credits"); + this->screen->request_state_change(new CreditsScreen, "Credits"); } break; case 2: { play_sound_effect("Select"); - this->screen->change_state(new ControlScreen, "Controls"); + this->screen->request_state_change(new ControlScreen, "Controls"); } break; case 3: { play_sound_effect("Select"); - this->screen->change_state(new MenuScreen, "Main Menu"); + this->screen->request_state_change(new MenuScreen, "Main Menu"); } break; default: @@ -739,11 +756,11 @@ void PreLevelScreen::update() { stop_timer("ScreenTimer"); reset_timer("ScreenTimer"); - this->screen->change_state(new LevelScreen, "Level"); + this->screen->request_state_change(new LevelScreen, "Level"); } if(time_up) - this->screen->change_state(new LevelScreen, "Level"); + this->screen->request_state_change(new LevelScreen, "Level"); } string get_pause_text(int id) @@ -795,12 +812,12 @@ void LevelScreen::update() { stop_music(); this->screen->level_number += 1; - this->screen->change_state(new PreLevelScreen, "Pre Level"); + this->screen->request_state_change(new PreLevelScreen, "Pre Level"); } else { stop_music(); - this->screen->change_state(new WinScreen, "Win"); + this->screen->request_state_change(new WinScreen, "Win"); } } } @@ -811,7 +828,7 @@ void LevelScreen::update() stop_music(); this->screen->level_number = 1; this->screen->current_level = get_next_level(this->screen->level_number,this->screen->get_cell_sheets(),this->screen->get_tile_size(),this->screen->get_players()); - this->screen->change_state(new GameOverScreen, "GameOver"); + this->screen->request_state_change(new GameOverScreen, "GameOver"); } } @@ -853,7 +870,7 @@ void LevelScreen::update() stop_music(); this->screen->level_number = 1; this->screen->current_level = get_next_level(this->screen->level_number,this->screen->get_cell_sheets(),this->screen->get_tile_size(),this->screen->get_players()); - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); break; } default: @@ -941,12 +958,12 @@ void GameOverScreen::update() { case 0: { - this->screen->change_state(new PreLevelScreen, "PreLevel"); + this->screen->request_state_change(new PreLevelScreen, "PreLevel"); break; } case 1: { - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); break; } default: @@ -1022,12 +1039,12 @@ void WinScreen::update() { case 0: { - this->screen->change_state(new PreLevelScreen, "PreLevel"); + this->screen->request_state_change(new PreLevelScreen, "PreLevel"); break; } case 1: { - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); break; } default: @@ -1081,7 +1098,7 @@ void CreditsScreen::update() } if(key_typed(RETURN_KEY) || key_typed(screen->input_key)) - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); } void ControlScreen::update() @@ -1112,7 +1129,7 @@ void ControlScreen::update() if(key_typed(RETURN_KEY) || key_typed(screen->input_key)) - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); } void BackstoryScreen::update() @@ -1142,7 +1159,7 @@ void BackstoryScreen::update() draw_text("Press key to continue. . .", font_color, screen_font, 20, pt.x- text_width("Press key to continue. . .", screen_font, 20)/2, (pt.y - text_height("Press key to continue. . .", screen_font, 20)/2) + 180, option_to_screen()); } else if (current > max_screens - 1) - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); else draw_bitmap(this->name(), 0, 0, option_to_screen()); @@ -1150,7 +1167,7 @@ void BackstoryScreen::update() { current++; if(current > max_screens - 1) - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); } draw_text("Press key to continue. . .", font_color, screen_font, 20, pt.x- text_width("Press key to continue. . .", screen_font, 20)/2, (pt.y - text_height("Press key to continue. . .", screen_font, 20)/2) + 180, option_to_screen()); @@ -1167,7 +1184,7 @@ void enter_level(int level_number, Screen* screen) { screen->level_number = level_number; play_sounds(); - screen->change_state(new PreLevelScreen, "Pre Level"); + screen->request_state_change(new PreLevelScreen, "Pre Level"); } string get_password_text(int id) @@ -1240,7 +1257,7 @@ void PasswordScreen::update() } case 2: { - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); break; } default: @@ -1256,7 +1273,7 @@ void PasswordScreen::update() if(password == "EXITEXITEXIT") { play_sound_effect("Select"); - this->screen->change_state(new MenuScreen, "Menu"); + this->screen->request_state_change(new MenuScreen, "Menu"); } else if(password == "START") { diff --git a/games/BelowTheSurface/snakemachine.h b/games/BelowTheSurface/snakemachine.h index 331dbf32..6a9d6571 100644 --- a/games/BelowTheSurface/snakemachine.h +++ b/games/BelowTheSurface/snakemachine.h @@ -33,13 +33,15 @@ class SnakeMachine { private: SnakeMachineState *state; + SnakeMachineState *next_state; + string next_state_type; sprite enemy_sprite; bool facing_left; vector> level_players; public: - SnakeMachine(SnakeMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr) + SnakeMachine(SnakeMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr), next_state(nullptr) { this->enemy_sprite = enemy_sprite; this->level_players = level_players; @@ -51,6 +53,12 @@ class SnakeMachine { delete state; }; + + void request_state_change(SnakeMachineState *new_state, string type) + { + this->next_state = new_state; + this->next_state_type = type; + }; void change_state(SnakeMachineState *new_state, string type) { @@ -59,6 +67,15 @@ class SnakeMachine this->state = new_state; this->state->set_state(this, type); }; + + void apply_next_state() + { + if (this->next_state != nullptr) + { + change_state(this->next_state, this->next_state_type); + this->next_state = nullptr; + } + } void update() { @@ -139,7 +156,7 @@ void SnakeIdle::update() double y_dist = snake_pos.y - player_pos.y; if(abs(x_dist) < 320 && abs(y_dist) < 17) { - this->snake->change_state(new SnakeCharge, "Charge"); + this->snake->request_state_change(new SnakeCharge, "Charge"); break; } } @@ -162,5 +179,5 @@ void SnakeCharge::update() charge_time += 0.03; if(charge_time > 2) - this->snake->change_state(new SnakeIdle, "Idle"); + this->snake->request_state_change(new SnakeIdle, "Idle"); } \ No newline at end of file diff --git a/games/BelowTheSurface/tentaclemachine.h b/games/BelowTheSurface/tentaclemachine.h index a75ca638..f7a7b5ef 100644 --- a/games/BelowTheSurface/tentaclemachine.h +++ b/games/BelowTheSurface/tentaclemachine.h @@ -34,13 +34,15 @@ class TentacleMachine { private: TentacleMachineState *state; + TentacleMachineState *next_state; + string next_state_type; sprite enemy_sprite; bool facing_left; vector> level_players; public: - TentacleMachine(TentacleMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr) + TentacleMachine(TentacleMachineState *state, sprite enemy_sprite, vector> level_players) : state(nullptr), next_state(nullptr) { this->enemy_sprite = enemy_sprite; this->level_players = level_players; @@ -53,6 +55,12 @@ class TentacleMachine delete state; }; + void request_state_change(TentacleMachineState *new_state, string type) + { + this->next_state = new_state; + this->next_state_type = type; + }; + void change_state(TentacleMachineState *new_state, string type) { if (this->state != nullptr) @@ -61,6 +69,15 @@ class TentacleMachine this->state->set_state(this, type); }; + void apply_next_state() + { + if (this->next_state != nullptr) + { + change_state(this->next_state, this->next_state_type); + this->next_state = nullptr; + } + } + void update() { this->state->update(); @@ -160,7 +177,7 @@ void TentacleIdle::update() //double y_dist = tent_pos.y - player_pos.y; if(abs(x_dist) < 200) { - this->tentacle->change_state(new TentaclePopUp, "PopUp"); + this->tentacle->request_state_change(new TentaclePopUp, "PopUp"); break; } } @@ -171,7 +188,7 @@ void TentaclePopUp::update() sprite tentacle_sprite = this->tentacle->get_sprite(); if(sprite_animation_has_ended(tentacle_sprite)) - this->tentacle->change_state(new TentacleWiggle, "Wiggle"); + this->tentacle->request_state_change(new TentacleWiggle, "Wiggle"); else set_proper_direction(tentacle_sprite, "PopUp"); } @@ -181,7 +198,7 @@ void TentaclePopDown::update() sprite tentacle_sprite = this->tentacle->get_sprite(); if(sprite_animation_has_ended(tentacle_sprite)) - this->tentacle->change_state(new TentacleIdle, "Idle"); + this->tentacle->request_state_change(new TentacleIdle, "Idle"); else set_proper_direction(tentacle_sprite, "PopDown"); } @@ -201,7 +218,7 @@ void TentacleWiggle::update() double x_dist = tent_pos.x - player_pos.x; if(abs(x_dist) > 200) { - this->tentacle->change_state(new TentaclePopDown, "PopDown"); + this->tentacle->request_state_change(new TentaclePopDown, "PopDown"); break; } }