aboutsummaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
Diffstat (limited to 'game')
-rw-r--r--game/CMakeLists.txt11
-rw-r--r--game/Config.h20
-rw-r--r--game/EngineConfig.h19
-rw-r--r--game/GameScene.cpp1
-rw-r--r--game/PreviewScene.cpp117
-rw-r--r--game/QuitScript.cpp21
-rw-r--r--game/QuitScript.h11
-rw-r--r--game/StartGameScript.cpp2
-rw-r--r--game/background/StartSubScene.cpp48
-rw-r--r--game/enemy/BattleScript.cpp36
-rw-r--r--game/enemy/BattleScript.h2
-rw-r--r--game/enemy/EnemyBulletScript.cpp2
-rw-r--r--game/enemy/EnemyBulletSubScene.cpp7
-rw-r--r--game/enemy/EnemyConfig.h1
-rw-r--r--game/enemy/EnemyPool.cpp2
-rw-r--r--game/enemy/EnemyPool.h5
-rw-r--r--game/enemy/EnemyScript.cpp128
-rw-r--r--game/enemy/EnemyScript.h14
-rw-r--r--game/enemy/EnemySubScene.cpp24
-rw-r--r--game/hud/HudScript.cpp5
-rw-r--r--game/main.cpp3
-rw-r--r--game/menus/ButtonNextMainMenuSubScript.cpp2
-rw-r--r--game/menus/ButtonReplaySubScript.cpp13
-rw-r--r--game/menus/ButtonReplaySubScript.h3
-rw-r--r--game/menus/ButtonSubScene.cpp52
-rw-r--r--game/menus/ButtonSubScene.h14
-rw-r--r--game/menus/endgame/EndGameSubScene.cpp45
-rw-r--r--game/menus/endgame/EndGameSubScript.cpp46
-rw-r--r--game/menus/endgame/EndGameSubScript.h3
-rw-r--r--game/menus/mainmenu/MainMenuScene.cpp7
-rw-r--r--game/menus/shop/ButtonBuySelectBubbleScript.cpp34
-rw-r--r--game/menus/shop/ButtonBuySelectBubbleScript.h14
-rw-r--r--game/menus/shop/ButtonBuySelectBulletScript.cpp34
-rw-r--r--game/menus/shop/ButtonBuySelectBulletScript.h14
-rw-r--r--game/menus/shop/ShopLoadScript.cpp126
-rw-r--r--game/menus/shop/ShopLoadScript.h10
-rw-r--r--game/menus/shop/ShopMenuScene.cpp224
-rw-r--r--game/menus/shop/Shopconfig.h14
-rw-r--r--game/missile/AlertScript.cpp38
-rw-r--r--game/missile/AlertScript.h11
-rw-r--r--game/missile/AlertSubScene.cpp33
-rw-r--r--game/missile/AlertSubScene.h8
-rw-r--r--game/missile/MissilePool.cpp2
-rw-r--r--game/missile/MissileScript.cpp39
-rw-r--r--game/missile/MissileSubScene.cpp12
-rw-r--r--game/missile/SpawnEvent.cpp22
-rw-r--r--game/missile/SpawnEvent.h5
-rw-r--r--game/player/PlayerBulletScript.cpp2
-rw-r--r--game/player/PlayerBulletSubScene.cpp4
-rw-r--r--game/player/PlayerEndScript.cpp3
-rw-r--r--game/player/PlayerScript.cpp45
-rw-r--r--game/player/PlayerScript.h12
-rw-r--r--game/player/PlayerSubScene.cpp32
-rw-r--r--game/preview/NpcScript.cpp17
-rw-r--r--game/preview/NpcScript.h5
-rw-r--r--game/preview/NpcSubScene.cpp10
-rw-r--r--game/preview/PrevPlayerScript.cpp71
-rw-r--r--game/preview/PrevPlayerScript.h17
-rw-r--r--game/preview/PrevPlayerSubScene.cpp19
-rw-r--r--game/preview/PreviewReplaySubScript.cpp55
-rw-r--r--game/preview/PreviewReplaySubScript.h24
-rw-r--r--game/preview/PreviewStartRecSubScript.cpp20
-rw-r--r--game/preview/PreviewStartRecSubScript.h11
-rw-r--r--game/preview/PreviewStopRecSubScript.cpp20
-rw-r--r--game/preview/PreviewStopRecSubScript.h11
-rw-r--r--game/scheduler/ObjectsScheduler.cpp55
-rw-r--r--game/scheduler/ObjectsScheduler.h2
67 files changed, 1495 insertions, 244 deletions
diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index e1168eb..a94beca 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.28)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
-set(CMAKE_BUILD_TYPE Debug)
+set(CMAKE_BUILD_TYPE Release)
project(game C CXX)
add_subdirectory(../src crepe)
@@ -33,6 +33,9 @@ target_sources(main PUBLIC
# mainscenes
GameScene.cpp
menus/shop/ShopMenuScene.cpp
+ menus/shop/ShopLoadScript.cpp
+ menus/shop/ButtonBuySelectBubbleScript.cpp
+ menus/shop/ButtonBuySelectBulletScript.cpp
menus/mainmenu/MainMenuScene.cpp
PreviewScene.cpp
main.cpp
@@ -41,6 +44,8 @@ target_sources(main PUBLIC
missile/MissilePool.cpp
missile/MissileScript.cpp
missile/MissileSubScene.cpp
+ missile/AlertSubScene.cpp
+ missile/AlertScript.cpp
missile/SpawnEvent.cpp
#scheduling
@@ -52,11 +57,15 @@ target_sources(main PUBLIC
preview/NpcScript.cpp
preview/PrevPlayerSubScene.cpp
preview/PrevPlayerScript.cpp
+ preview/PreviewStopRecSubScript.cpp
+ preview/PreviewStartRecSubScript.cpp
+ preview/PreviewReplaySubScript.cpp
# scripts
GameScene.cpp
MoveCameraManualyScript.cpp
StartGameScript.cpp
+ QuitScript.cpp
# player
player/PlayerScript.cpp
diff --git a/game/Config.h b/game/Config.h
index 8fa41ba..d2b5fc4 100644
--- a/game/Config.h
+++ b/game/Config.h
@@ -1,16 +1,6 @@
#pragma once
-#include "types.h"
-
-#include <crepe/api/Config.h>
-static const crepe::Config ENGINE_CONFIG {
- .log {
- .level = crepe::Log::Level::DEBUG,
- },
- .window_settings {
- .window_title = "Jetpack joyride clone",
- },
-};
+#include "types.h"
static constexpr int SORT_IN_LAY_BACK_BACKGROUND = 3; // For all scenes
static constexpr int SORT_IN_LAY_BACKGROUND = 4; // For all scenes
@@ -36,7 +26,7 @@ static constexpr int COLL_LAY_ENEMY = 10; // Only for GameScene
static constexpr int COLL_LAY_PLAYER_BULLET = 11; // Only for GameScene
static constexpr float GAME_HEIGHT = 800; // In game units
-static constexpr float HALLWAY_HEIGHT = 475; // In game units
+static constexpr float HALLWAY_HEIGHT = 450; // In game units
static constexpr float VIEWPORT_X = 1100; // In game units
// 'GAME_HEIGHT' (below) should be replaced by '500' when game development is finished
@@ -59,8 +49,12 @@ static constexpr const char * DISTANCE_RUN = "distance_run";
// Player config
static constexpr const char * PLAYER_NAME = "player";
static constexpr int PLAYER_SPEED = 7500; // In game units
-static constexpr int PLAYER_GRAVITY_SCALE = 60; // In game units
+static constexpr float PLAYER_GRAVITY_SCALE = 2.2; // factor
+static constexpr float PLAYER_HELP_KICK_SCALE = 0.2; // factor
+static constexpr float PLAYER_HELP_KICK_MAX = 0.3; // factor
static constexpr const char * CAMERA_NAME = "camera";
// Jetpack particles
static constexpr const char * JETPACK_PARTICLES = "jetpack_particles";
+
+static constexpr bool DISABLE_REPLAY = false;
diff --git a/game/EngineConfig.h b/game/EngineConfig.h
new file mode 100644
index 0000000..6a03a14
--- /dev/null
+++ b/game/EngineConfig.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "Config.h"
+
+#include <crepe/api/Config.h>
+
+static const crepe::Config ENGINE_CONFIG {
+ .log {
+ .level = crepe::Log::Level::DEBUG,
+ },
+ .physics {
+ // this division factor is now the amount of seconds it approximately takes to naturally
+ // fall from the ceiling to floor
+ .gravity = HALLWAY_HEIGHT / 0.5,
+ },
+ .window_settings {
+ .window_title = "Jetpack joyride clone",
+ },
+};
diff --git a/game/GameScene.cpp b/game/GameScene.cpp
index ea55f7b..7803c9d 100644
--- a/game/GameScene.cpp
+++ b/game/GameScene.cpp
@@ -1,6 +1,5 @@
#include "GameScene.h"
#include "Config.h"
-#include "MoveCameraManualyScript.h"
#include "StartGameScript.h"
#include "coins/CoinPoolSubScene.h"
#include "coins/CoinSystemScript.h"
diff --git a/game/PreviewScene.cpp b/game/PreviewScene.cpp
index 6cd9e78..bc28192 100644
--- a/game/PreviewScene.cpp
+++ b/game/PreviewScene.cpp
@@ -1,7 +1,14 @@
#include "PreviewScene.h"
#include "Config.h"
-#include "background/BackgroundSubScene.h"
+#include "background/AquariumSubScene.h"
+#include "background/ForestSubScene.h"
+#include "background/HallwaySubScene.h"
+#include "background/StartSubScene.h"
+#include "hud/HudScript.h"
+#include "hud/HudSubScene.h"
+#include "hud/SpeedScript.h"
+#include "menus/ButtonSubScene.h"
#include "missile/MissilePool.h"
#include "missile/SpawnEvent.h"
#include "preview/NpcSubScene.h"
@@ -36,17 +43,32 @@ using namespace std;
void PreviewScene::load_scene() {
- BackgroundSubScene background(*this);
+ StartSubScene start;
+ HallwaySubScene hallway;
+ ForestSubScene forest;
+ AquariumSubScene aquarium;
+
+ float begin_x = 400;
+
+ begin_x = start.create(*this, begin_x);
+
+ begin_x = hallway.create(*this, begin_x, 1, Color::YELLOW);
+
+ begin_x = aquarium.create(*this, begin_x);
+
+ begin_x = hallway.create(*this, begin_x, 2, Color::GREEN);
GameObject camera = new_object("camera", "camera", vec2(650, 0));
camera.add_component<Camera>(
ivec2(990, 720), vec2(VIEWPORT_X, VIEWPORT_Y),
Camera::Data {
- .bg_color = Color::RED,
+ .bg_color = Color::BLACK,
}
);
- camera.add_component<Rigidbody>(Rigidbody::Data {});
+
camera.add_component<BehaviorScript>().set_script<MissileSpawnEventHandler>();
+ camera.add_component<BehaviorScript>().set_script<HudScript>();
+ camera.add_component<BehaviorScript>().set_script<SpeedScript>();
GameObject floor = new_object("floor", "game_world", vec2(0, 325));
floor.add_component<Rigidbody>(Rigidbody::Data {
@@ -71,29 +93,90 @@ void PreviewScene::load_scene() {
.collision_layer = COLL_LAY_BOT_TOP,
});
ceiling.add_component<BoxCollider>(vec2(INFINITY, 200));
- GameObject world = this->new_object("world", "TAG", vec2 {0, 0}, 0, 1);
+ GameObject world = this->new_object("world", "TAG", vec2 {0, 0}, 0, 1);
world.add_component<Rigidbody>(Rigidbody::Data {
.body_type = Rigidbody::BodyType::STATIC,
- .collision_layers = {0},
+ .collision_layer = 100,
});
+ world.add_component<BoxCollider>(vec2(100, INFINITY), vec2(VIEWPORT_X, VIEWPORT_Y));
+ world.add_component<BoxCollider>(vec2(100, INFINITY), vec2(100, VIEWPORT_Y));
+
PrevPlayerSubScene player(*this);
NpcSubScene npc(*this);
SmokeSubScene smoke(*this);
MissilePool mpool(*this);
- /*
-
- for (int i = 0; i < 200; ++i) {
- int row = i / 10;
- int col = i % 10;
- float x = col * 25 + i;
- float y = row * 25 - 400;
- GameObject game_coin = this->new_object("coin", "coin", vec2 {x, y}, 0, 1);
- Coin coin(game_coin, vec2 {0, 0});
- }
- */
+ HudSubScene hud;
+ hud.create(*this);
+
+ const float Y_POS_BUTTONS = -220;
+ const float X_POS_BUTTONS = -150;
+ const float X_POS_BUTTONS_SPACING = 145;
+ ButtonSubScene button;
+ button.create(
+ *this,
+ ButtonSubScene::Data {
+ .text = "BACK",
+ .text_width = 60,
+ .position = {X_POS_BUTTONS, Y_POS_BUTTONS},
+ .script_type = ButtonSubScene::ScriptSelect::NEXT,
+ .button_type = ButtonSubScene::ButtonSelect::BACK,
+ .scale = 0.6,
+ .worldspace = false,
+ .tag = "Next button",
+ .sorting_layer_offset = 20,
+ }
+ );
+
+ button.create(
+ *this,
+ ButtonSubScene::Data {
+ .text = "START REC",
+ .text_width = 130,
+ .position = {X_POS_BUTTONS + X_POS_BUTTONS_SPACING, Y_POS_BUTTONS},
+ .script_type = ButtonSubScene::ScriptSelect::PREVIEW_START,
+ .button_type = ButtonSubScene::ButtonSelect::LARGE,
+ .scale = 0.6,
+ .worldspace = false,
+ .tag = "Next button",
+ .sorting_layer_offset = 20,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::YELLOW,
+ }
+ );
+
+ button.create(
+ *this,
+ ButtonSubScene::Data {
+ .text = "STOP REC",
+ .text_width = 120,
+ .position = {X_POS_BUTTONS + X_POS_BUTTONS_SPACING * 2, Y_POS_BUTTONS},
+ .script_type = ButtonSubScene::ScriptSelect::PREVIEW_STOP,
+ .button_type = ButtonSubScene::ButtonSelect::LARGE,
+ .scale = 0.6,
+ .worldspace = false,
+ .tag = "Next button",
+ .sorting_layer_offset = 20,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::BLUE,
+ }
+ );
+
+ button.create(
+ *this,
+ ButtonSubScene::Data {
+ .text = "REPLAY",
+ .text_width = 90,
+ .position = {X_POS_BUTTONS + X_POS_BUTTONS_SPACING * 3, Y_POS_BUTTONS},
+ .script_type = ButtonSubScene::ScriptSelect::PREVIEW_REPLAY,
+ .button_type = ButtonSubScene::ButtonSelect::LARGE,
+ .scale = 0.6,
+ .worldspace = false,
+ .tag = "Next button",
+ .sorting_layer_offset = 20,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::ORANGE,
+ }
+ );
}
string PreviewScene::get_name() const { return "preview scene"; }
diff --git a/game/QuitScript.cpp b/game/QuitScript.cpp
new file mode 100644
index 0000000..0c9f55a
--- /dev/null
+++ b/game/QuitScript.cpp
@@ -0,0 +1,21 @@
+
+
+#include "QuitScript.h"
+
+#include <crepe/api/Event.h>
+#include <crepe/api/KeyCodes.h>
+
+using namespace crepe;
+
+bool QuitScript::on_event(const KeyPressEvent & ev) {
+ if (Keycode::ESCAPE == ev.key) {
+ trigger_event<ShutDownEvent>(ShutDownEvent {});
+ }
+ return false;
+}
+
+void QuitScript::init() {
+ subscribe<KeyPressEvent>([this](const KeyPressEvent & ev) -> bool {
+ return this->on_event(ev);
+ });
+}
diff --git a/game/QuitScript.h b/game/QuitScript.h
new file mode 100644
index 0000000..b79a744
--- /dev/null
+++ b/game/QuitScript.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <crepe/api/Script.h>
+
+class QuitScript : public crepe::Script {
+private:
+ bool on_event(const crepe::KeyPressEvent & ev);
+
+public:
+ void init();
+};
diff --git a/game/StartGameScript.cpp b/game/StartGameScript.cpp
index 48055af..6d47e65 100644
--- a/game/StartGameScript.cpp
+++ b/game/StartGameScript.cpp
@@ -64,7 +64,7 @@ void StartGameScript::fixed_update(crepe::duration_t dt) {
// Start camera movement, enable player jumping and disable this script
if (player_transform.position.x > 500) {
Rigidbody & rb = this->get_components_by_name<Rigidbody>("camera").front();
- rb.data.linear_velocity = vec2(PLAYER_SPEED * dt.count(), 0);
+ rb.data.linear_velocity = vec2(PLAYER_SPEED * 0.02, 0);
BehaviorScript & player_script
= this->get_components_by_name<BehaviorScript>("player").front();
player_script.active = true;
diff --git a/game/background/StartSubScene.cpp b/game/background/StartSubScene.cpp
index d68287b..ba80517 100644
--- a/game/background/StartSubScene.cpp
+++ b/game/background/StartSubScene.cpp
@@ -199,8 +199,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_1_sprite.active = false;
Rigidbody & frag_1_rb = frag_1.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 10,
- .linear_velocity = vec2(400, 400),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(400, -400),
.linear_velocity_coefficient = vec2(0.5, 0.6),
.angular_velocity = 500,
.angular_velocity_coefficient = 0.55,
@@ -223,8 +223,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_2_sprite.active = false;
Rigidbody & frag_2_rb = frag_2.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 20,
- .linear_velocity = vec2(400, 400),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(400, -400),
.linear_velocity_coefficient = vec2(0.35, 0.4),
.angular_velocity = 400,
.angular_velocity_coefficient = 0.55,
@@ -247,8 +247,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_3_sprite.active = false;
Rigidbody & frag_3_rb = frag_3.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 30,
- .linear_velocity = vec2(400, 400),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(400, -400),
.linear_velocity_coefficient = vec2(0.3, 0.3),
.angular_velocity = 300,
.angular_velocity_coefficient = 0.55,
@@ -271,8 +271,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_4_sprite.active = false;
Rigidbody & frag_4_rb = frag_4.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 40,
- .linear_velocity = vec2(700, 400),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(700, -400),
.linear_velocity_coefficient = vec2(0.2, 0.2),
.angular_velocity = 200,
.angular_velocity_coefficient = 0.55,
@@ -295,8 +295,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_5_sprite.active = false;
Rigidbody & frag_5_rb = frag_5.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 50,
- .linear_velocity = vec2(600, 800),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(600, -500),
.linear_velocity_coefficient = vec2(0.25, 0.15),
.angular_velocity = 100,
.angular_velocity_coefficient = 0.55,
@@ -319,8 +319,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_6_sprite.active = false;
Rigidbody & frag_6_rb = frag_6.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 30,
- .linear_velocity = vec2(300, 800),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(300, -800),
.linear_velocity_coefficient = vec2(0.35, 0.25),
.angular_velocity = 100,
.angular_velocity_coefficient = 0.55,
@@ -343,8 +343,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_7_sprite.active = false;
Rigidbody & frag_7_rb = frag_7.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 20,
- .linear_velocity = vec2(400, 500),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(400, -500),
.linear_velocity_coefficient = vec2(0.45, 0.6),
.angular_velocity = 800,
.angular_velocity_coefficient = 0.55,
@@ -367,8 +367,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_8_sprite.active = false;
Rigidbody & frag_8_rb = frag_8.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 30,
- .linear_velocity = vec2(400, 400),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(400, -400),
.linear_velocity_coefficient = vec2(0.5, 0.6),
.angular_velocity = 500,
.angular_velocity_coefficient = 0.55,
@@ -391,8 +391,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_9_sprite.active = false;
Rigidbody & frag_9_rb = frag_9.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 40,
- .linear_velocity = vec2(200, 400),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(200, -400),
.linear_velocity_coefficient = vec2(0.5, 0.25),
.angular_velocity = 500,
.angular_velocity_coefficient = 0.55,
@@ -415,8 +415,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_10_sprite.active = false;
Rigidbody & frag_10_rb = frag_10.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 50,
- .linear_velocity = vec2(400, 900),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(400, -900),
.linear_velocity_coefficient = vec2(0.35, 0.4),
.angular_velocity = 300,
.angular_velocity_coefficient = 0.55,
@@ -439,8 +439,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_11_sprite.active = false;
Rigidbody & frag_11_rb = frag_11.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 60,
- .linear_velocity = vec2(600, 800),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(600, -400),
.linear_velocity_coefficient = vec2(0.3, 0.3),
.angular_velocity = 200,
.angular_velocity_coefficient = 0.55,
@@ -463,8 +463,8 @@ void StartSubScene::create_wall_fragments(crepe::Scene & scn, float begin_x) {
);
frag_12_sprite.active = false;
Rigidbody & frag_12_rb = frag_12.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 70,
- .linear_velocity = vec2(500, 800),
+ .gravity_scale = 1.0,
+ .linear_velocity = vec2(500, -800),
.linear_velocity_coefficient = vec2(0.25, 0.15),
.angular_velocity = 100,
.angular_velocity_coefficient = 0.55,
diff --git a/game/enemy/BattleScript.cpp b/game/enemy/BattleScript.cpp
index 6d96ef6..798cbb9 100644
--- a/game/enemy/BattleScript.cpp
+++ b/game/enemy/BattleScript.cpp
@@ -1,5 +1,7 @@
#include "BattleScript.h"
+#include "EnemyConfig.h"
#include "EnemyScript.h"
+#include "api/Transform.h"
#include <crepe/api/AI.h>
#include <crepe/api/BehaviorScript.h>
#include <crepe/api/Metadata.h>
@@ -18,11 +20,10 @@ void BattleScript::init() {
void BattleScript::fixed_update(duration_t dt) {
if (!battle_active) return;
bool enemies_alive = false;
- RefVector<BehaviorScript> enemy_scripts
- = this->get_components_by_tag<BehaviorScript>("enemy");
+ RefVector<AI> enemy_ai = this->get_components_by_tag<AI>("enemy");
- for (BehaviorScript & script : enemy_scripts) {
- if (script.active) {
+ for (AI & ai : enemy_ai) {
+ if (ai.active) {
enemies_alive = true;
}
}
@@ -32,20 +33,29 @@ void BattleScript::fixed_update(duration_t dt) {
}
}
bool BattleScript::create_battle(const BattleStartEvent & e) {
- this->battle_active = true;
- RefVector<BehaviorScript> enemy_scripts
- = this->get_components_by_tag<BehaviorScript>("enemy");
- std::uniform_real_distribution<float> dist(10, 30);
- for (int i = 0; i < e.num_enemies; i++) {
- BehaviorScript & script = enemy_scripts[i];
- script.active = true;
+ this->battle_active = e.battle;
+ this->spawn_enemies(e.num_enemies);
+ return false;
+}
+void BattleScript::spawn_enemies(int amount) {
+ RefVector<AI> enemy_ai = this->get_components_by_tag<AI>("enemy");
+ std::uniform_real_distribution<float> dist(70, 150);
+ int spawned = 0;
+ for (int i = 0; i < ENEMY_POOL_MAX; i++) {
+ AI & ai = enemy_ai[i];
+ Transform & enemy_transform
+ = this->get_components_by_id<Transform>(ai.game_object_id).front();
+ if (ai.active == true || enemy_transform.position != ENEMY_POOL_LOCATION) continue;
this->queue_event<SpawnEnemyEvent>(
SpawnEnemyEvent {
.speed = dist(engine),
.column = i,
},
- script.game_object_id
+ ai.game_object_id
);
+ spawned++;
+ if (spawned >= amount) {
+ return;
+ }
}
- return false;
}
diff --git a/game/enemy/BattleScript.h b/game/enemy/BattleScript.h
index ddd0be1..57aa16c 100644
--- a/game/enemy/BattleScript.h
+++ b/game/enemy/BattleScript.h
@@ -9,6 +9,7 @@ struct BattleWonEvent : public crepe::Event {};
struct BattleStartEvent : public crepe::Event {
public:
int num_enemies = 0;
+ bool battle = false;
};
class BattleScript : public crepe::Script {
public:
@@ -20,5 +21,6 @@ private:
bool battle_active = false;
std::random_device rd;
std::default_random_engine engine;
+ void spawn_enemies(int amount);
bool create_battle(const BattleStartEvent & e);
};
diff --git a/game/enemy/EnemyBulletScript.cpp b/game/enemy/EnemyBulletScript.cpp
index 65c0c23..d208a88 100644
--- a/game/enemy/EnemyBulletScript.cpp
+++ b/game/enemy/EnemyBulletScript.cpp
@@ -18,7 +18,7 @@ void EnemyBulletScript::fixed_update(crepe::duration_t dt) {
Transform & cam_transform = this->get_components_by_name<Transform>("camera").front();
Rigidbody & bullet_body = this->get_component<Rigidbody>();
//move
- transform.position.x += bullet_body.data.linear_velocity.x * dt.count();
+ transform.position += bullet_body.data.linear_velocity * dt.count();
vec2 half_screen = camera.viewport_size / 2;
float despawn_location = cam_transform.position.x - half_screen.x - 50;
if (transform.position.x < despawn_location) {
diff --git a/game/enemy/EnemyBulletSubScene.cpp b/game/enemy/EnemyBulletSubScene.cpp
index ad2ca9d..bc31ba8 100644
--- a/game/enemy/EnemyBulletSubScene.cpp
+++ b/game/enemy/EnemyBulletSubScene.cpp
@@ -16,6 +16,7 @@
#include "EnemyBulletScript.h"
#include "EnemyBulletSubScene.h"
#include "EnemyScript.h"
+#include "api/Color.h"
using namespace crepe;
using namespace std;
int EnemyBulletSubScene::create(Scene & scn, int counter) {
@@ -27,19 +28,19 @@ int EnemyBulletSubScene::create(Scene & scn, int counter) {
Rigidbody & bullet_body = bullet.add_component<Rigidbody>(Rigidbody::Data {
.gravity_scale = 0,
.body_type = Rigidbody::BodyType::KINEMATIC,
-
- .linear_velocity = vec2 {-250, 0},
+ .linear_velocity = vec2 {-300, 0},
.kinematic_collision = false,
.collision_layers = {COLL_LAY_MISSILE, COLL_LAY_ZAPPER},
.collision_layer = COLL_LAY_BULLET
});
bullet_body.active = false;
- BoxCollider & bullet_collider = bullet.add_component<BoxCollider>(vec2(60, 30));
+ BoxCollider & bullet_collider = bullet.add_component<BoxCollider>(vec2(40, 10));
//bullet_collider.active = false;
Asset bullet_asset {"asset/other_effects/effect_smgbullet_x2.png"};
Sprite & bullet_sprite = bullet.add_component<Sprite>(
bullet_asset,
Sprite::Data {
+ .color = Color::BLUE,
.flip = {true, false},
.sorting_in_layer = SORT_IN_LAY_OBSTACLES,
.order_in_layer = 1,
diff --git a/game/enemy/EnemyConfig.h b/game/enemy/EnemyConfig.h
index f7b660a..f9fb469 100644
--- a/game/enemy/EnemyConfig.h
+++ b/game/enemy/EnemyConfig.h
@@ -5,3 +5,4 @@
// static constexpr crepe::vec2 PLAYER_BULLET_POOL_LOCATION = {0, -850};
static constexpr crepe::vec2 ENEMY_BULLET_POOL_LOCATION = {0, -750};
static constexpr crepe::vec2 ENEMY_POOL_LOCATION = {0, -650};
+static constexpr int ENEMY_POOL_MAX = 12;
diff --git a/game/enemy/EnemyPool.cpp b/game/enemy/EnemyPool.cpp
index a7179bf..135fc35 100644
--- a/game/enemy/EnemyPool.cpp
+++ b/game/enemy/EnemyPool.cpp
@@ -4,7 +4,7 @@ using namespace std;
void EnemyPool::create_enemies(crepe::Scene & scn) {
EnemySubScene enemy;
int amount = 0;
- while (amount < this->MAXIMUM_AMOUNT) {
+ while (amount < ENEMY_POOL_MAX) {
amount = enemy.create(scn, amount);
}
}
diff --git a/game/enemy/EnemyPool.h b/game/enemy/EnemyPool.h
index f4d6765..cfd0b1c 100644
--- a/game/enemy/EnemyPool.h
+++ b/game/enemy/EnemyPool.h
@@ -1,11 +1,8 @@
#pragma once
+#include "EnemyConfig.h"
#include <crepe/api/Scene.h>
-
class EnemyPool {
public:
void create_enemies(crepe::Scene & scn);
-
-private:
- static constexpr int MAXIMUM_AMOUNT = 10;
};
diff --git a/game/enemy/EnemyScript.cpp b/game/enemy/EnemyScript.cpp
index 5c03539..0822c29 100644
--- a/game/enemy/EnemyScript.cpp
+++ b/game/enemy/EnemyScript.cpp
@@ -1,13 +1,16 @@
#include "EnemyScript.h"
#include "../Config.h"
#include "../Random.h"
-#include "EnemyConfig.h"
+#include "../enemy/EnemyConfig.h"
+#include "api/Color.h"
+#include "api/Sprite.h"
#include <crepe/api/AI.h>
#include <crepe/api/Animator.h>
#include <crepe/api/AudioSource.h>
#include <crepe/api/BoxCollider.h>
#include <crepe/api/ParticleEmitter.h>
#include <crepe/api/Rigidbody.h>
+#include <crepe/api/Sprite.h>
#include <crepe/api/Transform.h>
#include <crepe/types.h>
#include <random>
@@ -16,7 +19,7 @@ using namespace std;
EnemyScript::EnemyScript() {
engine.seed(rd());
this->last_fired = std::chrono::steady_clock::now();
- this->shot_delay = std::chrono::duration<float>(3 + Random::f(1, 0));
+ this->shot_delay = std::chrono::duration<float>(1.5 + Random::f(2, 0));
}
void EnemyScript::init() {
Metadata & meta = this->get_component<Metadata>();
@@ -29,43 +32,78 @@ void EnemyScript::init() {
});
};
void EnemyScript::fixed_update(duration_t dt) {
- if (this->alive) {
- return;
+ if (!spawned) return;
+ auto now = std::chrono::steady_clock::now();
+ std::chrono::duration<float> elapsed_hit = now - last_hit;
+ //hit blink timer
+ if (elapsed_hit > blink_time) {
+ set_hit_blink(false);
}
Transform & transform = this->get_component<Transform>();
+ if (!this->alive) {
+ Camera & camera = this->get_components_by_name<Camera>("camera").front();
+ Transform & cam_transform = this->get_components_by_name<Transform>("camera").front();
+ vec2 half_screen = camera.viewport_size / 2;
+ float x_value = cam_transform.position.x - half_screen.x - 100;
+ if (transform.position.x < x_value) {
+ this->despawn_enemy();
+ }
+ return;
+ }
+
Transform & player_transform = this->get_components_by_name<Transform>("player").front();
Rigidbody & enemy_body = this->get_component<Rigidbody>();
AI & ai_component = this->get_component<AI>();
- //transform.position += enemy_body.data.linear_velocity * dt.count();
float direction_to_player_y = player_transform.position.y - transform.position.y;
float distance_to_player_y = std::abs(direction_to_player_y);
float adjustment_speed = speed * (distance_to_player_y / MAX_DISTANCE);
-
adjustment_speed = std::clamp(adjustment_speed, MIN_SPEED, MAX_SPEED);
- // Move the path nodes on the Y-axis
+ Rigidbody & player_body = this->get_components_by_tag<Rigidbody>("player").front();
+ // move path nodes
for (vec2 & path_node : ai_component.path) {
path_node.y += (direction_to_player_y > 0 ? 1 : -1) * adjustment_speed * dt.count();
+ path_node.x += player_body.data.linear_velocity.x * dt.count();
}
//bullet fire logic:
- auto now = std::chrono::steady_clock::now();
+
std::chrono::duration<float> elapsed = now - last_fired;
if (elapsed > shot_delay) {
- this->shoot(transform.position, 0);
+ this->shoot(transform.position);
last_fired = now;
- this->shot_delay = std::chrono::duration<float>(Random::f(4, 1));
+ this->shot_delay = std::chrono::duration<float>(Random::f(3, 1.5));
}
}
+
bool EnemyScript::spawn_enemy(const SpawnEnemyEvent & e) {
+
this->speed = e.speed;
+ this->alive = true;
+ this->spawned = true;
+ this->health = 2;
+ RefVector<Animator> animators = this->get_components<Animator>();
+ for (Animator & anim : animators) {
+ anim.active = false;
+ anim.set_anim(0);
+ }
+ RefVector<Sprite> sprites = this->get_components<Sprite>();
+ for (Sprite & sprite : sprites) {
+ sprite.data.position_offset.x = 0;
+ }
+ Sprite & jetpack = sprites[2];
+ jetpack.data.position_offset.x = 20;
+ Sprite & gun = sprites[3];
+ gun.data.position_offset.x = -20;
AI & ai_component = this->get_component<AI>();
Transform & transform = this->get_component<Transform>();
Camera & camera = this->get_components_by_name<Camera>("camera").front();
Transform & cam_transform = this->get_components_by_name<Transform>("camera").front();
-
+ Rigidbody & rb = this->get_component<Rigidbody>();
+ rb.data.collision_layers = {COLL_LAY_BOT_TOP, COLL_LAY_PLAYER_BULLET};
+ rb.data.collision_layer = COLL_LAY_ENEMY;
vec2 half_screen = camera.viewport_size / 2;
- float x_value = cam_transform.position.x + half_screen.x - 50 * (1 + e.column);
+ float x_value = cam_transform.position.x + half_screen.x - 40 * (1 + e.column);
uniform_real_distribution<float> dist(
cam_transform.position.y - half_screen.y + 100,
cam_transform.position.y + half_screen.y - 100
@@ -75,31 +113,77 @@ bool EnemyScript::spawn_enemy(const SpawnEnemyEvent & e) {
= {cam_transform.position.x + camera.viewport_size.x / 2 + 100, random_height};
transform.position = spawn_location;
ai_component.path.clear();
- ai_component.make_oval_path(10, 10, vec2 {x_value, random_height}, 1.5708, true);
+ ai_component.make_oval_path(10, 30, vec2 {x_value, random_height}, 1.5708, true);
ai_component.active = true;
this->last_fired = std::chrono::steady_clock::now();
+
return false;
}
+void EnemyScript::set_hit_blink(bool status) {
+ RefVector<Sprite> sprites = this->get_components<Sprite>();
+ for (Sprite & sprite : sprites) {
+ if (status) {
+ sprite.data.color = Color::RED;
+ continue;
+ }
+ sprite.data.color = Color::WHITE;
+ }
+}
+
bool EnemyScript::on_collide(const CollisionEvent & e) {
+ if (!this->alive) return false;
if (e.info.other.metadata.tag == "player_bullet") {
- this->despawn_enemy();
+ this->health--;
+ last_hit = std::chrono::steady_clock::now();
+ //Sprite& sprite;
+ set_hit_blink(true);
+ if (health <= 0) {
+ this->death();
+ }
}
- Animator & body_animator = this->get_components<Animator>().front();
- body_animator.data.col = 2;
+
//body_animator.play();
- BehaviorScript & enemy_script = this->get_component<BehaviorScript>();
- enemy_script.active = false;
+
return false;
}
+void EnemyScript::death() {
+
+ Rigidbody & rb = this->get_component<Rigidbody>();
+ Transform & tr = this->get_component<Transform>();
+ RefVector<Animator> animators = this->get_components<Animator>();
+ for (Animator & anim : animators) {
+ anim.active = false;
+ anim.set_anim(3);
+ }
+ RefVector<Sprite> sprites = this->get_components<Sprite>();
+ for (Sprite & sprite : sprites) {
+ sprite.data.position_offset.x = 15;
+ }
+ rb.data.linear_velocity_coefficient = {0.5, 1};
+ rb.data.collision_layers = {COLL_LAY_BOT_TOP};
+ rb.data.collision_layer = 0;
+
+ rb.data.gravity_scale = 1;
+ tr.rotation = 90;
+ AI & ai = this->get_component<AI>();
+ ai.active = false;
+ this->alive = false;
+ AI & ai_component = this->get_component<AI>();
+ ai_component.active = false;
+}
void EnemyScript::despawn_enemy() {
Transform & transform = this->get_component<Transform>();
+ Rigidbody & rb = this->get_component<Rigidbody>();
+ rb.data.gravity_scale = 0;
+ rb.data.linear_velocity = {0, 0};
+ transform.rotation = 0;
transform.position = ENEMY_POOL_LOCATION;
- AI & ai_component = this->get_component<AI>();
- // Rigidbody& enemy_body
- ai_component.active = false;
+
+ this->spawned = false;
}
-void EnemyScript::shoot(const vec2 & location, float angle) {
+
+void EnemyScript::shoot(const vec2 & location) {
RefVector<Transform> bullet_transforms
= this->get_components_by_tag<Transform>("enemy_bullet");
diff --git a/game/enemy/EnemyScript.h b/game/enemy/EnemyScript.h
index 42ecac4..be71a78 100644
--- a/game/enemy/EnemyScript.h
+++ b/game/enemy/EnemyScript.h
@@ -13,19 +13,25 @@ public:
EnemyScript();
void init() override;
void fixed_update(crepe::duration_t dt) override;
- void shoot(const crepe::vec2 & position, float angle);
+ void shoot(const crepe::vec2 & position);
bool on_collide(const crepe::CollisionEvent & collisionData);
void despawn_enemy();
bool spawn_enemy(const SpawnEnemyEvent & e);
+ void death();
+ void set_hit_blink(bool status);
private:
std::random_device rd;
std::default_random_engine engine;
bool alive = false;
+ bool spawned = false;
float speed = 50;
- const float MIN_SPEED = 10;
- const float MAX_SPEED = 130;
- const float MAX_DISTANCE = 100;
+ int health = 2;
+ const float MIN_SPEED = 20;
+ const float MAX_SPEED = 150;
+ const float MAX_DISTANCE = 200;
std::chrono::time_point<std::chrono::steady_clock> last_fired;
+ std::chrono::time_point<std::chrono::steady_clock> last_hit;
std::chrono::duration<float> shot_delay = std::chrono::duration<float>(0);
+ std::chrono::duration<float> blink_time = std::chrono::duration<float>(0.1);
};
diff --git a/game/enemy/EnemySubScene.cpp b/game/enemy/EnemySubScene.cpp
index 607b9a9..c6aecec 100644
--- a/game/enemy/EnemySubScene.cpp
+++ b/game/enemy/EnemySubScene.cpp
@@ -31,8 +31,9 @@ int EnemySubScene::create(Scene & scn, int enemy_counter) {
.collision_layer = COLL_LAY_ENEMY,
});
+ // normal body
Asset enemy_body_asset {"asset/workers/worker2Body.png"};
- enemy.add_component<BoxCollider>(vec2(50, 50));
+ enemy.add_component<BoxCollider>(vec2(40, 60));
Sprite & enemy_body_sprite = enemy.add_component<Sprite>(
enemy_body_asset,
Sprite::Data {
@@ -52,7 +53,7 @@ int EnemySubScene::create(Scene & scn, int enemy_counter) {
}
);
body_animator.pause();
- enemy.add_component<BoxCollider>(vec2(40, 60), vec2(-20, 0));
+
Asset enemy_head_asset {"asset/workers/worker2Head.png"};
Sprite & enemy_head_sprite = enemy.add_component<Sprite>(
enemy_head_asset,
@@ -71,7 +72,9 @@ int EnemySubScene::create(Scene & scn, int enemy_counter) {
.looping = true,
}
);
- enemy.add_component<CircleCollider>(25, vec2(0, -20));
+
+ //jetpack
+ //enemy.add_component<CircleCollider>(25, vec2(0, -20));
Asset enemy_jetpack_asset {"asset/barry/jetpackDefault.png"};
Sprite & enemy_jetpack_sprite = enemy.add_component<Sprite>(
enemy_jetpack_asset,
@@ -91,11 +94,24 @@ int EnemySubScene::create(Scene & scn, int enemy_counter) {
.looping = true,
}
);
+ //gun
+ Asset enemy_pistol_asset {"asset/workers/gun.png"};
+ Sprite & enemy_pistol_sprite = enemy.add_component<Sprite>(
+ enemy_pistol_asset,
+ Sprite::Data {
+ .flip = {false, false},
+ .sorting_in_layer = SORT_IN_LAY_WORKERS_FRONT,
+ .order_in_layer = 2,
+ .size = vec2(0, 20),
+ .position_offset = vec2(-20, 0),
+ }
+ );
enemy.add_component<AudioSource>(Asset("asset/sfx/bike_gun_2.ogg")).volume = 0.1;
AI & ai_component = enemy.add_component<AI>(3000);
ai_component.path_follow_on();
+ ai_component.active = false;
BehaviorScript & enemy_script
= enemy.add_component<BehaviorScript>().set_script<EnemyScript>();
- enemy_script.active = false;
+ //enemy_script.active = false;
return enemy_counter;
}
diff --git a/game/hud/HudScript.cpp b/game/hud/HudScript.cpp
index 8f77706..e4aeae7 100644
--- a/game/hud/HudScript.cpp
+++ b/game/hud/HudScript.cpp
@@ -3,6 +3,8 @@
#include "../Config.h"
#include "../Events.h"
+#include "api/KeyCodes.h"
+#include "menus/endgame/EndGameSubScript.h"
#include <climits>
@@ -36,7 +38,7 @@ void HudScript::init() {
}
bool HudScript::toggle_fps(crepe::KeyPressEvent ev) {
- if (ev.key != Keycode::END) return false;
+ if (ev.key != Keycode::D1) return false;
Text & txt_fps = this->get_components_by_name<Text>(HUD_FPS).front();
this->show_fps = !this->show_fps;
if (this->show_fps) {
@@ -91,5 +93,6 @@ bool HudScript::save() {
SaveManager & savemgr = this->get_save_manager();
savemgr.set(TOTAL_COINS_RUN, this->coin_amount);
savemgr.set(DISTANCE_RUN, this->distance_st);
+ this->trigger_event<ShowScoreEvent>();
return false;
}
diff --git a/game/main.cpp b/game/main.cpp
index 14eec99..95cb35c 100644
--- a/game/main.cpp
+++ b/game/main.cpp
@@ -3,7 +3,7 @@
#include <crepe/api/Engine.h>
#include <crepe/api/Script.h>
-#include "Config.h"
+#include "EngineConfig.h"
#include "GameScene.h"
#include "PreviewScene.h"
#include "menus/mainmenu/MainMenuScene.h"
@@ -17,6 +17,7 @@ int main() {
Config::get_instance() = ENGINE_CONFIG;
Engine gameloop;
+
gameloop.add_scene<MainMenuScene>();
gameloop.add_scene<ShopMenuScene>();
gameloop.add_scene<GameScene>();
diff --git a/game/menus/ButtonNextMainMenuSubScript.cpp b/game/menus/ButtonNextMainMenuSubScript.cpp
index e03a34a..63a2777 100644
--- a/game/menus/ButtonNextMainMenuSubScript.cpp
+++ b/game/menus/ButtonNextMainMenuSubScript.cpp
@@ -1,4 +1,5 @@
#include "ButtonNextMainMenuSubScript.h"
+#include "ButtonReplaySubScript.h"
#include "MenusConfig.h"
#include "ValueBroker.h"
@@ -27,6 +28,7 @@ bool ButtonNextMainMenuSubScript::on_button_press(const ButtonPressEvent & e) {
audio.stop();
}
+ this->trigger_event<DeleteRecordingEvent>();
SaveManager & savemgr = this->get_save_manager();
ValueBroker<int> coins = savemgr.get<int>(TOTAL_COINS_RUN, 0);
diff --git a/game/menus/ButtonReplaySubScript.cpp b/game/menus/ButtonReplaySubScript.cpp
index 9308350..01cccbf 100644
--- a/game/menus/ButtonReplaySubScript.cpp
+++ b/game/menus/ButtonReplaySubScript.cpp
@@ -1,4 +1,5 @@
#include "ButtonReplaySubScript.h"
+#include "Config.h"
#include "MenusConfig.h"
#include "../Events.h"
@@ -16,15 +17,27 @@ void ButtonReplaySubScript::init() {
this->subscribe<EndGameEvent>([this](const EndGameEvent & e) {
return this->set_recording();
});
+ this->subscribe<DeleteRecordingEvent>([this](const DeleteRecordingEvent & e) {
+ return this->delete_recording();
+ });
+ if (DISABLE_REPLAY) return;
replay.record_start();
}
bool ButtonReplaySubScript::on_button_press(const ButtonPressEvent & e) {
+ if (DISABLE_REPLAY) return false;
replay.play(this->recording);
return false;
}
bool ButtonReplaySubScript::set_recording() {
+ if (DISABLE_REPLAY) return false;
this->recording = replay.record_end();
return false;
}
+
+bool ButtonReplaySubScript::delete_recording() {
+ if (DISABLE_REPLAY) return false;
+ replay.release(this->recording);
+ return false;
+}
diff --git a/game/menus/ButtonReplaySubScript.h b/game/menus/ButtonReplaySubScript.h
index bfc684d..3eb8aa9 100644
--- a/game/menus/ButtonReplaySubScript.h
+++ b/game/menus/ButtonReplaySubScript.h
@@ -4,6 +4,8 @@
#include <crepe/api/Script.h>
+struct DeleteRecordingEvent : public crepe::Event {};
+
class ButtonReplaySubScript : public IButtonScript {
public:
void init() override;
@@ -12,6 +14,7 @@ public:
private:
crepe::recording_t recording = 0;
bool set_recording();
+ bool delete_recording();
protected:
bool transition = false;
diff --git a/game/menus/ButtonSubScene.cpp b/game/menus/ButtonSubScene.cpp
index 30646f1..1fe6b03 100644
--- a/game/menus/ButtonSubScene.cpp
+++ b/game/menus/ButtonSubScene.cpp
@@ -7,10 +7,16 @@
#include "IButtonScript.h"
#include "MenusConfig.h"
+#include "../preview/PreviewReplaySubScript.h"
+#include "../preview/PreviewStartRecSubScript.h"
+#include "../preview/PreviewStopRecSubScript.h"
+#include "api/Asset.h"
#include "mainmenu/ButtonTransitionPreviewSubScript.h"
#include "../Config.h"
#include "mainmenu/CreditsSubScript.h"
+#include "menus/shop/ButtonBuySelectBubbleScript.h"
+#include "menus/shop/ButtonBuySelectBulletScript.h"
#include <crepe/api/BehaviorScript.h>
#include <crepe/api/Button.h>
@@ -72,6 +78,25 @@ void ButtonSubScene::set_script(crepe::GameObject & button_object, const Data &
button_object.add_component<BehaviorScript>()
.set_script<ButtonShowCreditsSubScript>();
break;
+ case ScriptSelect::PREVIEW_REPLAY:
+ button_object.add_component<BehaviorScript>().set_script<PreviewReplaySubScript>();
+ break;
+ case ScriptSelect::PREVIEW_START:
+ button_object.add_component<BehaviorScript>().set_script<PreviewStartRecSubScript>(
+ );
+ break;
+ case ScriptSelect::PREVIEW_STOP:
+ button_object.add_component<BehaviorScript>().set_script<PreviewStopRecSubScript>(
+ );
+ break;
+ case ScriptSelect::SHOP_BULLET:
+ button_object.add_component<BehaviorScript>()
+ .set_script<ButtonBuySelectBulletScript>();
+ break;
+ case ScriptSelect::SHOP_BUBBLE:
+ button_object.add_component<BehaviorScript>()
+ .set_script<ButtonBuySelectBubbleScript>();
+ break;
case ScriptSelect::NONE:
button_object.add_component<BehaviorScript>().set_script<IButtonScript>();
break;
@@ -196,8 +221,31 @@ void ButtonSubScene::next_btn_overlay(crepe::GameObject & button_object, const D
void ButtonSubScene::btn_color_side(
crepe::GameObject & button_object, const vec2 & offset, const Data & data
) {
+ Asset * selected;
+ Asset blue = Asset("asset/ui/buttonSmallBlue.png");
+ Asset orange = Asset("asset/ui/buttonSmallOrange.png");
+ Asset purple = Asset("asset/ui/buttonSmallPurple.png");
+ Asset yellow = Asset("asset/ui/buttonSmallYellow.png");
+ switch (data.btn_side_color) {
+ case ButtonSideColor::BLUE:
+ selected = &blue;
+ break;
+ case ButtonSideColor::ORANGE:
+ selected = &orange;
+ break;
+ case ButtonSideColor::PURPLE:
+ selected = &purple;
+ break;
+ case ButtonSideColor::YELLOW:
+ selected = &yellow;
+ break;
+ case ButtonSideColor::NONE:
+ selected = &blue;
+ break;
+ }
+
button_object.add_component<Sprite>(
- Asset("asset/ui/buttonSmallBlue.png"),
+ *selected,
Sprite::Data {
.sorting_in_layer = STARTING_SORTING_IN_LAYER + 2 + data.sorting_layer_offset,
.size = SIDE_PANEL_SIZE,
@@ -206,7 +254,7 @@ void ButtonSubScene::btn_color_side(
}
);
button_object.add_component<Sprite>(
- Asset("asset/ui/buttonSmallBlue.png"),
+ *selected,
Sprite::Data {
.flip = {true, false},
.sorting_in_layer = STARTING_SORTING_IN_LAYER + 2 + data.sorting_layer_offset,
diff --git a/game/menus/ButtonSubScene.h b/game/menus/ButtonSubScene.h
index 74f9464..d4c7223 100644
--- a/game/menus/ButtonSubScene.h
+++ b/game/menus/ButtonSubScene.h
@@ -19,6 +19,11 @@ public:
REPLAY,
CREDITS_SHOW,
CREDITS_BACK,
+ PREVIEW_START,
+ PREVIEW_STOP,
+ PREVIEW_REPLAY,
+ SHOP_BULLET,
+ SHOP_BUBBLE,
NONE,
};
//icon enum
@@ -33,6 +38,14 @@ public:
NEXT,
LARGE,
};
+
+ enum class ButtonSideColor {
+ BLUE,
+ ORANGE,
+ PURPLE,
+ YELLOW,
+ NONE,
+ };
//data struct
struct Data {
const std::string & text = "NODATA";
@@ -48,6 +61,7 @@ public:
const bool color_side = true;
const std::string & tag = "";
const int sorting_layer_offset = 0;
+ const ButtonSideColor btn_side_color = ButtonSideColor::NONE;
};
public:
diff --git a/game/menus/endgame/EndGameSubScene.cpp b/game/menus/endgame/EndGameSubScene.cpp
index a6f8b25..b33072a 100644
--- a/game/menus/endgame/EndGameSubScene.cpp
+++ b/game/menus/endgame/EndGameSubScene.cpp
@@ -47,6 +47,51 @@ void EndGameSubScene::create(Scene & scn) {
vec2 {0, -207} + FONTOFFSET, TITEL_STRING
);
+ const float Y_SPACING = 50;
+ const float Y_OFFSET = -100;
+
+ // Gold gathered
+ const string GOLD_STRING = "gold:0";
+ GameObject gold = scn.new_object("gold_endgame", TAG);
+ crepe::vec2 size_gold = {200, (200.0f / GOLD_STRING.size()) * 2};
+ gold.add_component<Text>(
+ size_gold, FONT,
+ Text::Data {
+ .world_space = false,
+ .text_color = Color::GOLD,
+ },
+ vec2 {0, Y_OFFSET} + FONTOFFSET, GOLD_STRING
+ );
+
+ // Distance
+ const string DISTANCE_STRING = "0M";
+ GameObject distance = scn.new_object("distance_endgame", TAG);
+ crepe::vec2 size_distance = {200, (200.0f / DISTANCE_STRING.size()) * 2};
+ distance.add_component<Text>(
+ size_distance, FONT,
+ Text::Data {
+ .world_space = false,
+ .text_color = Color::WHITE,
+ },
+ vec2 {0, Y_SPACING + Y_OFFSET} + FONTOFFSET, DISTANCE_STRING
+ );
+
+ // Highscore
+ const string HIGHSCORE_STRING = "NEW HIGHSCORE";
+ GameObject highscore = scn.new_object("highscore_endgame", "highscore_tag_end");
+ crepe::vec2 size_highscore = {200, (200.0f / HIGHSCORE_STRING.size()) * 2};
+ highscore
+ .add_component<Text>(
+ size_highscore, FONT,
+ Text::Data {
+ .world_space = false,
+ .text_color = Color::WHITE,
+ },
+ vec2 {0, Y_SPACING * 2 + Y_OFFSET} + FONTOFFSET, HIGHSCORE_STRING
+ )
+ .active
+ = false;
+
// Buttons
vec2 button_position = {190, 190};
ButtonSubScene button;
diff --git a/game/menus/endgame/EndGameSubScript.cpp b/game/menus/endgame/EndGameSubScript.cpp
index 6edfe7b..6793f3e 100644
--- a/game/menus/endgame/EndGameSubScript.cpp
+++ b/game/menus/endgame/EndGameSubScript.cpp
@@ -1,8 +1,11 @@
#include "EndGameSubScript.h"
+#include "../../Config.h"
#include "../../Events.h"
#include "../ButtonReplaySubScript.h"
#include "../IFloatingWindowScript.h"
+#include "ValueBroker.h"
+#include "manager/SaveManager.h"
#include <string>
@@ -21,6 +24,9 @@ void EndGameSubScript::init() {
this->subscribe<EndGameEvent>([this](const EndGameEvent e) {
return this->reset_timescale();
});
+ this->subscribe<ShowScoreEvent>([this](const ShowScoreEvent e) {
+ return this->showscore();
+ });
}
bool EndGameSubScript::disable_all() {
@@ -53,3 +59,43 @@ bool EndGameSubScript::reset_timescale() {
this->get_loop_timer().set_time_scale(1);
return false;
}
+
+bool EndGameSubScript::showscore() {
+ // Gather text
+ Text & coins_text = this->get_components_by_name<Text>("gold_endgame").front().get();
+ Text & distance_text
+ = this->get_components_by_name<Text>("distance_endgame").front().get();
+ Text & highscore_text
+ = this->get_components_by_name<Text>("highscore_endgame").front().get();
+ highscore_text.active = false;
+
+ // Gather saved data
+ SaveManager & savemgr = this->get_save_manager();
+ ValueBroker<std::string> coins = savemgr.get<std::string>(TOTAL_COINS_RUN, "0");
+ ValueBroker<std::string> distance = savemgr.get<std::string>(DISTANCE_RUN, "0");
+ int distance_run = savemgr.get<int>(DISTANCE_RUN, 0).get();
+ int distance_game = savemgr.get<int>(DISTANCE_GAME, 0).get();
+
+ // Show highscore
+ if (distance_run > distance_game) highscore_text.active = true;
+
+ const float CHAR_SIZE_DIS = 20;
+ // Show distance
+ std::string distance_string = "DISTANCE:" + distance.get();
+ distance_text.text = distance_string;
+ crepe::vec2 size_distance
+ = {CHAR_SIZE_DIS * distance_string.size(),
+ (CHAR_SIZE_DIS * distance_string.size() / distance_string.size()) * 2};
+ distance_text.dimensions = size_distance;
+
+ const float CHAR_SIZE_COIN = 16;
+ // Show coins
+ std::string coins_string = "Coins:" + coins.get();
+ coins_text.text = coins_string;
+ crepe::vec2 size_coins
+ = {CHAR_SIZE_COIN * coins_string.size(),
+ (CHAR_SIZE_COIN * coins_string.size() / coins_string.size()) * 2};
+ coins_text.dimensions = size_coins;
+
+ return false;
+}
diff --git a/game/menus/endgame/EndGameSubScript.h b/game/menus/endgame/EndGameSubScript.h
index 62a2f0c..c25f6ca 100644
--- a/game/menus/endgame/EndGameSubScript.h
+++ b/game/menus/endgame/EndGameSubScript.h
@@ -5,6 +5,8 @@
#include <crepe/api/Event.h>
#include <crepe/api/Script.h>
+struct ShowScoreEvent : public crepe::Event {};
+
class EndGameSubScript : public IFloatingWindowScript {
public:
EndGameSubScript(const std::string & tag);
@@ -12,4 +14,5 @@ public:
bool disable_all();
bool enable_all();
bool reset_timescale();
+ bool showscore();
};
diff --git a/game/menus/mainmenu/MainMenuScene.cpp b/game/menus/mainmenu/MainMenuScene.cpp
index fba90ac..c5d2030 100644
--- a/game/menus/mainmenu/MainMenuScene.cpp
+++ b/game/menus/mainmenu/MainMenuScene.cpp
@@ -2,6 +2,7 @@
#include "MainMenuScene.h"
#include "CreditsSubScene.h"
#include "MainMenuConfig.h"
+#include "QuitScript.h"
#include "TransitionStartSubScript.h"
#include "../ButtonSubScene.h"
@@ -29,10 +30,11 @@ void MainMenuScene::load_scene() {
camera_object.add_component<Camera>(
ivec2(990, 720), vec2(1100, 800),
Camera::Data {
- .bg_color = Color::RED,
+ .bg_color = Color::BLACK,
}
);
camera_object.add_component<BehaviorScript>().set_script<TransitionStartSubScript>();
+ camera_object.add_component<BehaviorScript>().set_script<QuitScript>();
//Button menu
GameObject menu_button = this->new_object(MENU_BUTTON_NAME, MENU_BUTTON_NAME, MENU_OFFSET);
@@ -55,6 +57,7 @@ void MainMenuScene::load_scene() {
.text_width = 200,
.position = pos_btn,
.script_type = ButtonSubScene::ScriptSelect::PREVIEW,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::PURPLE,
}
);
@@ -70,6 +73,7 @@ void MainMenuScene::load_scene() {
.icon_type = ButtonSubScene::IconSelect::SHOP,
.position = pos_btn,
.script_type = ButtonSubScene::ScriptSelect::SHOP,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::ORANGE,
}
);
@@ -83,6 +87,7 @@ void MainMenuScene::load_scene() {
.text_width = 200,
.position = pos_btn,
.script_type = ButtonSubScene::ScriptSelect::CREDITS_SHOW,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::BLUE,
}
);
diff --git a/game/menus/shop/ButtonBuySelectBubbleScript.cpp b/game/menus/shop/ButtonBuySelectBubbleScript.cpp
new file mode 100644
index 0000000..741afde
--- /dev/null
+++ b/game/menus/shop/ButtonBuySelectBubbleScript.cpp
@@ -0,0 +1,34 @@
+#include "ButtonBuySelectBubbleScript.h"
+#include "../MenusConfig.h"
+#include "Config.h"
+#include "ValueBroker.h"
+#include "manager/SaveManager.h"
+#include "menus/shop/Shopconfig.h"
+
+using namespace crepe;
+using namespace std;
+
+void ButtonBuySelectBubbleScript::init() {
+ IButtonScript::init();
+ this->subscribe<ButtonPressEvent>([this](const ButtonPressEvent & e) {
+ return this->on_button_press(e);
+ });
+}
+
+bool ButtonBuySelectBubbleScript::on_button_press(const ButtonPressEvent & e) {
+ SaveManager & save = this->get_save_manager();
+ ValueBroker<int> buy_bullet = save.get<int>(BUY_BUBBLE_SAVE, 0);
+ if (!buy_bullet.get()) {
+ ValueBroker<int> coins = save.get<int>(TOTAL_COINS_GAME, 0);
+ if (coins.get() >= 1000) {
+ int coin = coins.get();
+ coin -= 1000;
+ save.set(TOTAL_COINS_GAME, coin);
+ save.set(BUY_BUBBLE_SAVE, 1);
+ }
+ } else {
+ save.set(JETPACK_PARTICLES, 1);
+ }
+ this->trigger_event<ShopUpdate>();
+ return false;
+}
diff --git a/game/menus/shop/ButtonBuySelectBubbleScript.h b/game/menus/shop/ButtonBuySelectBubbleScript.h
new file mode 100644
index 0000000..ce276ef
--- /dev/null
+++ b/game/menus/shop/ButtonBuySelectBubbleScript.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "../IButtonScript.h"
+
+#include <crepe/api/Script.h>
+
+class ButtonBuySelectBubbleScript : public IButtonScript {
+public:
+ void init() override;
+ bool on_button_press(const crepe::ButtonPressEvent & e);
+
+protected:
+ bool transition = false;
+};
diff --git a/game/menus/shop/ButtonBuySelectBulletScript.cpp b/game/menus/shop/ButtonBuySelectBulletScript.cpp
new file mode 100644
index 0000000..d30849c
--- /dev/null
+++ b/game/menus/shop/ButtonBuySelectBulletScript.cpp
@@ -0,0 +1,34 @@
+#include "ButtonBuySelectBulletScript.h"
+#include "../MenusConfig.h"
+#include "Config.h"
+#include "ValueBroker.h"
+#include "manager/SaveManager.h"
+#include "menus/shop/Shopconfig.h"
+
+using namespace crepe;
+using namespace std;
+
+void ButtonBuySelectBulletScript::init() {
+ IButtonScript::init();
+ this->subscribe<ButtonPressEvent>([this](const ButtonPressEvent & e) {
+ return this->on_button_press(e);
+ });
+}
+
+bool ButtonBuySelectBulletScript::on_button_press(const ButtonPressEvent & e) {
+ SaveManager & save = this->get_save_manager();
+ ValueBroker<int> buy_bullet = save.get<int>(BUY_BULLET_SAVE, 0);
+ if (!buy_bullet.get()) {
+ ValueBroker<int> coins = save.get<int>(TOTAL_COINS_GAME, 0);
+ if (coins.get() >= 0) {
+ int coin = coins.get();
+ coin -= 0;
+ save.set(TOTAL_COINS_GAME, coin);
+ save.set(BUY_BULLET_SAVE, 1);
+ }
+ } else {
+ save.set(JETPACK_PARTICLES, 0);
+ }
+ this->trigger_event<ShopUpdate>();
+ return false;
+}
diff --git a/game/menus/shop/ButtonBuySelectBulletScript.h b/game/menus/shop/ButtonBuySelectBulletScript.h
new file mode 100644
index 0000000..86de0ac
--- /dev/null
+++ b/game/menus/shop/ButtonBuySelectBulletScript.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "../IButtonScript.h"
+
+#include <crepe/api/Script.h>
+
+class ButtonBuySelectBulletScript : public IButtonScript {
+public:
+ void init() override;
+ bool on_button_press(const crepe::ButtonPressEvent & e);
+
+protected:
+ bool transition = false;
+};
diff --git a/game/menus/shop/ShopLoadScript.cpp b/game/menus/shop/ShopLoadScript.cpp
new file mode 100644
index 0000000..a545fe2
--- /dev/null
+++ b/game/menus/shop/ShopLoadScript.cpp
@@ -0,0 +1,126 @@
+#include "ShopLoadScript.h"
+#include "Shopconfig.h"
+#include "api/Button.h"
+#include "api/Sprite.h"
+#include "api/Text.h"
+#include "manager/SaveManager.h"
+#include <crepe/ValueBroker.h>
+
+using namespace crepe;
+using namespace std;
+
+void ShopLoadScript::init() {
+ this->update();
+ this->subscribe<ShopUpdate>([this](const ShopUpdate e) { return this->update(); });
+}
+
+bool ShopLoadScript::update() {
+ SaveManager & save = this->get_save_manager();
+ ValueBroker<int> buy_bullet = save.get<int>(BUY_BULLET_SAVE, 0);
+ ValueBroker<int> buy_bubble = save.get<int>(BUY_BUBBLE_SAVE, 0);
+
+ if (buy_bullet.get()) {
+ auto sprites = this->get_components_by_tag<Sprite>(BUY_BULLET);
+ for (auto sprite : sprites) {
+ sprite.get().active = false;
+ }
+ auto buttons = this->get_components_by_tag<Button>(BUY_BULLET);
+ for (auto btn : buttons) {
+ btn.get().active = false;
+ }
+ auto texts = this->get_components_by_tag<Text>(BUY_BULLET);
+ for (auto txt : texts) {
+ txt.get().active = false;
+ }
+ auto sprites1 = this->get_components_by_tag<Sprite>(SELECT_BULLET);
+ for (auto sprite : sprites1) {
+ sprite.get().active = true;
+ }
+ auto buttons1 = this->get_components_by_tag<Button>(SELECT_BULLET);
+ for (auto btn : buttons1) {
+ btn.get().active = true;
+ }
+ auto texts1 = this->get_components_by_tag<Text>(SELECT_BULLET);
+ for (auto txt : texts1) {
+ txt.get().active = true;
+ }
+ } else {
+ auto sprites = this->get_components_by_tag<Sprite>(SELECT_BULLET);
+ for (auto sprite : sprites) {
+ sprite.get().active = false;
+ }
+ auto buttons = this->get_components_by_tag<Button>(SELECT_BULLET);
+ for (auto btn : buttons) {
+ btn.get().active = false;
+ }
+ auto texts = this->get_components_by_tag<Text>(SELECT_BULLET);
+ for (auto txt : texts) {
+ txt.get().active = false;
+ }
+ auto sprites1 = this->get_components_by_tag<Sprite>(BUY_BULLET);
+ for (auto sprite : sprites1) {
+ sprite.get().active = true;
+ }
+ auto buttons1 = this->get_components_by_tag<Button>(BUY_BULLET);
+ for (auto btn : buttons1) {
+ btn.get().active = true;
+ }
+ auto texts1 = this->get_components_by_tag<Text>(BUY_BULLET);
+ for (auto txt : texts1) {
+ txt.get().active = true;
+ }
+ }
+
+ if (buy_bubble.get()) {
+ auto sprites = this->get_components_by_tag<Sprite>(BUY_BUBBLE);
+ for (auto sprite : sprites) {
+ sprite.get().active = false;
+ }
+ auto buttons = this->get_components_by_tag<Button>(BUY_BUBBLE);
+ for (auto btn : buttons) {
+ btn.get().active = false;
+ }
+ auto texts = this->get_components_by_tag<Text>(BUY_BUBBLE);
+ for (auto txt : texts) {
+ txt.get().active = false;
+ }
+ auto sprites1 = this->get_components_by_tag<Sprite>(SELECT_BUBBLE);
+ for (auto sprite : sprites1) {
+ sprite.get().active = true;
+ }
+ auto buttons1 = this->get_components_by_tag<Button>(SELECT_BUBBLE);
+ for (auto btn : buttons1) {
+ btn.get().active = true;
+ }
+ auto texts1 = this->get_components_by_tag<Text>(SELECT_BUBBLE);
+ for (auto txt : texts1) {
+ txt.get().active = true;
+ }
+ } else {
+ auto sprites = this->get_components_by_tag<Sprite>(SELECT_BUBBLE);
+ for (auto sprite : sprites) {
+ sprite.get().active = false;
+ }
+ auto buttons = this->get_components_by_tag<Button>(SELECT_BUBBLE);
+ for (auto btn : buttons) {
+ btn.get().active = false;
+ }
+ auto texts = this->get_components_by_tag<Text>(SELECT_BUBBLE);
+ for (auto txt : texts) {
+ txt.get().active = false;
+ }
+ auto sprites1 = this->get_components_by_tag<Sprite>(BUY_BUBBLE);
+ for (auto sprite : sprites1) {
+ sprite.get().active = true;
+ }
+ auto buttons1 = this->get_components_by_tag<Button>(BUY_BUBBLE);
+ for (auto btn : buttons1) {
+ btn.get().active = true;
+ }
+ auto texts1 = this->get_components_by_tag<Text>(BUY_BUBBLE);
+ for (auto txt : texts1) {
+ txt.get().active = true;
+ }
+ }
+ return false;
+}
diff --git a/game/menus/shop/ShopLoadScript.h b/game/menus/shop/ShopLoadScript.h
new file mode 100644
index 0000000..b17bf1c
--- /dev/null
+++ b/game/menus/shop/ShopLoadScript.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <crepe/api/Script.h>
+#include <crepe/manager/SaveManager.h>
+
+class ShopLoadScript : public crepe::Script {
+public:
+ void init() override;
+ bool update();
+};
diff --git a/game/menus/shop/ShopMenuScene.cpp b/game/menus/shop/ShopMenuScene.cpp
index d1ea81d..4975a95 100644
--- a/game/menus/shop/ShopMenuScene.cpp
+++ b/game/menus/shop/ShopMenuScene.cpp
@@ -2,11 +2,14 @@
#include "ShopMenuScene.h"
#include "../../Config.h"
-#include "../BannerSubScene.h"
#include "../ButtonSubScene.h"
#include "../MenusConfig.h"
+#include "api/BehaviorScript.h"
+#include "menus/BannerSubScene.h"
+#include "menus/shop/ShopLoadScript.h"
#include "types.h"
+#include "Shopconfig.h"
#include <crepe/api/Camera.h>
#include <crepe/api/Sprite.h>
#include <crepe/api/Text.h>
@@ -40,6 +43,7 @@ void ShopMenuScene::load_scene() {
.position_offset {0},
}
);
+ menu_background.add_component<BehaviorScript>().set_script<ShopLoadScript>();
ButtonSubScene button;
button.create(
@@ -50,26 +54,74 @@ void ShopMenuScene::load_scene() {
.position = {-400, -350},
.script_type = ButtonSubScene::ScriptSelect::MAINMENU,
.button_type = ButtonSubScene::ButtonSelect::BACK,
- .scale = 0.8
+ .scale = 0.8,
+ .sorting_layer_offset = 1,
}
);
+ const float CHAR_SIZE = 16;
+ const float CHAR_SIZE_COIN = 16;
+ crepe::vec2 size;
+
GameObject shop_item_bullet = this->new_object("bullet", "shop_item", vec2(-100, 0));
shop_item_bullet.add_component<Sprite>(
Asset("asset/other_effects/effect_rocketmgshell_TVOS.png"),
Sprite::Data {
.sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
- .size = {0, 100},
+ .size = {0, 20},
+ .angle_offset = 30,
.position_offset = {0, 0},
}
);
+ shop_item_bullet.add_component<Sprite>(
+ Asset("asset/other_effects/effect_rocketmgshell_TVOS.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 20},
+ .angle_offset = 10,
+ .position_offset = {-10, -30},
+ }
+ );
+ shop_item_bullet.add_component<Sprite>(
+ Asset("asset/other_effects/effect_rocketmgshell_TVOS.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 20},
+ .angle_offset = -10,
+ .position_offset = {-40, 30},
+ }
+ );
+ shop_item_bullet.add_component<Sprite>(
+ Asset("asset/other_effects/effect_rocketmgshell_TVOS.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 20},
+ .angle_offset = 0,
+ .position_offset = {10, 15},
+ }
+ );
+ shop_item_bullet.add_component<Sprite>(
+ Asset("asset/other_effects/effect_rocketmgshell_TVOS.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 20},
+ .angle_offset = -5,
+ .position_offset = {45, -5},
+ }
+ );
+
+ const string BULLETS_STRING = "BULLETS";
+ size
+ = {CHAR_SIZE * BULLETS_STRING.size(),
+ (CHAR_SIZE * BULLETS_STRING.size() / BULLETS_STRING.size()) * 2};
+
shop_item_bullet.add_component<Text>(
- vec2 {100, 50}, FONT,
+ size, FONT,
Text::Data {
.world_space = true,
.text_color = Color::WHITE,
},
- vec2 {0, -75}, "BULLETS"
+ vec2 {0, -75}, BULLETS_STRING
);
shop_item_bullet.add_component<Sprite>(
Asset("asset/ui/buttonCoinsSmall.png"),
@@ -79,13 +131,18 @@ void ShopMenuScene::load_scene() {
.position_offset = {25, 75},
}
);
+
+ const string BULLETS_GOLD_STRING = "0";
+ size
+ = {CHAR_SIZE_COIN * BULLETS_GOLD_STRING.size(),
+ (CHAR_SIZE_COIN * BULLETS_GOLD_STRING.size() / BULLETS_GOLD_STRING.size()) * 2};
shop_item_bullet.add_component<Text>(
- vec2 {37.5, 37.5}, FONT,
+ size, FONT,
Text::Data {
.world_space = true,
.text_color = Color::GOLD,
},
- vec2 {-25, 75}, "0"
+ vec2 {-5, 75}, BULLETS_GOLD_STRING
);
GameObject shop_item_bubble = this->new_object("bubble", "shop_item", vec2(100, 0));
@@ -93,17 +150,94 @@ void ShopMenuScene::load_scene() {
Asset("asset/background/aquarium/bubble.png"),
Sprite::Data {
.sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
- .size = {0, 100},
+ .size = {0, 10},
.position_offset = {0, 0},
}
);
+ shop_item_bubble.add_component<Sprite>(
+ Asset("asset/background/aquarium/bubble.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 10},
+ .position_offset = {-50, -20},
+ }
+ );
+ shop_item_bubble.add_component<Sprite>(
+ Asset("asset/background/aquarium/bubble.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 20},
+ .position_offset = {45, -40},
+ }
+ );
+ shop_item_bubble.add_component<Sprite>(
+ Asset("asset/background/aquarium/bubble.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 20},
+ .position_offset = {-20, 40},
+ }
+ );
+ shop_item_bubble.add_component<Sprite>(
+ Asset("asset/background/aquarium/bubble.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 15},
+ .position_offset = {15, -25},
+ }
+ );
+ shop_item_bubble.add_component<Sprite>(
+ Asset("asset/background/aquarium/bubble.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 10},
+ .position_offset = {10, 5},
+ }
+ );
+ shop_item_bubble.add_component<Sprite>(
+ Asset("asset/background/aquarium/bubble.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 10},
+ .position_offset = {-5, -20},
+ }
+ );
+ shop_item_bubble.add_component<Sprite>(
+ Asset("asset/background/aquarium/bubble.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 20},
+ .position_offset = {15, -40},
+ }
+ );
+ shop_item_bubble.add_component<Sprite>(
+ Asset("asset/background/aquarium/bubble.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 20},
+ .position_offset = {-20, 10},
+ }
+ );
+ shop_item_bubble.add_component<Sprite>(
+ Asset("asset/background/aquarium/bubble.png"),
+ Sprite::Data {
+ .sorting_in_layer = STARTING_SORTING_IN_LAYER + 1,
+ .size = {0, 15},
+ .position_offset = {30, -25},
+ }
+ );
+
+ const string BUBBLE_STRING = "BUBBLE";
+ size
+ = {CHAR_SIZE * BUBBLE_STRING.size(),
+ (CHAR_SIZE * BUBBLE_STRING.size() / BUBBLE_STRING.size()) * 2};
shop_item_bubble.add_component<Text>(
- vec2 {100, 50}, FONT,
+ size, FONT,
Text::Data {
.world_space = true,
.text_color = Color::WHITE,
},
- vec2 {0, -75}, "BUBBLE"
+ vec2 {0, -75}, BUBBLE_STRING
);
shop_item_bubble.add_component<Sprite>(
Asset("asset/ui/buttonCoinsSmall.png"),
@@ -113,13 +247,79 @@ void ShopMenuScene::load_scene() {
.position_offset = {45, 75},
}
);
+
+ const string BUBBLE_GOLD_STRING = "1000";
+ size
+ = {CHAR_SIZE_COIN * BUBBLE_GOLD_STRING.size(),
+ (CHAR_SIZE_COIN * BUBBLE_GOLD_STRING.size() / BUBBLE_GOLD_STRING.size()) * 2};
shop_item_bubble.add_component<Text>(
- vec2 {100, 25}, FONT,
+ size, FONT,
Text::Data {
.world_space = true,
.text_color = Color::GOLD,
},
- vec2 {-25, 75}, "1000"
+ vec2 {-10, 75}, BUBBLE_GOLD_STRING
+ );
+
+ button.create(
+ *this,
+ ButtonSubScene::Data {
+ .text = "BUY",
+ .text_width = 100,
+ .position = vec2(-100, 120),
+ .script_type = ButtonSubScene::ScriptSelect::SHOP_BULLET,
+ .button_type = ButtonSubScene::ButtonSelect::LARGE,
+ .scale = 0.4,
+ .tag = BUY_BULLET,
+ .sorting_layer_offset = 20,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::PURPLE
+
+ }
+ );
+
+ button.create(
+ *this,
+ ButtonSubScene::Data {
+ .text = "BUY",
+ .text_width = 100,
+ .position = vec2(100, 120),
+ .script_type = ButtonSubScene::ScriptSelect::SHOP_BUBBLE,
+ .button_type = ButtonSubScene::ButtonSelect::LARGE,
+ .scale = 0.4,
+ .tag = BUY_BUBBLE,
+ .sorting_layer_offset = 20,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::PURPLE
+ }
+ );
+
+ button.create(
+ *this,
+ ButtonSubScene::Data {
+ .text = "SELECT",
+ .text_width = 100,
+ .position = vec2(-100, 120),
+ .script_type = ButtonSubScene::ScriptSelect::SHOP_BULLET,
+ .button_type = ButtonSubScene::ButtonSelect::LARGE,
+ .scale = 0.4,
+ .tag = SELECT_BULLET,
+ .sorting_layer_offset = 20,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::PURPLE
+ }
+ );
+
+ button.create(
+ *this,
+ ButtonSubScene::Data {
+ .text = "SELECT",
+ .text_width = 100,
+ .position = vec2(100, 120),
+ .script_type = ButtonSubScene::ScriptSelect::SHOP_BUBBLE,
+ .button_type = ButtonSubScene::ButtonSelect::LARGE,
+ .scale = 0.4,
+ .tag = SELECT_BUBBLE,
+ .sorting_layer_offset = 20,
+ .btn_side_color = ButtonSubScene::ButtonSideColor::PURPLE
+ }
);
}
diff --git a/game/menus/shop/Shopconfig.h b/game/menus/shop/Shopconfig.h
new file mode 100644
index 0000000..a686242
--- /dev/null
+++ b/game/menus/shop/Shopconfig.h
@@ -0,0 +1,14 @@
+#pragma once
+#include "api/Event.h"
+
+//tags
+static constexpr const char * BUY_BULLET = "BUY_BULLET";
+static constexpr const char * SELECT_BULLET = "SELECT_BULLET";
+static constexpr const char * BUY_BUBBLE = "BUY_BUBBLE";
+static constexpr const char * SELECT_BUBBLE = "SELECT_BUBBLE";
+
+//save_data
+static constexpr const char * BUY_BULLET_SAVE = "BUY_BULLET_SAVE";
+static constexpr const char * BUY_BUBBLE_SAVE = "BUY_BUBBLE_SAVE";
+
+struct ShopUpdate : public crepe::Event {};
diff --git a/game/missile/AlertScript.cpp b/game/missile/AlertScript.cpp
new file mode 100644
index 0000000..0e6f5c5
--- /dev/null
+++ b/game/missile/AlertScript.cpp
@@ -0,0 +1,38 @@
+#include "AlertScript.h"
+#include "../Config.h"
+
+#include <crepe/api/CircleCollider.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/api/Transform.h>
+
+using namespace crepe;
+
+void AlertScript::fixed_update(crepe::duration_t dt) {
+ const auto & cam = this->get_components_by_name<Transform>("camera").front().get();
+ //missile transform
+ const auto & this_transform = this->get_component<Transform>();
+ auto missile_transforms = this->get_components_by_name<Transform>("missile");
+ const auto & this_collider = this->get_component<CircleCollider>();
+
+ auto alert_sprites = this->get_components_by_name<Sprite>("missile_alert");
+ auto alert_transforms = this->get_components_by_name<Transform>("missile_alert");
+
+ int idx = 0;
+ for (int i = 0; i < missile_transforms.size(); ++i) {
+ const auto & missile_transform = missile_transforms[i].get();
+ if (this_transform.game_object_id == missile_transform.game_object_id) {
+ idx = i;
+ break;
+ }
+ }
+
+ auto & alert_transform = alert_transforms[idx].get();
+ alert_transform.position.x = cam.position.x + (VIEWPORT_X / 2 - 100);
+ alert_transform.position.y = this_transform.position.y;
+
+ // check if transform is in camera view
+ if (this_transform.position.x > cam.position.x - (VIEWPORT_X / 2)
+ && this_transform.position.x < cam.position.x + (VIEWPORT_X / 2)) {
+ alert_sprites[idx].get().active = false;
+ }
+}
diff --git a/game/missile/AlertScript.h b/game/missile/AlertScript.h
new file mode 100644
index 0000000..5b0b3a1
--- /dev/null
+++ b/game/missile/AlertScript.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <crepe/api/Script.h>
+
+class AlertScript : public crepe::Script {
+private:
+ bool has_alert = false;
+
+public:
+ void fixed_update(crepe::duration_t dt);
+};
diff --git a/game/missile/AlertSubScene.cpp b/game/missile/AlertSubScene.cpp
new file mode 100644
index 0000000..5bce5ac
--- /dev/null
+++ b/game/missile/AlertSubScene.cpp
@@ -0,0 +1,33 @@
+#include "AlertSubScene.h"
+#include "../Config.h"
+
+#include <crepe/api/Animator.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/Sprite.h>
+
+using namespace crepe;
+
+MissileAlert::MissileAlert(Scene & scn) {
+ GameObject alert = scn.new_object("missile_alert", "missile_alert", {0, 0}, 0, 1);
+
+ Asset missile_alert_ss {"asset/obstacles/missile/missileAlert.png"};
+
+ auto & missile_alert_sprite = alert.add_component<Sprite>(
+ missile_alert_ss,
+ Sprite::Data {
+ .sorting_in_layer = SORT_IN_LAY_OBSTACLES,
+ .size = {0, 100},
+ }
+ );
+
+ auto & missile_alert_anim = alert.add_component<Animator>(
+ missile_alert_sprite, ivec2 {64, 64}, uvec2 {4, 2},
+ Animator::Data {
+ .fps = 15,
+ .looping = true,
+ }
+ );
+
+ missile_alert_anim.set_anim(1);
+ missile_alert_sprite.active = false;
+}
diff --git a/game/missile/AlertSubScene.h b/game/missile/AlertSubScene.h
new file mode 100644
index 0000000..8ea288f
--- /dev/null
+++ b/game/missile/AlertSubScene.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <crepe/api/Scene.h>
+
+class MissileAlert {
+public:
+ MissileAlert(crepe::Scene & scn);
+};
diff --git a/game/missile/MissilePool.cpp b/game/missile/MissilePool.cpp
index e549210..23f03c9 100644
--- a/game/missile/MissilePool.cpp
+++ b/game/missile/MissilePool.cpp
@@ -1,5 +1,6 @@
#include "MissilePool.h"
#include "MissileSubScene.h"
+#include "missile/AlertSubScene.h"
#include <crepe/api/Scene.h>
@@ -10,6 +11,7 @@ MissilePool::MissilePool(Scene & scn) {
int amount = 0;
MissileSubScene missile;
while (amount < this->MAX_MISSILE_COUNT) {
+ MissileAlert alert(scn);
missile.create(scn);
amount++;
}
diff --git a/game/missile/MissileScript.cpp b/game/missile/MissileScript.cpp
index 6d0e40e..3aa4eb6 100644
--- a/game/missile/MissileScript.cpp
+++ b/game/missile/MissileScript.cpp
@@ -1,18 +1,19 @@
#include "MissileScript.h"
#include "../Config.h"
-#include "api/BehaviorScript.h"
+#include <cmath>
+#include <crepe/api/AI.h>
#include <crepe/api/Animator.h>
#include <crepe/api/AudioSource.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/CircleCollider.h>
+#include <crepe/api/KeyCodes.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/Sprite.h>
#include <crepe/api/Transform.h>
#include <crepe/system/CollisionSystem.h>
#include <crepe/types.h>
-#include <cmath>
-#include <crepe/api/AI.h>
-#include <crepe/api/KeyCodes.h>
-#include <crepe/api/Sprite.h>
-
using namespace std;
using namespace crepe;
@@ -25,8 +26,8 @@ void MissileScript::init() {
void MissileScript::kill_missile() {
auto animations = this->get_components<Animator>();
auto sprites = this->get_components<Sprite>();
- auto & fly_sound = this->get_components<AudioSource>().front().get();
- auto & this_script = this->get_components<BehaviorScript>().back().get();
+ auto collider = this->get_component<CircleCollider>();
+ auto & this_script = this->get_components<BehaviorScript>().front().get();
animations[0].get().active = false;
animations[1].get().active = false;
@@ -35,23 +36,22 @@ void MissileScript::kill_missile() {
sprites[1].get().active = false;
sprites[2].get().active = true;
+ collider.active = false;
this_script.active = false;
this->seeking_disabled = false;
-
- fly_sound.stop();
}
void MissileScript::activate() {
auto anim = this->get_components<Animator>();
auto sprites = this->get_components<Sprite>();
- anim[0].get().active = true;
- anim[1].get().active = true;
- anim[2].get().stop();
sprites[0].get().active = true;
sprites[1].get().active = true;
sprites[2].get().active = false;
-}
+ anim[0].get().active = true;
+ anim[1].get().active = true;
+ anim[2].get().stop();
+}
bool MissileScript::on_collision(const CollisionEvent & ev) {
auto & explosion_sound = this->get_components<AudioSource>().back().get();
@@ -74,15 +74,16 @@ void MissileScript::fixed_update(crepe::duration_t dt) {
const auto & cam = this->get_components_by_name<Transform>("camera").front().get();
const auto & velocity = this->get_component<Rigidbody>().data.linear_velocity;
- if (missile.position.x < (cam.position.x - VIEWPORT_X / 1.8)) {
- this->kill_missile();
- return;
- }
-
// check if animation is at the end
if (explosion_anim.data.row == 7) {
this->activate();
this->seeking_disabled = false;
+ return;
+ }
+
+ if (missile.position.x < (cam.position.x - VIEWPORT_X / 1.8)) {
+ this->kill_missile();
+ return;
}
if (this->seeking_disabled) {
diff --git a/game/missile/MissileSubScene.cpp b/game/missile/MissileSubScene.cpp
index 6719c3d..d325050 100644
--- a/game/missile/MissileSubScene.cpp
+++ b/game/missile/MissileSubScene.cpp
@@ -1,6 +1,8 @@
#include "MissileSubScene.h"
#include "../Config.h"
#include "../missile/MissileScript.h"
+#include "Random.h"
+#include "missile/AlertScript.h"
#include <crepe/api/AI.h>
#include <crepe/api/Animator.h>
@@ -10,14 +12,10 @@
#include <crepe/api/Scene.h>
#include <crepe/api/Sprite.h>
#include <crepe/types.h>
-#include <random>
using namespace crepe;
void MissileSubScene::create(crepe::Scene & scn) {
- std::random_device rd;
- std::mt19937 gen(rd());
-
GameObject missle = scn.new_object("missile", "missile", {0, 0}, 0, 1);
Asset missle_ss {"asset/obstacles/missile/missile.png"};
@@ -27,6 +25,7 @@ void MissileSubScene::create(crepe::Scene & scn) {
Asset missile_fire {"asset/sfx/missile_launch.ogg"};
missle.add_component<BehaviorScript>().set_script<MissileScript>().active = false;
+ missle.add_component<BehaviorScript>().set_script<AlertScript>();
auto & sound = missle.add_component<AudioSource>(missile_fire);
sound.volume = 0.5;
@@ -88,16 +87,15 @@ void MissileSubScene::create(crepe::Scene & scn) {
missile_explosion_sprite.active = false;
explosion_anim.active = false;
- std::uniform_int_distribution<> dist(200, 250);
missle.add_component<Rigidbody>(Rigidbody::Data {
.body_type = Rigidbody::BodyType::KINEMATIC,
- .max_linear_velocity = static_cast<float>(dist(gen)),
+ .max_linear_velocity = Random::f(250, 200),
.kinematic_collision = false,
.collision_layers = {COLL_LAY_PLAYER, COLL_LAY_BOT_TOP},
.collision_layer = COLL_LAY_MISSILE,
});
- missle.add_component<CircleCollider>(3);
+ missle.add_component<CircleCollider>(3).active = false;
auto & missle_ai = missle.add_component<AI>(1000);
}
diff --git a/game/missile/SpawnEvent.cpp b/game/missile/SpawnEvent.cpp
index 03a9b8c..6109686 100644
--- a/game/missile/SpawnEvent.cpp
+++ b/game/missile/SpawnEvent.cpp
@@ -1,14 +1,15 @@
#include "SpawnEvent.h"
+#include "Random.h"
#include <crepe/api/Animator.h>
#include <crepe/api/AudioSource.h>
#include <crepe/api/BehaviorScript.h>
#include <crepe/api/Camera.h>
+#include <crepe/api/CircleCollider.h>
#include <crepe/api/Sprite.h>
#include <crepe/api/Transform.h>
#include <cstdlib>
-#include <random>
using namespace crepe;
@@ -18,28 +19,29 @@ void MissileSpawnEventHandler::init() {
});
}
-std::random_device rd;
-std::mt19937 gen(rd());
-
bool MissileSpawnEventHandler::on_event(const MissileSpawnEvent & event) {
- auto missile_sprites = this->get_components_by_name<Sprite>("missile");
+ auto alert_sprites = this->get_components_by_name<Sprite>("missile_alert");
+
auto missile_transforms = this->get_components_by_name<Transform>("missile");
+ auto colliders = this->get_components_by_name<CircleCollider>("missile");
auto missile_behaviorscripts = this->get_components_by_name<BehaviorScript>("missile");
auto missile_audiosources = this->get_components_by_name<AudioSource>("missile");
+
auto & camera_transform = this->get_components_by_name<Transform>("camera").front().get();
- for (size_t i = 0; i < missile_behaviorscripts.size(); ++i) {
- auto & script = missile_behaviorscripts[i].get();
+ for (size_t i = 0; i < missile_transforms.size(); ++i) {
+ BehaviorScript & script = missile_behaviorscripts[i * 2].get();
if (script.active) continue;
script.active = true;
-
+ colliders[i].get().active = true;
missile_audiosources[i * 2].get().play();
auto & transform = missile_transforms[i].get();
transform.position.x = camera_transform.position.x + this->MISSILE_OFFSET;
- std::uniform_int_distribution<> dist(this->MIN_RANGE, this->MAX_RANGE);
- transform.position.y = dist(gen);
+ transform.position.y = Random::i(this->MAX_RANGE, this->MIN_RANGE);
+ auto & alert_sprite = alert_sprites[i].get();
+ alert_sprite.active = true;
break;
}
diff --git a/game/missile/SpawnEvent.h b/game/missile/SpawnEvent.h
index 58293d7..84b1987 100644
--- a/game/missile/SpawnEvent.h
+++ b/game/missile/SpawnEvent.h
@@ -10,9 +10,8 @@ struct MissileSpawnEvent : public crepe::Event {};
class MissileSpawnEventHandler : public crepe::Script {
private:
static constexpr int MISSILE_OFFSET = VIEWPORT_X;
- static constexpr int RANGE = GAME_HEIGHT / 4;
- static constexpr int MIN_RANGE = -RANGE;
- static constexpr int MAX_RANGE = RANGE;
+ static constexpr int MIN_RANGE = -150;
+ static constexpr int MAX_RANGE = 150;
public:
void init();
diff --git a/game/player/PlayerBulletScript.cpp b/game/player/PlayerBulletScript.cpp
index a76b7eb..a823375 100644
--- a/game/player/PlayerBulletScript.cpp
+++ b/game/player/PlayerBulletScript.cpp
@@ -17,7 +17,7 @@ void PlayerBulletScript::fixed_update(crepe::duration_t dt) {
Camera & camera = this->get_components_by_name<Camera>("camera").front();
Transform & cam_transform = this->get_components_by_name<Transform>("camera").front();
Rigidbody & bullet_body = this->get_component<Rigidbody>();
- transform.rotation += bullet_body.data.angular_velocity;
+ transform.rotation += bullet_body.data.angular_velocity * dt.count();
transform.position += bullet_body.data.linear_velocity * dt.count();
vec2 half_screen = camera.viewport_size / 2;
float despawn_location = cam_transform.position.x + half_screen.x + 50;
diff --git a/game/player/PlayerBulletSubScene.cpp b/game/player/PlayerBulletSubScene.cpp
index 795747b..82ce4a9 100644
--- a/game/player/PlayerBulletSubScene.cpp
+++ b/game/player/PlayerBulletSubScene.cpp
@@ -24,8 +24,8 @@ int PlayerBulletSubScene::create(Scene & scn, int counter) {
Rigidbody & player_bullet_body = player_bullet.add_component<Rigidbody>(Rigidbody::Data {
.gravity_scale = 0,
.body_type = Rigidbody::BodyType::KINEMATIC,
- .linear_velocity = vec2 {400, 0},
- .angular_velocity = 10,
+ .linear_velocity = vec2 {450, 0},
+ .angular_velocity = 300,
.kinematic_collision = false,
.collision_layers = {COLL_LAY_ENEMY, COLL_LAY_ZAPPER},
diff --git a/game/player/PlayerEndScript.cpp b/game/player/PlayerEndScript.cpp
index 4ae813f..62fd350 100644
--- a/game/player/PlayerEndScript.cpp
+++ b/game/player/PlayerEndScript.cpp
@@ -92,8 +92,9 @@ bool PlayerEndScript::on_collision(const crepe::CollisionEvent & ev) {
jump++;
}
- if (rb_player.data.linear_velocity.x < 5 && jump >= 3) {
+ if (rb_player.data.linear_velocity.x < 5 && jump == 3) {
this->trigger_event<EndGameEvent>();
+ jump++;
}
return false;
diff --git a/game/player/PlayerScript.cpp b/game/player/PlayerScript.cpp
index fadca9c..8cbe8dc 100644
--- a/game/player/PlayerScript.cpp
+++ b/game/player/PlayerScript.cpp
@@ -18,8 +18,42 @@ void PlayerScript::init() {
subscribe<CollisionEvent>([this](const CollisionEvent & ev) -> bool {
return this->on_collision(ev);
});
+ subscribe<KeyPressEvent>([this](const KeyPressEvent & ev) -> bool {
+ if (ev.repeat) return false;
+ return this->on_key_down(ev);
+ });
+ subscribe<KeyReleaseEvent>([this](const KeyReleaseEvent & ev) -> bool {
+ return this->on_key_up(ev);
+ });
this->last_fired = std::chrono::steady_clock::now();
+ this->body = get_component<Rigidbody>();
+}
+
+bool PlayerScript::on_key_down(const KeyPressEvent & ev) {
+ if (ev.key == Keycode::SPACE) {
+ const vec2 UP = {0, -1};
+ this->help_kick(UP);
+ }
+ return false;
}
+
+bool PlayerScript::on_key_up(const KeyReleaseEvent & ev) {
+ if (ev.key == Keycode::SPACE) {
+ const vec2 DOWN = {0, 1};
+ this->help_kick(DOWN);
+ }
+ return false;
+}
+
+void PlayerScript::help_kick(const vec2 & direction) {
+ // softly "kick" the player (at start/end of flight)
+ vec2 & velocity = this->body->data.linear_velocity;
+ float kick_amount = std::min(
+ velocity.length() * PLAYER_HELP_KICK_SCALE, engine_gravity * PLAYER_HELP_KICK_MAX
+ );
+ velocity += direction * kick_amount;
+}
+
bool PlayerScript::on_collision(const CollisionEvent & ev) {
BehaviorScript & play_scr = this->get_components_by_name<BehaviorScript>("player").front();
BehaviorScript & end_scr = this->get_components_by_name<BehaviorScript>("player").back();
@@ -94,7 +128,7 @@ void PlayerScript::fixed_update(crepe::duration_t dt) {
emitter.data.boundary.offset = vec2(0, -transform.position.y);
}
- Rigidbody & rb = this->get_components_by_name<Rigidbody>("player").front();
+ Rigidbody & rb = this->body;
if (this->get_key_state(Keycode::ENTER)) {
auto now = std::chrono::steady_clock::now();
@@ -105,7 +139,10 @@ void PlayerScript::fixed_update(crepe::duration_t dt) {
}
}
if (this->get_key_state(Keycode::SPACE)) {
- rb.add_force_linear(vec2(0, -PLAYER_GRAVITY_SCALE / 2.5) * dt.count() / 0.02);
+ rb.add_force_linear(
+ vec2(0, -1) * (engine_gravity * PLAYER_GRAVITY_SCALE * dt.count())
+ );
+
if (prev_anim != 1) {
for (Animator & anim : animators) {
anim.active = true;
@@ -126,8 +163,8 @@ void PlayerScript::fixed_update(crepe::duration_t dt) {
if (current_jetpack_sound > 7) {
current_jetpack_sound = 0;
}
- } else if (transform.position.y == 195) {
- Rigidbody & rb = this->get_components_by_name<Rigidbody>("player").front();
+ } else if (transform.position.y == 200) {
+ Rigidbody & rb = this->body;
if (prev_anim != 0 && rb.data.linear_velocity.x != 0) {
for (Animator & anim : animators) {
anim.active = true;
diff --git a/game/player/PlayerScript.h b/game/player/PlayerScript.h
index e7d860a..6a7dedb 100644
--- a/game/player/PlayerScript.h
+++ b/game/player/PlayerScript.h
@@ -1,8 +1,11 @@
#pragma once
+#include "util/OptionalRef.h"
#include <chrono>
+#include <crepe/api/Config.h>
#include <crepe/api/Event.h>
#include <crepe/api/Script.h>
+
class PlayerScript : public crepe::Script {
public:
void init();
@@ -10,13 +13,20 @@ public:
private:
bool on_collision(const crepe::CollisionEvent & ev);
+ bool on_key_down(const crepe::KeyPressEvent & ev);
+ bool on_key_up(const crepe::KeyReleaseEvent & ev);
// bool on_key_up(const crepe::KeyReleaseEvent& ev);
void shoot(const crepe::vec2 & location, float angle);
+ void help_kick(const crepe::vec2 & direction);
private:
int prev_anim = 0;
std::chrono::time_point<std::chrono::steady_clock> last_fired;
+ std::chrono::time_point<std::chrono::steady_clock> last_switched;
std::chrono::duration<float> shot_delay = std::chrono::duration<float>(0.5);
-
+ std::chrono::duration<float> switch_delay = std::chrono::duration<float>(0.01);
int current_jetpack_sound = 0;
+
+ float & engine_gravity = crepe::Config::get_instance().physics.gravity;
+ crepe::OptionalRef<crepe::Rigidbody> body;
};
diff --git a/game/player/PlayerSubScene.cpp b/game/player/PlayerSubScene.cpp
index c4d689a..d0142e0 100644
--- a/game/player/PlayerSubScene.cpp
+++ b/game/player/PlayerSubScene.cpp
@@ -5,8 +5,8 @@
#include "../Config.h"
#include "../coins/CoinScript.h"
-#include "api/Asset.h"
+#include <crepe/ValueBroker.h>
#include <crepe/api/Animator.h>
#include <crepe/api/AudioSource.h>
#include <crepe/api/BoxCollider.h>
@@ -16,6 +16,7 @@
#include <crepe/api/Scene.h>
#include <crepe/api/Script.h>
#include <crepe/api/Sprite.h>
+#include <crepe/manager/SaveManager.h>
#include <crepe/types.h>
using namespace crepe;
@@ -24,7 +25,23 @@ using namespace std;
PlayerSubScene::PlayerSubScene(Scene & scn) {
GameObject player = scn.new_object("player", "player", vec2(-100, 200));
- Asset player_bullet {"asset/other_effects/effect_smgbullet.png"};
+ SaveManager & save = scn.get_save_manager();
+ ValueBroker<int> particle_type = save.get<int>(JETPACK_PARTICLES, 0);
+
+ string player_bullet_string;
+ string player_bullet_x2_string;
+ string player_shell_string;
+ if (particle_type.get() == 0) {
+ player_bullet_string = "asset/other_effects/effect_smgbullet.png";
+ player_bullet_x2_string = "asset/other_effects/effect_smgbullet_x2.png";
+ player_shell_string = "asset/other_effects/effect_rocketmgshell_TVOS.png";
+ } else {
+ player_bullet_string = "asset/background/aquarium/bubble.png";
+ player_bullet_x2_string = "asset/background/aquarium/bubble.png";
+ player_shell_string = "asset/background/aquarium/bubble.png";
+ }
+
+ Asset player_bullet {player_bullet_string};
Sprite & player_bullet_sprite = player.add_component<Sprite>(
player_bullet,
Sprite::Data {
@@ -45,7 +62,7 @@ PlayerSubScene::PlayerSubScene(Scene & scn) {
.reset_on_exit = true,
},
});
- Asset player_bullet_x2 {"asset/other_effects/effect_smgbullet_x2.png"};
+ Asset player_bullet_x2 {player_bullet_x2_string};
Sprite & player_bullet_x2_sprite = player.add_component<Sprite>(
player_bullet_x2,
Sprite::Data {
@@ -66,7 +83,7 @@ PlayerSubScene::PlayerSubScene(Scene & scn) {
.reset_on_exit = true,
},
});
- Asset player_shell {"asset/other_effects/effect_rocketmgshell_TVOS.png"};
+ Asset player_shell {player_shell_string};
Sprite & player_shell_sprite = player.add_component<Sprite>(
player_shell,
Sprite::Data {
@@ -106,7 +123,7 @@ PlayerSubScene::PlayerSubScene(Scene & scn) {
.looping = true,
}
);
- player.add_component<BoxCollider>(vec2(50, 50));
+ player.add_component<BoxCollider>(vec2(50, 35));
Asset player_head_asset {"asset/barry/defaultHead.png"};
Sprite & player_head_sprite = player.add_component<Sprite>(
player_head_asset,
@@ -143,9 +160,9 @@ PlayerSubScene::PlayerSubScene(Scene & scn) {
.looping = true,
}
);
- player.add_component<BoxCollider>(vec2(40, 60), vec2(-20, 0));
+ player.add_component<BoxCollider>(vec2(40, 50), vec2(-20, 0));
player.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = PLAYER_GRAVITY_SCALE,
+ .gravity_scale = 1.0,
.body_type = Rigidbody::BodyType::DYNAMIC,
.linear_velocity = vec2(PLAYER_SPEED * 0.02, 0),
.collision_layers
@@ -153,6 +170,7 @@ PlayerSubScene::PlayerSubScene(Scene & scn) {
},
.collision_layer = COLL_LAY_PLAYER,
});
+
player.add_component<BehaviorScript>().set_script<PlayerScript>().active = false;
player.add_component<BehaviorScript>().set_script<CoinScript>();
player.add_component<BehaviorScript>().set_script<PlayerEndScript>().active = false;
diff --git a/game/preview/NpcScript.cpp b/game/preview/NpcScript.cpp
index c4148f2..86117d4 100644
--- a/game/preview/NpcScript.cpp
+++ b/game/preview/NpcScript.cpp
@@ -7,26 +7,23 @@
using namespace std;
using namespace crepe;
-void NpcScript::init() {}
void NpcScript::fixed_update(duration_t dt) {
auto & rb = this->get_component<Rigidbody>();
- auto & npc = this->get_component<Sprite>();
+ auto npc = this->get_components<Sprite>();
auto & transform = this->get_component<Transform>();
- if (transform.position.x < -990) {
+ if (transform.position.x < 200) {
rb.data.linear_velocity.x *= -1;
}
- if (transform.position.x > 990) {
+ if (transform.position.x > 700) {
rb.data.linear_velocity.x *= -1;
}
if (rb.data.linear_velocity.x < 0) {
- npc.data.flip = {true, false};
+ npc.front().get().data.flip = {true, false};
+ npc.back().get().data.flip = {true, false};
} else {
- npc.data.flip = {false, false};
+ npc.front().get().data.flip = {false, false};
+ npc.back().get().data.flip = {false, false};
}
-
- auto & savemgr = this->get_save_manager();
- savemgr.set("npc_x", transform.position.x);
- savemgr.set("npc_y", transform.position.y);
}
diff --git a/game/preview/NpcScript.h b/game/preview/NpcScript.h
index 8d856fd..d278f83 100644
--- a/game/preview/NpcScript.h
+++ b/game/preview/NpcScript.h
@@ -1,11 +1,8 @@
+#pragma once
#include <crepe/api/Script.h>
class NpcScript : public crepe::Script {
-
-private:
-
public:
- void init();
void fixed_update(crepe::duration_t dt);
};
diff --git a/game/preview/NpcSubScene.cpp b/game/preview/NpcSubScene.cpp
index bd6cfb2..5ededb6 100644
--- a/game/preview/NpcSubScene.cpp
+++ b/game/preview/NpcSubScene.cpp
@@ -15,11 +15,7 @@
using namespace crepe;
NpcSubScene::NpcSubScene(Scene & scn) {
- auto & savemgr = scn.get_save_manager();
- ValueBroker npc_x = savemgr.get<float>("npc_x", 500);
- ValueBroker npc_y = savemgr.get<float>("npc_y", 0);
-
- GameObject npc = scn.new_object("npc", "npc_tag", vec2 {npc_x.get(), npc_y.get()}, 0, 1);
+ GameObject npc = scn.new_object("npc", "npc_tag", vec2 {500, 0}, 0, 1);
Asset npc_body {"asset/workers/worker1Body.png"};
Asset npc_head {"asset/workers/worker1Head.png"};
@@ -53,7 +49,7 @@ NpcSubScene::NpcSubScene(Scene & scn) {
.looping = true,
}
);
- npc.add_component<BoxCollider>(vec2 {50, 50});
+ npc.add_component<BoxCollider>(vec2 {40, 50});
npc.add_component<Rigidbody>(Rigidbody::Data {
.mass = 10,
@@ -61,7 +57,7 @@ NpcSubScene::NpcSubScene(Scene & scn) {
.body_type = Rigidbody::BodyType::DYNAMIC,
.linear_velocity = {-50, 0},
//.max_linear_velocity = 40,
- .collision_layers = {COLL_LAY_BOT_TOP, COLL_LAY_PLAYER},
+ .collision_layers = {COLL_LAY_BOT_TOP, 100},
.collision_layer = COLL_LAY_PLAYER,
});
diff --git a/game/preview/PrevPlayerScript.cpp b/game/preview/PrevPlayerScript.cpp
index 2657b8d..ae25dad 100644
--- a/game/preview/PrevPlayerScript.cpp
+++ b/game/preview/PrevPlayerScript.cpp
@@ -1,12 +1,11 @@
#include "PrevPlayerScript.h"
#include "../missile/SpawnEvent.h"
-#include "api/Transform.h"
+
#include <crepe/api/AudioSource.h>
#include <crepe/api/Camera.h>
+#include <crepe/api/Transform.h>
#include <crepe/manager/SaveManager.h>
-#include <iostream>
-#include <ostream>
using namespace crepe;
@@ -22,10 +21,6 @@ bool PrevPlayerScript::key_pressed(const KeyPressEvent & ev) {
this->body->data.flip = {false, false};
this->head->data.flip = {false, false};
break;
-
- case Keycode::SPACE:
- this->get_component<Rigidbody>().data.linear_velocity.y = -move_speed;
- break;
case Keycode::D0:
this->body_anim->set_anim(0);
this->head_anim->set_anim(0);
@@ -59,25 +54,20 @@ bool PrevPlayerScript::key_pressed(const KeyPressEvent & ev) {
this->head_anim->set_anim(7);
break;
case Keycode::LEFT:
- this->head->data.angle_offset -= 1;
+ this->get_component<Transform>().rotation += 10;
break;
case Keycode::RIGHT:
- this->head->data.angle_offset += 1;
+ this->get_component<Transform>().rotation -= 10;
break;
case Keycode::UP:
- this->head->data.scale_offset += 0.1;
+ this->head->data.position_offset += 10;
break;
case Keycode::DOWN:
- this->head->data.scale_offset -= 0.1;
+ this->head->data.position_offset -= 10;
break;
case Keycode::P:
- this->get_component<AudioSource>().play();
- break;
- case Keycode::Q:
- this->get_components_by_name<Camera>("camera").front().get().data.zoom -= 0.01;
- break;
- case Keycode::E:
- this->get_components_by_name<Camera>("camera").front().get().data.zoom += 0.01;
+ this->get_components_by_name<AudioSource>("background_music").front().get().active
+ = true;
break;
case Keycode::J:
this->get_components_by_name<Transform>("camera").front().get().position.x
@@ -98,11 +88,6 @@ bool PrevPlayerScript::key_pressed(const KeyPressEvent & ev) {
case Keycode::M:
trigger_event<MissileSpawnEvent>(MissileSpawnEvent {});
break;
- //todo
- case Keycode::PAGE_UP:
- case Keycode::PAGE_DOWN:
- case Keycode::HOME:
- break;
default:
break;
}
@@ -110,6 +95,8 @@ bool PrevPlayerScript::key_pressed(const KeyPressEvent & ev) {
}
void PrevPlayerScript::init() {
+ this->rb = get_component<Rigidbody>();
+
auto animations = this->get_components<Animator>();
body_anim = animations[0];
head_anim = animations[1];
@@ -121,12 +108,50 @@ void PrevPlayerScript::init() {
subscribe<KeyPressEvent>([this](const KeyPressEvent & ev) -> bool {
return this->key_pressed(ev);
});
+ subscribe<KeyPressEvent>([this](const KeyPressEvent & ev) -> bool {
+ if (ev.repeat) return false;
+ return this->on_key_down(ev);
+ });
+ subscribe<KeyReleaseEvent>([this](const KeyReleaseEvent & ev) -> bool {
+ return this->on_key_up(ev);
+ });
};
void PrevPlayerScript::fixed_update(crepe::duration_t dt) {
+ if (this->get_key_state(Keycode::SPACE)) {
+ this->rb->add_force_linear(
+ vec2(0, -1) * (engine_gravity * PLAYER_GRAVITY_SCALE * dt.count())
+ );
+ }
+
auto & savemgr = this->get_save_manager();
const auto & pos = this->get_component<Transform>().position;
savemgr.set("player_x", pos.x);
savemgr.set("player_y", pos.y);
};
+
+bool PrevPlayerScript::on_key_down(const KeyPressEvent & ev) {
+ if (ev.key == Keycode::SPACE) {
+ const vec2 UP = {0, -1};
+ this->help_kick(UP);
+ }
+ return false;
+}
+
+bool PrevPlayerScript::on_key_up(const KeyReleaseEvent & ev) {
+ if (ev.key == Keycode::SPACE) {
+ const vec2 DOWN = {0, 1};
+ this->help_kick(DOWN);
+ }
+ return false;
+}
+
+void PrevPlayerScript::help_kick(const vec2 & direction) {
+ // softly "kick" the player (at start/end of flight)
+ vec2 & velocity = this->rb->data.linear_velocity;
+ float kick_amount = std::min(
+ velocity.length() * PLAYER_HELP_KICK_SCALE, engine_gravity * PLAYER_HELP_KICK_MAX
+ );
+ velocity += direction * kick_amount;
+}
diff --git a/game/preview/PrevPlayerScript.h b/game/preview/PrevPlayerScript.h
index cc3184e..ae66449 100644
--- a/game/preview/PrevPlayerScript.h
+++ b/game/preview/PrevPlayerScript.h
@@ -1,10 +1,10 @@
-
+#include <crepe/api/Animator.h>
+#include <crepe/api/Config.h>
#include <crepe/api/Event.h>
+#include <crepe/api/Rigidbody.h>
#include <crepe/api/Script.h>
-#include <crepe/util/OptionalRef.h>
-
-#include <crepe/api/Animator.h>
#include <crepe/api/Sprite.h>
+#include <crepe/util/OptionalRef.h>
class PrevPlayerScript : public crepe::Script {
private:
@@ -20,4 +20,13 @@ private:
void init();
void fixed_update(crepe::duration_t dt);
bool key_pressed(const crepe::KeyPressEvent & ev);
+
+private:
+ bool on_key_down(const crepe::KeyPressEvent & ev);
+ bool on_key_up(const crepe::KeyReleaseEvent & ev);
+ void help_kick(const crepe::vec2 & direction);
+
+private:
+ float & engine_gravity = crepe::Config::get_instance().physics.gravity;
+ crepe::OptionalRef<crepe::Rigidbody> rb;
};
diff --git a/game/preview/PrevPlayerSubScene.cpp b/game/preview/PrevPlayerSubScene.cpp
index b59a0af..074cfb4 100644
--- a/game/preview/PrevPlayerSubScene.cpp
+++ b/game/preview/PrevPlayerSubScene.cpp
@@ -16,13 +16,8 @@
using namespace crepe;
PrevPlayerSubScene::PrevPlayerSubScene(Scene & scn) {
- auto & savemgr = scn.get_save_manager();
- ValueBroker player_x = savemgr.get<float>("player_x", 500);
- ValueBroker player_y = savemgr.get<float>("player_y", -100);
-
- GameObject player
- = scn.new_object("player", "TAG", vec2 {player_x.get(), player_y.get()}, 0, 1);
+ GameObject player = scn.new_object("player", "player", vec2 {800, -100}, 0, 1);
Asset player_body_asset {"asset/barry/defaultBody.png"};
Sprite & player_body_sprite = player.add_component<Sprite>(
player_body_asset,
@@ -75,12 +70,18 @@ PrevPlayerSubScene::PrevPlayerSubScene(Scene & scn) {
}
);
player.add_component<Rigidbody>(Rigidbody::Data {
- .gravity_scale = 20,
+ .gravity_scale = 1,
.body_type = Rigidbody::BodyType::DYNAMIC,
.linear_velocity = vec2(100, 0),
- .collision_layers = {COLL_LAY_BOT_TOP},
+ .collision_layers = {COLL_LAY_BOT_TOP, 100},
.collision_layer = COLL_LAY_PLAYER,
});
- player.add_component<BoxCollider>(vec2(50, 50));
+ player.add_component<BoxCollider>(vec2(40, 50));
player.add_component<BehaviorScript>().set_script<PrevPlayerScript>();
+
+ GameObject music = scn.new_object("background_music", "background_music");
+ AudioSource & audio = music.add_component<AudioSource>(Asset {"asset/music/level.ogg"});
+ audio.loop = true;
+ audio.play_on_awake = true;
+ audio.active = false;
}
diff --git a/game/preview/PreviewReplaySubScript.cpp b/game/preview/PreviewReplaySubScript.cpp
new file mode 100644
index 0000000..580a608
--- /dev/null
+++ b/game/preview/PreviewReplaySubScript.cpp
@@ -0,0 +1,55 @@
+#include "PreviewReplaySubScript.h"
+#include "Config.h"
+#include "menus/ButtonReplaySubScript.h"
+#include <crepe/api/AudioSource.h>
+#include <crepe/types.h>
+
+using namespace crepe;
+using namespace std;
+
+void PreviewReplaySubScript::init() {
+ IButtonScript::init();
+ this->subscribe<ButtonPressEvent>([this](const ButtonPressEvent & e) {
+ return this->on_button_press(e);
+ });
+ this->subscribe<StopPreviewRecording>([this](const StopPreviewRecording & e) {
+ return this->stop_recording();
+ });
+ this->subscribe<DeleteRecordingEvent>([this](const DeleteRecordingEvent & e) {
+ return this->delete_recording();
+ });
+ this->subscribe<StartPreviewRecording>([this](const StartPreviewRecording & e) {
+ return this->start_recording();
+ });
+}
+
+bool PreviewReplaySubScript::on_button_press(const ButtonPressEvent & e) {
+ if (DISABLE_REPLAY) return false;
+ replay.play(this->recording);
+ return false;
+}
+bool PreviewReplaySubScript::start_recording() {
+ if (DISABLE_REPLAY) return false;
+ if (record_saved) {
+ this->stop_recording();
+ this->delete_recording();
+ }
+ replay.record_start();
+ this->record_started = true;
+ return false;
+}
+
+bool PreviewReplaySubScript::stop_recording() {
+ if (DISABLE_REPLAY) return false;
+ if (this->record_started) this->recording = replay.record_end();
+ this->record_saved = true;
+ return false;
+}
+
+bool PreviewReplaySubScript::delete_recording() {
+ if (DISABLE_REPLAY) return false;
+ if (this->record_started) this->stop_recording();
+ if (this->record_saved) replay.release(this->recording);
+ this->record_saved = false;
+ return false;
+}
diff --git a/game/preview/PreviewReplaySubScript.h b/game/preview/PreviewReplaySubScript.h
new file mode 100644
index 0000000..59b78c3
--- /dev/null
+++ b/game/preview/PreviewReplaySubScript.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "menus/IButtonScript.h"
+
+#include <crepe/api/Script.h>
+
+struct StartPreviewRecording : public crepe::Event {};
+struct StopPreviewRecording : public crepe::Event {};
+
+class PreviewReplaySubScript : public IButtonScript {
+public:
+ void init() override;
+ bool on_button_press(const crepe::ButtonPressEvent & e);
+
+private:
+ crepe::recording_t recording = 0;
+ bool start_recording();
+ bool stop_recording();
+ bool delete_recording();
+
+private:
+ bool record_saved = false;
+ bool record_started = false;
+};
diff --git a/game/preview/PreviewStartRecSubScript.cpp b/game/preview/PreviewStartRecSubScript.cpp
new file mode 100644
index 0000000..8a2f54c
--- /dev/null
+++ b/game/preview/PreviewStartRecSubScript.cpp
@@ -0,0 +1,20 @@
+#include "PreviewStartRecSubScript.h"
+#include "PreviewReplaySubScript.h"
+
+#include <crepe/api/AudioSource.h>
+#include <crepe/types.h>
+
+using namespace crepe;
+using namespace std;
+
+void PreviewStartRecSubScript::init() {
+ IButtonScript::init();
+ this->subscribe<ButtonPressEvent>([this](const ButtonPressEvent & e) {
+ return this->on_button_press(e);
+ });
+}
+
+bool PreviewStartRecSubScript::on_button_press(const ButtonPressEvent & e) {
+ this->trigger_event<StartPreviewRecording>();
+ return false;
+}
diff --git a/game/preview/PreviewStartRecSubScript.h b/game/preview/PreviewStartRecSubScript.h
new file mode 100644
index 0000000..a54a085
--- /dev/null
+++ b/game/preview/PreviewStartRecSubScript.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "menus/IButtonScript.h"
+
+#include <crepe/api/Script.h>
+
+class PreviewStartRecSubScript : public IButtonScript {
+public:
+ void init() override;
+ bool on_button_press(const crepe::ButtonPressEvent & e);
+};
diff --git a/game/preview/PreviewStopRecSubScript.cpp b/game/preview/PreviewStopRecSubScript.cpp
new file mode 100644
index 0000000..a229da8
--- /dev/null
+++ b/game/preview/PreviewStopRecSubScript.cpp
@@ -0,0 +1,20 @@
+#include "PreviewStopRecSubScript.h"
+#include "PreviewReplaySubScript.h"
+
+#include <crepe/api/AudioSource.h>
+#include <crepe/types.h>
+
+using namespace crepe;
+using namespace std;
+
+void PreviewStopRecSubScript::init() {
+ IButtonScript::init();
+ this->subscribe<ButtonPressEvent>([this](const ButtonPressEvent & e) {
+ return this->on_button_press(e);
+ });
+}
+
+bool PreviewStopRecSubScript::on_button_press(const ButtonPressEvent & e) {
+ this->trigger_event<StopPreviewRecording>();
+ return false;
+}
diff --git a/game/preview/PreviewStopRecSubScript.h b/game/preview/PreviewStopRecSubScript.h
new file mode 100644
index 0000000..b2dd73b
--- /dev/null
+++ b/game/preview/PreviewStopRecSubScript.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "menus/IButtonScript.h"
+
+#include <crepe/api/Script.h>
+
+class PreviewStopRecSubScript : public IButtonScript {
+public:
+ void init() override;
+ bool on_button_press(const crepe::ButtonPressEvent & e);
+};
diff --git a/game/scheduler/ObjectsScheduler.cpp b/game/scheduler/ObjectsScheduler.cpp
index 3ce2018..7f58c79 100644
--- a/game/scheduler/ObjectsScheduler.cpp
+++ b/game/scheduler/ObjectsScheduler.cpp
@@ -4,6 +4,7 @@
#include "../Config.h"
#include "../Random.h"
+#include "../enemy/EnemyScript.h"
#include "../missile/SpawnEvent.h"
#include "api/Rigidbody.h"
#include "api/Transform.h"
@@ -11,18 +12,52 @@
#include "prefab/ZapperPoolSubScene.h"
using namespace crepe;
+
void ObjectsScheduler::preset_0() {
+ for (int i = 0; i < this->amount_of_boss_fights; i++) {
+ this->trigger_event<MissileSpawnEvent>(MissileSpawnEvent {});
+ }
+ if (this->amount_of_boss_fights >= 1) {
+ this->trigger_event<BattleStartEvent>(BattleStartEvent {
+ .num_enemies = Random::i(this->amount_of_boss_fights, 0),
+ .battle = false,
+ });
+ }
+}
+
+void ObjectsScheduler::preset_1() {
trigger_event<MissileSpawnEvent>(MissileSpawnEvent {});
- trigger_event<MissileSpawnEvent>(MissileSpawnEvent {});
+ if (this->amount_of_boss_fights >= 3) {
+ this->trigger_event<BattleStartEvent>(BattleStartEvent {
+ .num_enemies = Random::i(1, 0),
+ .battle = false,
+ });
+ }
}
-void ObjectsScheduler::preset_1() { trigger_event<MissileSpawnEvent>(MissileSpawnEvent {}); }
-void ObjectsScheduler::preset_2() { trigger_event<CreateZapperEvent>(CreateZapperEvent {}); }
+
+void ObjectsScheduler::preset_2() {
+ trigger_event<CreateZapperEvent>(CreateZapperEvent {});
+ if (this->amount_of_boss_fights >= 2) {
+ this->trigger_event<BattleStartEvent>(BattleStartEvent {
+ .num_enemies = Random::i(2, 1),
+ .battle = false,
+ });
+ }
+}
+
void ObjectsScheduler::preset_3() { trigger_event<CreateZapperEvent>(CreateZapperEvent {}); }
+
void ObjectsScheduler::preset_4() {}
+
void ObjectsScheduler::boss_fight_1() {
this->get_components_by_name<Rigidbody>("camera").front().get().data.linear_velocity.x = 0;
this->get_components_by_name<Rigidbody>("player").front().get().data.linear_velocity.x = 0;
- this->trigger_event<BattleStartEvent>(BattleStartEvent {.num_enemies = 2});
+
+ this->amount_of_boss_fights++;
+ this->trigger_event<BattleStartEvent>(BattleStartEvent {
+ .num_enemies = amount_of_boss_fights,
+ .battle = true,
+ });
RefVector<Rigidbody> rb_back_forest
= this->get_components_by_tag<Rigidbody>("forest_background");
@@ -37,10 +72,18 @@ bool ObjectsScheduler::boss_fight_1_event() {
this->get_components_by_name<Rigidbody>("player").front().get().data.linear_velocity.x
= PLAYER_SPEED * 0.02;
+ bool first = true;
RefVector<Rigidbody> rb_back_forest
= this->get_components_by_tag<Rigidbody>("forest_background");
- rb_back_forest.front().get().data.linear_velocity.x = 30;
- rb_back_forest.back().get().data.linear_velocity.x = 40;
+ for (Rigidbody & rb : rb_back_forest) {
+ if (first == true) {
+ rb.data.linear_velocity.x = 30;
+ first = false;
+ } else {
+ rb.data.linear_velocity.x = 40;
+ first = true;
+ }
+ }
return false;
}
diff --git a/game/scheduler/ObjectsScheduler.h b/game/scheduler/ObjectsScheduler.h
index bd0701b..7ada8e1 100644
--- a/game/scheduler/ObjectsScheduler.h
+++ b/game/scheduler/ObjectsScheduler.h
@@ -16,6 +16,8 @@ private:
int obstacle_interval = 350;
int start_offset = 1300;
+ int amount_of_boss_fights = 0;
+
private:
void preset_0();
void preset_1();