From 7e12ebdf945d40d6f11872cf5852c9bb54d1864f Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sun, 22 Dec 2024 16:12:31 +0100
Subject: big WIP

---
 game/CMakeLists.txt | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

(limited to 'game/CMakeLists.txt')

diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index 937b5e6..a149487 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -8,20 +8,19 @@ set(CMAKE_BUILD_TYPE Debug)
 project(game C CXX)
 
 add_subdirectory(../src crepe)
-add_executable(main
-	background/AquariumSubScene.cpp
-	background/BackgroundSubScene.cpp
-	background/ForestParallaxScript.cpp
-	background/ForestSubScene.cpp
+
+add_executable(main)
+
+target_sources(main PUBLIC
 	GameScene.cpp
-	background/HallwaySubScene.cpp
 	MoveCameraManualyScript.cpp
-	PlayerScript.cpp
-	PlayerSubScene.cpp
 	StartGameScript.cpp
-	background/StartSubScene.cpp
 	main.cpp
 )
 
+add_subdirectory(background)
+add_subdirectory(prefab)
+
 target_link_libraries(main PUBLIC crepe)
+target_include_directories(main PRIVATE .)
 
-- 
cgit v1.2.3


From 36942c357663a033582a1dfb39af0d3ab15afd0c Mon Sep 17 00:00:00 2001
From: WBoerenkamps <wrj.boerenkamps@student.avans.nl>
Date: Mon, 6 Jan 2025 10:46:11 +0100
Subject: start of enemypool and creation

---
 game/CMakeLists.txt          |  2 ++
 game/enemy/EnemyPool.cpp     |  7 +++++++
 game/enemy/EnemyPool.h       | 10 ++++++++++
 game/enemy/EnemySubScene.cpp | 29 +++++++++++++++++++++++++++++
 game/enemy/EnemySubScene.h   | 10 ++++++++++
 5 files changed, 58 insertions(+)
 create mode 100644 game/enemy/EnemyPool.cpp
 create mode 100644 game/enemy/EnemyPool.h
 create mode 100644 game/enemy/EnemySubScene.cpp
 create mode 100644 game/enemy/EnemySubScene.h

(limited to 'game/CMakeLists.txt')

diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index 937b5e6..a5218a5 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -9,6 +9,8 @@ project(game C CXX)
 
 add_subdirectory(../src crepe)
 add_executable(main
+	enemy/EnemyPool.cpp
+	enemy/EnemySubScene.cpp
 	background/AquariumSubScene.cpp
 	background/BackgroundSubScene.cpp
 	background/ForestParallaxScript.cpp
diff --git a/game/enemy/EnemyPool.cpp b/game/enemy/EnemyPool.cpp
new file mode 100644
index 0000000..b5160db
--- /dev/null
+++ b/game/enemy/EnemyPool.cpp
@@ -0,0 +1,7 @@
+#include "EnemySubScene.h"
+#include "EnemyPool.h"
+using namespace std;
+void EnemyPool::create_enemies(crepe::Scene & scn) {
+	EnemySubScene enemy;
+	while(enemy.create(scn) < this->MAXIMUM_AMOUNT);
+}
diff --git a/game/enemy/EnemyPool.h b/game/enemy/EnemyPool.h
new file mode 100644
index 0000000..e2b9ddd
--- /dev/null
+++ b/game/enemy/EnemyPool.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <crepe/api/Scene.h>
+
+class EnemyPool {
+public:
+	void create_enemies(crepe::Scene & scn);
+private:
+	static constexpr int MAXIMUM_AMOUNT = 100;
+};
diff --git a/game/enemy/EnemySubScene.cpp b/game/enemy/EnemySubScene.cpp
new file mode 100644
index 0000000..4187411
--- /dev/null
+++ b/game/enemy/EnemySubScene.cpp
@@ -0,0 +1,29 @@
+#include <string>
+
+#include "EnemySubScene.h"
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/BoxCollider.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Sprite.h>
+using namespace crepe;
+using namespace std;
+int EnemySubScene::create(Scene & scn){
+	vec2 size = {20, 20};
+
+	static int coin_counter = 0;
+	string unique_name = "enemy_" + to_string(coin_counter++);
+	GameObject enemy = scn.new_object(unique_name.c_str(),"enemy",vec2{650,0},0,1);
+	enemy.add_component<Rigidbody>(Rigidbody::Data{
+		.body_type = Rigidbody::BodyType::DYNAMIC,
+	});
+	crepe::OptionalRef<Sprite> enemy_sprite = enemy.add_component<Sprite>(Asset{"asset/coin/coin1_TVOS.png"}, Sprite::Data{
+																   	.sorting_in_layer = 100,
+																	.order_in_layer = 100,
+																   	.size = vec2(0, 50),
+															   });
+	enemy.add_component<>
+	
+	return coin_counter;
+}
diff --git a/game/enemy/EnemySubScene.h b/game/enemy/EnemySubScene.h
new file mode 100644
index 0000000..a24020b
--- /dev/null
+++ b/game/enemy/EnemySubScene.h
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace crepe {
+class Scene;
+}
+
+class EnemySubScene {
+public:
+	int create(crepe::Scene & scn);
+};
-- 
cgit v1.2.3


From 743cdd5b2fe175605352c337396c3d70dac66247 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Tue, 7 Jan 2025 09:43:53 +0100
Subject: roll back player controller

---
 game/CMakeLists.txt          |  2 ++
 game/GameScene.cpp           |  4 +--
 game/PlayerScript.cpp        | 11 +++++++
 game/PlayerScript.h          |  8 +++++
 game/PlayerSubScene.cpp      | 76 ++++++++++++++++++++++++++++++++++++++++++++
 game/PlayerSubScene.h        | 10 ++++++
 game/prefab/CMakeLists.txt   |  2 --
 game/prefab/PlayerObject.cpp | 71 -----------------------------------------
 game/prefab/PlayerObject.h   | 30 -----------------
 game/prefab/PlayerScript.cpp | 13 --------
 game/prefab/PlayerScript.h   | 16 ----------
 11 files changed, 109 insertions(+), 134 deletions(-)
 create mode 100644 game/PlayerScript.cpp
 create mode 100644 game/PlayerScript.h
 create mode 100644 game/PlayerSubScene.cpp
 create mode 100644 game/PlayerSubScene.h
 delete mode 100644 game/prefab/PlayerObject.cpp
 delete mode 100644 game/prefab/PlayerObject.h
 delete mode 100644 game/prefab/PlayerScript.cpp
 delete mode 100644 game/prefab/PlayerScript.h

(limited to 'game/CMakeLists.txt')

diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index a149487..32d7085 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -15,6 +15,8 @@ target_sources(main PUBLIC
 	GameScene.cpp
 	MoveCameraManualyScript.cpp
 	StartGameScript.cpp
+	PlayerScript.cpp
+	PlayerSubScene.cpp
 	main.cpp
 )
 
diff --git a/game/GameScene.cpp b/game/GameScene.cpp
index b287763..71612e3 100644
--- a/game/GameScene.cpp
+++ b/game/GameScene.cpp
@@ -20,7 +20,7 @@
 #include "StartGameScript.h"
 
 #include "background/BackgroundSubScene.h"
-#include "prefab/PlayerObject.h"
+#include "PlayerSubScene.h"
 #include "prefab/ZapperObject.h"
 
 using namespace crepe;
@@ -41,7 +41,7 @@ void GameScene::load_scene() {
 	camera.add_component<BehaviorScript>().set_script<MoveCameraManualyScript>();
 	camera.add_component<Rigidbody>(Rigidbody::Data {});
 
-	PlayerObject {new_object("player", "player", vec2(-100, 200))};
+	PlayerSubScene player(*this);
 
 	GameObject floor = new_object("floor", "game_world", vec2(0, 325));
 	floor.add_component<Rigidbody>(Rigidbody::Data {
diff --git a/game/PlayerScript.cpp b/game/PlayerScript.cpp
new file mode 100644
index 0000000..1c388f5
--- /dev/null
+++ b/game/PlayerScript.cpp
@@ -0,0 +1,11 @@
+#include "PlayerScript.h"
+
+#include <crepe/api/Rigidbody.h>
+
+using namespace crepe;
+using namespace std;
+
+void PlayerScript::fixed_update(crepe::duration_t dt) {
+	Rigidbody & rb = this->get_components_by_name<Rigidbody>("player").front();
+	if (this->get_key_state(Keycode::SPACE)) rb.add_force_linear(vec2(0, -10));
+}
diff --git a/game/PlayerScript.h b/game/PlayerScript.h
new file mode 100644
index 0000000..84c4f7f
--- /dev/null
+++ b/game/PlayerScript.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <crepe/api/Script.h>
+
+class PlayerScript : public crepe::Script {
+public:
+	void fixed_update(crepe::duration_t dt);
+};
diff --git a/game/PlayerSubScene.cpp b/game/PlayerSubScene.cpp
new file mode 100644
index 0000000..00b7810
--- /dev/null
+++ b/game/PlayerSubScene.cpp
@@ -0,0 +1,76 @@
+#include "PlayerSubScene.h"
+#include "Config.h"
+#include "PlayerScript.h"
+
+#include <crepe/api/Animator.h>
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/Script.h>
+#include <crepe/api/Sprite.h>
+
+using namespace crepe;
+using namespace std;
+
+PlayerSubScene::PlayerSubScene(Scene & scn) {
+	GameObject player = scn.new_object("player", "player", vec2(-100, 200));
+	Asset player_body_asset {"asset/barry/defaultBody.png"};
+	Sprite & player_body_sprite = player.add_component<Sprite>(
+		player_body_asset,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.order_in_layer = 0,
+			.size = vec2(0, 50),
+		}
+	);
+	player.add_component<Animator>(
+		player_body_sprite, ivec2(32, 32), uvec2(4, 8),
+		Animator::Data {
+			.fps = 5,
+			.looping = true,
+		}
+	);
+	Asset player_head_asset {"asset/barry/defaultHead.png"};
+	Sprite & player_head_sprite = player.add_component<Sprite>(
+		player_head_asset,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.order_in_layer = 1,
+			.size = vec2(0, 50),
+			.position_offset = vec2(0, -20),
+		}
+	);
+	player.add_component<Animator>(
+		player_head_sprite, ivec2(32, 32), uvec2(4, 8),
+		Animator::Data {
+			.fps = 5,
+			.looping = true,
+		}
+	);
+	Asset player_jetpack_asset {"asset/barry/jetpackDefault.png"};
+	Sprite & player_jetpack_sprite = player.add_component<Sprite>(
+		player_jetpack_asset,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.order_in_layer = 2,
+			.size = vec2(0, 60),
+			.position_offset = vec2(-20, 0),
+		}
+	);
+	player_jetpack_sprite.active = false;
+	player.add_component<Animator>(
+		player_jetpack_sprite, ivec2(32, 44), uvec2(4, 4),
+		Animator::Data {
+			.fps = 5,
+			.looping = true,
+		}
+	);
+	player.add_component<Rigidbody>(Rigidbody::Data {
+		.gravity_scale = 20,
+		.body_type = Rigidbody::BodyType::DYNAMIC,
+		.linear_velocity = vec2(100, 0),
+		.collision_layers = {COLL_LAY_BOT_TOP},
+		.collision_layer = COLL_LAY_PLAYER,
+	});
+	player.add_component<BoxCollider>(vec2(50, 50));
+	player.add_component<BehaviorScript>().set_script<PlayerScript>().active = false;
+}
diff --git a/game/PlayerSubScene.h b/game/PlayerSubScene.h
new file mode 100644
index 0000000..bf94c32
--- /dev/null
+++ b/game/PlayerSubScene.h
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace crepe {
+class Scene;
+}
+
+class PlayerSubScene {
+public:
+	PlayerSubScene(crepe::Scene & scn);
+};
diff --git a/game/prefab/CMakeLists.txt b/game/prefab/CMakeLists.txt
index 5585a32..5f8ea6c 100644
--- a/game/prefab/CMakeLists.txt
+++ b/game/prefab/CMakeLists.txt
@@ -1,6 +1,4 @@
 target_sources(main PUBLIC
-	PlayerObject.cpp
-	PlayerScript.cpp
 	ZapperObject.cpp
 )
 
diff --git a/game/prefab/PlayerObject.cpp b/game/prefab/PlayerObject.cpp
deleted file mode 100644
index 2d48bf8..0000000
--- a/game/prefab/PlayerObject.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#include "PlayerObject.h"
-#include "Config.h"
-#include "PlayerScript.h"
-
-using namespace crepe;
-
-PlayerObject::PlayerObject(crepe::GameObject && base)
-	: GameObject(std::move(base)),
-	  sprite {
-		  .body = add_component<Sprite>(
-			  Asset {"asset/barry/defaultBody.png"},
-			  Sprite::Data {
-				  .sorting_in_layer = SORT_IN_LAY_PLAYER,
-				  .order_in_layer = 0,
-				  .size = vec2(0, 50),
-			  }
-		  ),
-		  .head = add_component<Sprite>(
-			  Asset {"asset/barry/defaultHead.png"},
-			  Sprite::Data {
-				  .sorting_in_layer = SORT_IN_LAY_PLAYER,
-				  .order_in_layer = 1,
-				  .size = vec2(0, 50),
-				  .position_offset = vec2(0, -20),
-			  }
-		  ),
-		  .jetpack = add_component<Sprite>(
-			  Asset {"asset/barry/jetpackDefault.png"},
-			  Sprite::Data {
-				  .sorting_in_layer = SORT_IN_LAY_PLAYER,
-				  .order_in_layer = 2,
-				  .size = vec2(0, 60),
-				  .position_offset = vec2(-20, 0),
-			  }
-		  )
-	  },
-	  animator {
-		  .body = add_component<Animator>(
-			  sprite.body, ivec2(32, 32), uvec2(4, 8),
-			  Animator::Data {
-				  .fps = 5,
-				  .looping = true,
-			  }
-		  ),
-		  .head = add_component<Animator>(
-			  sprite.head, ivec2(32, 32), uvec2(4, 8),
-			  Animator::Data {
-				  .fps = 5,
-				  .looping = true,
-			  }
-		  ),
-		  .jetpack = add_component<Animator>(
-			  sprite.jetpack, ivec2(32, 44), uvec2(4, 4),
-			  Animator::Data {
-				  .fps = 5,
-				  .looping = true,
-			  }
-		  ),
-	  },
-	  body(add_component<Rigidbody>(Rigidbody::Data {
-		  .gravity_scale = 20,
-		  .body_type = Rigidbody::BodyType::DYNAMIC,
-		  .linear_velocity = vec2(100, 0),
-		  .collision_layers = {COLL_LAY_BOT_TOP},
-		  .collision_layer = COLL_LAY_PLAYER,
-	  })),
-	  collider(add_component<BoxCollider>(vec2(50, 50))),
-	  controller(add_component<BehaviorScript>().set_script<PlayerScript>(*this)) {
-	sprite.jetpack.active = false;
-	controller.active = false;
-}
diff --git a/game/prefab/PlayerObject.h b/game/prefab/PlayerObject.h
deleted file mode 100644
index a44d367..0000000
--- a/game/prefab/PlayerObject.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include <crepe/api/Animator.h>
-#include <crepe/api/BehaviorScript.h>
-#include <crepe/api/BoxCollider.h>
-#include <crepe/api/GameObject.h>
-#include <crepe/api/Rigidbody.h>
-#include <crepe/api/Sprite.h>
-
-class PlayerObject : public crepe::GameObject {
-public:
-	PlayerObject(crepe::GameObject &&);
-
-public:
-	struct {
-		crepe::Sprite & body;
-		crepe::Sprite & head;
-		crepe::Sprite & jetpack;
-	} sprite;
-
-	struct {
-		crepe::Animator & body;
-		crepe::Animator & head;
-		crepe::Animator & jetpack;
-	} animator;
-
-	crepe::Rigidbody & body;
-	crepe::BoxCollider & collider;
-	crepe::BehaviorScript & controller;
-};
diff --git a/game/prefab/PlayerScript.cpp b/game/prefab/PlayerScript.cpp
deleted file mode 100644
index 3d06476..0000000
--- a/game/prefab/PlayerScript.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <cassert>
-#include <crepe/api/Rigidbody.h>
-
-#include "PlayerScript.h"
-
-using namespace crepe;
-using namespace std;
-
-PlayerScript::PlayerScript(const PlayerObject & player) : player(player) {}
-
-void PlayerScript::fixed_update(crepe::duration_t dt) {
-	if (this->get_key_state(Keycode::SPACE)) player.body.add_force_linear({0, -10});
-}
diff --git a/game/prefab/PlayerScript.h b/game/prefab/PlayerScript.h
deleted file mode 100644
index cc0f0aa..0000000
--- a/game/prefab/PlayerScript.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include <crepe/api/Script.h>
-
-#include "PlayerObject.h"
-
-class PlayerScript : public crepe::Script {
-public:
-	PlayerScript(const PlayerObject & player);
-
-protected:
-	void fixed_update(crepe::duration_t dt);
-
-protected:
-	PlayerObject player;
-};
-- 
cgit v1.2.3


From b8acb539a3580bf0665fe435c55f33ba16cb507e Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 8 Jan 2025 09:58:34 +0100
Subject: WIP

---
 game/CMakeLists.txt              |  2 +-
 game/Config.h                    |  7 ++++---
 game/Random.cpp                  | 28 ++++++++++++++++++++++++++++
 game/Random.h                    | 11 +++++++++++
 game/main.cpp                    |  7 +++++--
 game/prefab/ZapperPoolScript.cpp |  9 ++++++++-
 6 files changed, 57 insertions(+), 7 deletions(-)
 create mode 100644 game/Random.cpp
 create mode 100644 game/Random.h

(limited to 'game/CMakeLists.txt')

diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index 48844b7..5c7bb6b 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -4,7 +4,6 @@ set(CMAKE_C_STANDARD 11)
 set(CMAKE_CXX_STANDARD 20)
 set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
 set(CMAKE_BUILD_TYPE Debug)
-
 project(game C CXX)
 
 add_subdirectory(../src crepe)
@@ -45,6 +44,7 @@ target_sources(main PUBLIC
 	hud/HudSubScene.cpp
 	hud/HudScript.cpp
 	hud/SpeedScript.cpp
+	Random.cpp
 )
 
 add_subdirectory(background)
diff --git a/game/Config.h b/game/Config.h
index 8c27226..95846d2 100644
--- a/game/Config.h
+++ b/game/Config.h
@@ -31,11 +31,12 @@ static constexpr int COLL_LAY_ZAPPER = 6; // Only for GameScene
 static constexpr int COLL_LAY_LASER = 7; // Only for GameScene
 static constexpr int COLL_LAY_MISSILE = 8; // Only for GameScene
 
-static constexpr int GAME_HEIGHT = 800; // In game units
+static constexpr float GAME_HEIGHT = 800; // In game units
+static constexpr float HALLWAY_HEIGHT = 475; // In game units
 
-static constexpr int VIEWPORT_X = 1100; // 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
-static constexpr int VIEWPORT_Y = 500; // In game units
+static constexpr float VIEWPORT_Y = 500; // In game units
 
 // Font settings
 static constexpr const char* FONT = "Jetpackia";
diff --git a/game/Random.cpp b/game/Random.cpp
new file mode 100644
index 0000000..59be3c5
--- /dev/null
+++ b/game/Random.cpp
@@ -0,0 +1,28 @@
+#include <cstdlib>
+
+#include "Random.h"
+
+float Random::f(float upper, float lower) {
+	float range = upper - lower;
+	float x = ((float) rand() / (float) (RAND_MAX)) * range;
+	return x + lower;
+}
+
+double Random::d(double upper, double lower) {
+	double range = upper - lower;
+	double x = ((double) rand() / (double) (RAND_MAX)) * range;
+	return x + lower;
+}
+
+int Random::i(int upper, int lower) {
+	int range = upper - lower;
+	int x = rand() % range;
+	return x + lower;
+}
+
+unsigned Random::u(unsigned upper, unsigned lower) {
+	unsigned range = upper - lower;
+	unsigned x = rand() % range;
+	return x + lower;
+}
+
diff --git a/game/Random.h b/game/Random.h
new file mode 100644
index 0000000..cf05e87
--- /dev/null
+++ b/game/Random.h
@@ -0,0 +1,11 @@
+#pragma once
+
+class Random {
+public:
+	static float f(float upper = 1.0, float lower = 0.0);
+	static double d(double upper = 1.0, double lower = 0.0);
+	static int i(int upper, int lower = 0);
+	static unsigned u(unsigned upper, unsigned lower = 0);
+
+};
+
diff --git a/game/main.cpp b/game/main.cpp
index bd5ca93..b6458b8 100644
--- a/game/main.cpp
+++ b/game/main.cpp
@@ -1,3 +1,5 @@
+#include <cstdlib>
+
 #include <crepe/api/Engine.h>
 #include <crepe/api/Script.h>
 
@@ -6,16 +8,17 @@
 #include "menus/mainmenu/MainMenuScene.h"
 #include "menus/shop/ShopMenuScene.h"
 
-
 using namespace crepe;
 
 int main() {
+	srand(time(NULL));
+
 	Config::get_instance() = ENGINE_CONFIG;
 
 	Engine gameloop;
+	gameloop.add_scene<GameScene>();
 	gameloop.add_scene<MainMenuScene>();
 	gameloop.add_scene<ShopMenuScene>();
-	gameloop.add_scene<GameScene>();
 
 	return gameloop.main();
 }
diff --git a/game/prefab/ZapperPoolScript.cpp b/game/prefab/ZapperPoolScript.cpp
index e42adc9..c6ce1e7 100644
--- a/game/prefab/ZapperPoolScript.cpp
+++ b/game/prefab/ZapperPoolScript.cpp
@@ -1,9 +1,11 @@
 #include <crepe/api/Camera.h>
 
 #include "../Config.h"
+#include "../Random.h"
 
 #include "ZapperPoolScript.h"
 #include "ZapperPoolSubScene.h"
+#include "util/OptionalRef.h"
 
 using namespace crepe;
 using namespace std;
@@ -24,9 +26,14 @@ void ZapperPoolScript::fixed_update(crepe::duration_t) {
 }
 
 void ZapperPoolScript::spawn_random() {
+	OptionalRef<ZapperObject> zapper = pool.get_next_zapper();
+	if (!zapper) return; // pool exhausted
+	
 	vec2 pos = this->get_camera_pos();
-	logf(Log::DEBUG, "Spawning random zapper at {}", pos);
+	pos.y = Random::f(0.5, -0.5) * HALLWAY_HEIGHT;
 
+	zapper->place(pos, 0, Random::f(400, 200));
+	logf(Log::DEBUG, "Spawning random zapper at {}", pos);
 }
 
 vec2 ZapperPoolScript::get_camera_pos() {
-- 
cgit v1.2.3


From 7f7c5c56dce30d47c32fb57fad6d839d0990b054 Mon Sep 17 00:00:00 2001
From: WBoerenkamps <wrj.boerenkamps@student.avans.nl>
Date: Wed, 8 Jan 2025 10:08:03 +0100
Subject: enemy spawn working + enemy shooting

---
 game/CMakeLists.txt                  |  8 +++
 game/Config.h                        |  2 +
 game/GameScene.cpp                   | 34 +++++++++++--
 game/StartGameScript.cpp             | 23 ++++-----
 game/enemy/BattleScript.cpp          | 53 ++++++++++++++++++++
 game/enemy/BattleScript.h            | 20 ++++++++
 game/enemy/BattleWonEvent.h          |  5 ++
 game/enemy/EnemyBulletPool.cpp       |  8 +++
 game/enemy/EnemyBulletPool.h         | 10 ++++
 game/enemy/EnemyBulletScript.cpp     | 36 ++++++++++++++
 game/enemy/EnemyBulletScript.h       | 11 +++++
 game/enemy/EnemyBulletSubScene.cpp   | 51 +++++++++++++++++++
 game/enemy/EnemyBulletSubScene.h     | 10 ++++
 game/enemy/EnemyPool.h               |  2 +-
 game/enemy/EnemyScript.cpp           | 96 ++++++++++++++++++++++++++++++++++++
 game/enemy/EnemyScript.h             | 29 +++++++++--
 game/enemy/EnemySubScene.cpp         | 44 +++++++++++++----
 game/player/PlayerBulletPool.cpp     |  8 +++
 game/player/PlayerBulletPool.h       | 10 ++++
 game/player/PlayerBulletScript.cpp   | 39 +++++++++++++++
 game/player/PlayerBulletScript.h     | 11 +++++
 game/player/PlayerBulletSubScene.cpp | 51 +++++++++++++++++++
 game/player/PlayerBulletSubScene.h   | 10 ++++
 game/player/PlayerEndScript.cpp      |  2 +
 game/player/PlayerScript.cpp         | 37 ++++++++++++--
 game/player/PlayerScript.h           |  5 +-
 game/player/PlayerSubScene.cpp       |  8 +--
 27 files changed, 587 insertions(+), 36 deletions(-)
 create mode 100644 game/enemy/BattleScript.cpp
 create mode 100644 game/enemy/BattleScript.h
 create mode 100644 game/enemy/BattleWonEvent.h
 create mode 100644 game/enemy/EnemyBulletPool.cpp
 create mode 100644 game/enemy/EnemyBulletPool.h
 create mode 100644 game/enemy/EnemyBulletScript.cpp
 create mode 100644 game/enemy/EnemyBulletScript.h
 create mode 100644 game/enemy/EnemyBulletSubScene.cpp
 create mode 100644 game/enemy/EnemyBulletSubScene.h
 create mode 100644 game/player/PlayerBulletPool.cpp
 create mode 100644 game/player/PlayerBulletPool.h
 create mode 100644 game/player/PlayerBulletScript.cpp
 create mode 100644 game/player/PlayerBulletScript.h
 create mode 100644 game/player/PlayerBulletSubScene.cpp
 create mode 100644 game/player/PlayerBulletSubScene.h

(limited to 'game/CMakeLists.txt')

diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index 819b88c..0e7fc6b 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -9,8 +9,13 @@ project(game C CXX)
 
 add_subdirectory(../src crepe)
 add_executable(main
+	enemy/BattleScript.cpp
 	enemy/EnemyPool.cpp
+	enemy/EnemyBulletScript.cpp
+	enemy/EnemyBulletSubScene.cpp
+	enemy/EnemyBulletPool.cpp
 	enemy/EnemySubScene.cpp
+	enemy/EnemyScript.cpp
 	background/AquariumSubScene.cpp
 	background/BackgroundSubScene.cpp
 	background/ForestParallaxScript.cpp
@@ -20,6 +25,9 @@ add_executable(main
 	MoveCameraManualyScript.cpp
 	player/PlayerScript.cpp
 	player/PlayerSubScene.cpp
+	player/PlayerBulletPool.cpp
+	player/PlayerBulletScript.cpp
+	player/PlayerBulletSubScene.cpp
 	StartGameScript.cpp
 	player/PlayerEndScript.cpp
 	background/StartSubScene.cpp
diff --git a/game/Config.h b/game/Config.h
index d6f8349..aa04018 100644
--- a/game/Config.h
+++ b/game/Config.h
@@ -16,6 +16,8 @@ static constexpr int COLL_LAY_WALL_FRAGS = 5; // Only for GameScene
 static constexpr int COLL_LAY_ZAPPER = 6; // Only for GameScene
 static constexpr int COLL_LAY_LASER = 7; // Only for GameScene
 static constexpr int COLL_LAY_MISSILE = 8; // Only for GameScene
+static constexpr int COLL_LAY_BULLET = 9; // Only for GameScene
+static constexpr int COLL_LAY_ENEMY = 10; // Only for GameScene
 
 static constexpr int GAME_HEIGHT = 800; // In game units
 
diff --git a/game/GameScene.cpp b/game/GameScene.cpp
index a8fcb47..af6fc61 100644
--- a/game/GameScene.cpp
+++ b/game/GameScene.cpp
@@ -5,7 +5,12 @@
 
 #include "background/BackgroundSubScene.h"
 #include "player/PlayerSubScene.h"
-
+#include "player/PlayerBulletPool.h"
+#include "player/PlayerBulletSubScene.h"
+#include "enemy/EnemyPool.h"
+#include "enemy/EnemySubScene.h"
+#include "enemy/EnemyBulletPool.h"
+#include "enemy/BattleScript.h"
 #include <cmath>
 #include <crepe/api/Animator.h>
 #include <crepe/api/Asset.h>
@@ -15,6 +20,7 @@
 #include <crepe/api/Color.h>
 #include <crepe/api/Event.h>
 #include <crepe/api/GameObject.h>
+#include <crepe/api/AI.h>
 #include <crepe/api/ParticleEmitter.h>
 #include <crepe/api/Rigidbody.h>
 #include <crepe/api/Script.h>
@@ -29,7 +35,7 @@ void GameScene::load_scene() {
 	BackgroundSubScene background(*this);
 
 	GameObject camera = new_object("camera", "camera", vec2(650, 0));
-	camera.add_component<Camera>(
+	Camera& camera_cam = camera.add_component<Camera>(
 		ivec2(990, 720), vec2(VIEWPORT_X, VIEWPORT_Y),
 		Camera::Data {
 			.bg_color = Color::RED,
@@ -37,7 +43,13 @@ void GameScene::load_scene() {
 	);
 	camera.add_component<BehaviorScript>().set_script<MoveCameraManualyScript>();
 	camera.add_component<Rigidbody>(Rigidbody::Data {});
-
+	AI& enemy_path_1 = camera.add_component<AI>(400);
+	enemy_path_1.make_oval_path(100, 100, camera.transform.position, 1.5708, true);
+	AI& enemy_path_2 = camera.add_component<AI>(400);
+	enemy_path_2.make_oval_path(100, 100, {0, 0}, 1.5708, true);
+	AI& enemy_path_3 = camera.add_component<AI>(400);
+	enemy_path_3.make_oval_path(100, 100, {0, 0}, 1.5708, true);
+	// camer.add_component<AI>
 	PlayerSubScene player(*this);
 
 	GameObject floor = new_object("floor", "game_world", vec2(0, 325));
@@ -116,6 +128,22 @@ void GameScene::load_scene() {
 		.collision_layer = COLL_LAY_MISSILE,
 	});
 	missile.add_component<BoxCollider>(vec2(100, 100));
+	//Enemy pool
+	EnemyPool enemy_pool;
+	enemy_pool.create_enemies(*this);
+	PlayerBulletPool player_bullet_pool;
+	player_bullet_pool.create_bullets(*this);
+	//Enemy Bullet pool
+	// PlayerBulletSubScene player_bullet;
+	// player_bullet.create(*this);
+	EnemyBulletPool enemy_bullet_pool;
+	enemy_bullet_pool.create_bullets(*this);
+	BehaviorScript& script = camera.add_component<BehaviorScript>().set_script<BattleScript>();
+	
+	// EnemySubScene enemy_sub_scene1;
+	// enemy_sub_scene1.create(*this);
+	// EnemySubScene enemy_sub_scene2;
+	// enemy_sub_scene2.create(*this);
 }
 
 string GameScene::get_name() const { return "scene1"; }
diff --git a/game/StartGameScript.cpp b/game/StartGameScript.cpp
index c786eb4..5698a53 100644
--- a/game/StartGameScript.cpp
+++ b/game/StartGameScript.cpp
@@ -1,3 +1,4 @@
+#include <iostream>
 #include "StartGameScript.h"
 #include "Config.h"
 
@@ -10,7 +11,7 @@ using namespace std;
 
 void StartGameScript::fixed_update(crepe::duration_t dt) {
 	Transform & player_transform = this->get_components_by_name<Transform>("player").front();
-
+	// cout << "startgameScript call speed: " << PLAYER_SPEED * dt.count() << endl;
 	// Create hole in wall and activate panic lamp
 	if (player_transform.position.x > 75 && !this->created_hole) {
 		Sprite & lamp_sprite = this->get_components_by_name<Sprite>("start_end").back();
@@ -49,14 +50,14 @@ 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);
-		BehaviorScript & player_script
-			= this->get_components_by_name<BehaviorScript>("player").front();
-		player_script.active = true;
-		BehaviorScript & this_script
-			= this->get_components_by_name<BehaviorScript>("start_game_script").front();
-		this_script.active = false;
-	}
+	// 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);
+	// 	BehaviorScript & player_script
+	// 		= this->get_components_by_name<BehaviorScript>("player").front();
+	// 	player_script.active = true;
+	// 	BehaviorScript & this_script
+	// 		= this->get_components_by_name<BehaviorScript>("start_game_script").front();
+	// 	this_script.active = false;
+	// }
 }
diff --git a/game/enemy/BattleScript.cpp b/game/enemy/BattleScript.cpp
new file mode 100644
index 0000000..463ddf3
--- /dev/null
+++ b/game/enemy/BattleScript.cpp
@@ -0,0 +1,53 @@
+#include <iostream>
+#include "BattleScript.h"
+#include <crepe/api/AI.h>
+#include "EnemyScript.h"
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Metadata.h>
+#include "BattleWonEvent.h"
+#include "EnemyScript.h"
+using namespace std;
+using namespace crepe;
+// stop player movement
+// spawn enemies
+// resume game once enemies are defeated
+// optional: spawn lazers during fight
+BattleScript::BattleScript(){
+	engine.seed(rd());
+}
+void BattleScript::init(){
+	std::uniform_int_distribution<int> dist(2,10);
+	int random_enemy_amount = dist(this->engine);
+	// this->create_battle(random_enemy_amount);
+	this->subscribe<BattleStartEvent>([this](const BattleStartEvent& e) -> bool {
+		return this->create_battle(e);
+	});
+}
+void BattleScript::fixed_update(duration_t dt){
+	bool enemies_alive = false;
+	RefVector<BehaviorScript> enemy_scripts = this->get_components_by_tag<BehaviorScript>("enemy");
+	
+	for(BehaviorScript& script : enemy_scripts){
+		if(script.active){
+			enemies_alive = true;
+		}
+	}
+	if(!enemies_alive){
+		this->trigger_event<BattleWonEvent>();
+	}
+}
+bool BattleScript::create_battle(const BattleStartEvent& e){
+	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->trigger_event<SpawnEnemyEvent>(SpawnEnemyEvent{
+			.speed = dist(engine),
+			.column = i,
+		},script.game_object_id);
+		
+	}
+	return true;
+}
+
diff --git a/game/enemy/BattleScript.h b/game/enemy/BattleScript.h
new file mode 100644
index 0000000..d239e70
--- /dev/null
+++ b/game/enemy/BattleScript.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <crepe/api/Script.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Event.h>
+#include <random>
+struct BattleStartEvent : public crepe::Event{
+	public: 
+	int num_enemies = 0;
+};
+class BattleScript : public crepe::Script{
+	public:
+	BattleScript();
+	void init() override;
+	void fixed_update(crepe::duration_t dt) override;
+	private:
+	std::random_device rd;
+	std::default_random_engine engine;
+	bool create_battle(const BattleStartEvent& e);
+};
diff --git a/game/enemy/BattleWonEvent.h b/game/enemy/BattleWonEvent.h
new file mode 100644
index 0000000..a48dbad
--- /dev/null
+++ b/game/enemy/BattleWonEvent.h
@@ -0,0 +1,5 @@
+#pragma once
+#include <crepe/api/Event.h>
+struct BattleWonEvent : public crepe::Event{
+
+};
diff --git a/game/enemy/EnemyBulletPool.cpp b/game/enemy/EnemyBulletPool.cpp
new file mode 100644
index 0000000..6ebd50a
--- /dev/null
+++ b/game/enemy/EnemyBulletPool.cpp
@@ -0,0 +1,8 @@
+#include "EnemyBulletSubScene.h"
+#include "EnemyBulletPool.h"
+using namespace std;
+
+void EnemyBulletPool::create_bullets(crepe::Scene & scn) {
+	EnemyBulletSubScene bullet;
+	while(bullet.create(scn) < this->MAXIMUM_AMOUNT);
+}
diff --git a/game/enemy/EnemyBulletPool.h b/game/enemy/EnemyBulletPool.h
new file mode 100644
index 0000000..e0de02c
--- /dev/null
+++ b/game/enemy/EnemyBulletPool.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <crepe/api/Scene.h>
+
+class EnemyBulletPool {
+public:
+	void create_bullets(crepe::Scene & scn);
+private:
+	static constexpr int MAXIMUM_AMOUNT = 20;
+};
diff --git a/game/enemy/EnemyBulletScript.cpp b/game/enemy/EnemyBulletScript.cpp
new file mode 100644
index 0000000..561d086
--- /dev/null
+++ b/game/enemy/EnemyBulletScript.cpp
@@ -0,0 +1,36 @@
+#include <iostream>
+#include "EnemyBulletScript.h"
+#include <crepe/api/Camera.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/Metadata.h>
+using namespace crepe;
+using namespace std;
+void EnemyBulletScript::init(){
+	this->subscribe<CollisionEvent>([this](const CollisionEvent& e) -> bool {
+		return this->on_collide(e);
+	});
+}
+void EnemyBulletScript::fixed_update(crepe::duration_t dt){
+	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();
+	
+	vec2 half_screen = camera.viewport_size / 2;
+	float despawn_location = cam_transform.position.x - half_screen.x - 50;
+	if(transform.position.x < despawn_location){
+		this->despawn_bullet();
+	}
+}
+
+void EnemyBulletScript::despawn_bullet(){
+	Transform& transform = this->get_component<Transform>();
+	Rigidbody& bullet_body = this->get_component<Rigidbody>();
+	bullet_body.active = false;
+	transform.position = {0,-750};
+}
+
+bool EnemyBulletScript::on_collide(const CollisionEvent& e){
+	cout << "collision happened with " << e.info.other.metadata.tag << endl;
+	//this->despawn_bullet();
+	return false;
+}
diff --git a/game/enemy/EnemyBulletScript.h b/game/enemy/EnemyBulletScript.h
new file mode 100644
index 0000000..822387f
--- /dev/null
+++ b/game/enemy/EnemyBulletScript.h
@@ -0,0 +1,11 @@
+#pragma once
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Script.h>
+
+class EnemyBulletScript : public crepe::Script{
+	public:
+		void init() override;
+		void fixed_update(crepe::duration_t dt) override;
+		bool on_collide(const crepe::CollisionEvent& e);
+		void despawn_bullet();
+};
diff --git a/game/enemy/EnemyBulletSubScene.cpp b/game/enemy/EnemyBulletSubScene.cpp
new file mode 100644
index 0000000..1660607
--- /dev/null
+++ b/game/enemy/EnemyBulletSubScene.cpp
@@ -0,0 +1,51 @@
+#include <string>
+
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/BoxCollider.h>
+#include <crepe/api/CircleCollider.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Animator.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/api/AI.h>
+#include "../Config.h"
+
+
+#include "EnemyBulletSubScene.h"
+#include "EnemyScript.h"
+#include "EnemyBulletScript.h"
+using namespace crepe;
+using namespace std;
+int EnemyBulletSubScene::create(Scene & scn){
+	vec2 size = {20, 20};
+
+	static int counter = 0;
+	string unique_name = "enemyBullet_" + to_string(counter++);
+	GameObject bullet = scn.new_object(unique_name.c_str(),"EnemyBullet",vec2{0,-750},0,1);
+	
+	Rigidbody& bullet_body = bullet.add_component<Rigidbody>(Rigidbody::Data {
+		.gravity_scale = 0,
+		.body_type = Rigidbody::BodyType::DYNAMIC,
+		.linear_velocity = vec2{-300,0},
+		.collision_layers = {COLL_LAY_PLAYER},
+		.collision_layer = COLL_LAY_BULLET,
+
+		
+	});
+	bullet_body.active = false;
+	BoxCollider& bullet_collider = bullet.add_component<BoxCollider>(vec2(60, 40));
+	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 {
+			.flip = {true,false},
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.order_in_layer = 1,
+			.size = vec2(60,0),
+		}
+	);
+	bullet.add_component<BehaviorScript>().set_script<EnemyBulletScript>();
+	return counter;
+}
diff --git a/game/enemy/EnemyBulletSubScene.h b/game/enemy/EnemyBulletSubScene.h
new file mode 100644
index 0000000..a7e30d7
--- /dev/null
+++ b/game/enemy/EnemyBulletSubScene.h
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace crepe {
+class Scene;
+}
+
+class EnemyBulletSubScene {
+public:
+	int create(crepe::Scene & scn);
+};
diff --git a/game/enemy/EnemyPool.h b/game/enemy/EnemyPool.h
index e2b9ddd..916b930 100644
--- a/game/enemy/EnemyPool.h
+++ b/game/enemy/EnemyPool.h
@@ -6,5 +6,5 @@ class EnemyPool {
 public:
 	void create_enemies(crepe::Scene & scn);
 private:
-	static constexpr int MAXIMUM_AMOUNT = 100;
+	static constexpr int MAXIMUM_AMOUNT = 10;
 };
diff --git a/game/enemy/EnemyScript.cpp b/game/enemy/EnemyScript.cpp
index e69de29..1fbefaa 100644
--- a/game/enemy/EnemyScript.cpp
+++ b/game/enemy/EnemyScript.cpp
@@ -0,0 +1,96 @@
+#include <iostream>
+#include "../Config.h"
+#include "EnemyScript.h"
+#include <crepe/api/Animator.h>
+#include <crepe/api/ParticleEmitter.h>
+#include <crepe/api/BoxCollider.h>
+#include <crepe/api/AI.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/Transform.h>
+#include <crepe/types.h>
+using namespace crepe;
+using namespace std;
+EnemyScript::EnemyScript(){
+	//cout << column << std::endl;
+	engine.seed(rd());
+	this->last_fired = std::chrono::steady_clock::now();
+}
+void EnemyScript::init(){
+	Metadata& meta = this->get_component<Metadata>();
+	this->subscribe<SpawnEnemyEvent>([this](const SpawnEnemyEvent& e) -> bool{
+		return this->spawn_enemy(e);
+	},meta.game_object_id);
+};
+void EnemyScript::fixed_update(duration_t dt) {
+	
+    Transform& transform = this->get_component<Transform>();
+    Transform& player_transform = this->get_components_by_name<Transform>("player").front();
+    AI& ai_component = this->get_component<AI>();
+
+    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);
+	//cout  << "speed: "<< adjustment_speed << endl;
+	//cout  << "direction: " << direction_to_player_y << endl;
+	// Move the path nodes on the Y-axis
+	for (vec2& path_node : ai_component.path) {
+		path_node.y += (direction_to_player_y > 0 ? 1 : -1) * adjustment_speed * dt.count();
+	}
+	//bullet fire logic:
+
+	auto now = std::chrono::steady_clock::now();
+    std::chrono::duration<float> elapsed = now - last_fired;
+	if (elapsed > std::chrono::duration<float>(5)) {
+    	this->shoot(transform.position,0);
+		last_fired = now;
+	}
+
+}
+bool EnemyScript::spawn_enemy(const SpawnEnemyEvent& e){
+	this->speed = e.speed;
+	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();
+	vec2 half_screen = camera.viewport_size / 2;
+	//cout << "column: " << e.column << endl;
+	float x_value = cam_transform.position.x + half_screen.x - 50 * (1 + e.column);  
+		uniform_real_distribution<float> dist(
+		cam_transform.position.y - half_screen.y + 100,
+		cam_transform.position.y + half_screen.y - 100
+		);
+	float random_height = dist(engine);
+	vec2 spawn_location = {cam_transform.position.x + camera.viewport_size.x / 2 + 100,random_height};
+	transform.position = spawn_location;
+	// transform.position = vec2{cam_transform}
+	ai_component.path.clear();
+	ai_component.make_oval_path(10, 10, vec2{x_value,random_height}, 1.5708, true);
+	
+	return true;
+}
+
+void EnemyScript::onCollide(const CollisionEvent & collisionData){
+
+}
+
+void EnemyScript::shoot(const vec2& location,float angle){
+	//cout << "enemy shot" << endl;
+	RefVector<Transform> bullet_transforms = this->get_components_by_tag<Transform>("EnemyBullet");
+
+	for(Transform& bullet_pos : bullet_transforms){
+		//cout << "bullet pos  x: " << bullet_pos.position.x << " y: " << bullet_pos.position.y << endl;
+		if(bullet_pos.position.x == 0 && bullet_pos.position.y == -750){
+
+			bullet_pos.position = location;
+			bullet_pos.position.x -= 20;
+			Rigidbody& bullet_body = this->get_components_by_id<Rigidbody>(bullet_pos.game_object_id).front();
+			BoxCollider bullet_collider = this->get_components_by_id<BoxCollider>(bullet_pos.game_object_id).front();
+			bullet_collider.active = true;
+			bullet_body.active = true;
+			return;
+		}
+	}
+}
diff --git a/game/enemy/EnemyScript.h b/game/enemy/EnemyScript.h
index 0ecf050..35d2626 100644
--- a/game/enemy/EnemyScript.h
+++ b/game/enemy/EnemyScript.h
@@ -1,7 +1,30 @@
 #pragma once
-
+#include <crepe/api/Event.h>
+#include <crepe/api/Script.h>
+#include <crepe/api/Event.h>
+#include <crepe/api/Camera.h>
+#include <random>
+#include <chrono>
+struct SpawnEnemyEvent : public crepe::Event{
+	float speed = 0;
+	int column = 0;
+};
 class EnemyScript : public crepe::Script {
+	public:
+	EnemyScript();
 	void init() override;
-	void update() override;
-	void onCollide(const CollisionEvent & collisionData);
+	void fixed_update(crepe::duration_t dt) override;
+	void shoot(const crepe::vec2& position,float angle);
+	void onCollide(const crepe::CollisionEvent & collisionData);
+	bool spawn_enemy(const SpawnEnemyEvent& e);
+	private:
+	std::random_device rd;
+	std::default_random_engine engine;
+
+	float speed = 50;
+	const float MIN_SPEED = 10;
+	const float MAX_SPEED = 130;
+	const float MAX_DISTANCE = 100;
+	std::chrono::time_point<std::chrono::steady_clock> last_fired;
+	std::chrono::duration<float> shot_delay;
 };
diff --git a/game/enemy/EnemySubScene.cpp b/game/enemy/EnemySubScene.cpp
index 4a567b9..5618829 100644
--- a/game/enemy/EnemySubScene.cpp
+++ b/game/enemy/EnemySubScene.cpp
@@ -1,6 +1,7 @@
 #include <string>
 
 #include "EnemySubScene.h"
+#include "EnemyScript.h"
 #include <crepe/api/GameObject.h>
 #include <crepe/api/Scene.h>
 #include <crepe/api/BoxCollider.h>
@@ -9,37 +10,56 @@
 #include <crepe/api/BehaviorScript.h>
 #include <crepe/api/Animator.h>
 #include <crepe/api/Sprite.h>
+
+#include <crepe/api/AI.h>
 #include "../Config.h"
 using namespace crepe;
 using namespace std;
 int EnemySubScene::create(Scene & scn){
 	vec2 size = {20, 20};
 
-	static int coin_counter = 0;
-	string unique_name = "enemy_" + to_string(coin_counter++);
-	GameObject enemy = scn.new_object(unique_name.c_str(),"enemy",vec2{650,0},0,1);
+	static int enemy_counter = 0;
+	string unique_name = "enemy_" + to_string(enemy_counter++);
+	GameObject enemy = scn.new_object(unique_name.c_str(),"enemy",vec2{0,-650},0,1);
+	
 	enemy.add_component<Rigidbody>(Rigidbody::Data {
 		.gravity_scale = 0,
+		
 		.body_type = Rigidbody::BodyType::DYNAMIC,
 		// .collision_layers
 		// = {COLL_LAY_BOT_TOP, COLL_LAY_ZAPPER, COLL_LAY_LASER},
-		.collision_layer = COLL_LAY_PLAYER,
+		.max_linear_velocity = 400,
+		.collision_layer = COLL_LAY_ENEMY,
+		
 	});
-	Asset enemy_body_asset {"asset/worker/worker1body.png"};
+	Asset enemy_body_asset {"asset/workers/worker2Body.png"};
 	enemy.add_component<BoxCollider>(vec2(50, 50));
 	Sprite & enemy_body_sprite = enemy.add_component<Sprite>(
 		enemy_body_asset,
 		Sprite::Data {
+			.flip = {true,false},
 			.sorting_in_layer = SORT_IN_LAY_PLAYER,
 			.order_in_layer = 0,
 			.size = vec2(0, 50),
 		}
 	);
+	Animator& body_animator = enemy.add_component<Animator>(
+		enemy_body_sprite, ivec2(32, 32), uvec2(4, 8),
+		Animator::Data {
+			.fps = 5,
+			.col = 3,
+			.row = 1,
+			
+			.looping = false,
+		}
+	);
+	body_animator.pause();
 	enemy.add_component<BoxCollider>(vec2(40, 60), vec2(-20, 0));
-	Asset enemy_head_asset {"asset/workers/worker1Head.png"};
+	Asset enemy_head_asset {"asset/workers/worker2Head.png"};
 	Sprite & enemy_head_sprite = enemy.add_component<Sprite>(
 		enemy_head_asset,
 		Sprite::Data {
+			.flip = {true,false},
 			.sorting_in_layer = SORT_IN_LAY_PLAYER,
 			.order_in_layer = 1,
 			.size = vec2(0, 50),
@@ -58,13 +78,14 @@ int EnemySubScene::create(Scene & scn){
 	Sprite & enemy_jetpack_sprite = enemy.add_component<Sprite>(
 		enemy_jetpack_asset,
 		Sprite::Data {
+			.flip = {true,false},
 			.sorting_in_layer = SORT_IN_LAY_PLAYER,
 			.order_in_layer = 2,
 			.size = vec2(0, 60),
-			.position_offset = vec2(-20, 0),
+			.position_offset = vec2(20, 0),
 		}
 	);
-	enemy_jetpack_sprite.active = false;
+	enemy_jetpack_sprite.active = true;
 	enemy.add_component<Animator>(
 		enemy_jetpack_sprite, ivec2(32, 44), uvec2(4, 4),
 		Animator::Data {
@@ -72,5 +93,10 @@ int EnemySubScene::create(Scene & scn){
 			.looping = true,
 		}
 	);
-	return coin_counter;
+	
+	AI& ai_component = enemy.add_component<AI>(3000);
+	ai_component.path_follow_on();
+	BehaviorScript& enemy_script = enemy.add_component<BehaviorScript>().set_script<EnemyScript>();
+	enemy_script.active = false;
+	return enemy_counter;
 }
diff --git a/game/player/PlayerBulletPool.cpp b/game/player/PlayerBulletPool.cpp
new file mode 100644
index 0000000..63ef346
--- /dev/null
+++ b/game/player/PlayerBulletPool.cpp
@@ -0,0 +1,8 @@
+#include "PlayerBulletSubScene.h"
+#include "PlayerBulletPool.h"
+using namespace std;
+
+void PlayerBulletPool::create_bullets(crepe::Scene & scn) {
+	PlayerBulletSubScene bullet;
+	while(bullet.create(scn) < this->MAXIMUM_AMOUNT);
+}
diff --git a/game/player/PlayerBulletPool.h b/game/player/PlayerBulletPool.h
new file mode 100644
index 0000000..a8ba2fb
--- /dev/null
+++ b/game/player/PlayerBulletPool.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <crepe/api/Scene.h>
+
+class PlayerBulletPool {
+public:
+	void create_bullets(crepe::Scene & scn);
+private:
+	static constexpr int MAXIMUM_AMOUNT = 20;
+};
diff --git a/game/player/PlayerBulletScript.cpp b/game/player/PlayerBulletScript.cpp
new file mode 100644
index 0000000..e1637c2
--- /dev/null
+++ b/game/player/PlayerBulletScript.cpp
@@ -0,0 +1,39 @@
+#include <iostream>
+
+#include <crepe/api/Camera.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/Metadata.h>
+
+#include "PlayerBulletScript.h"
+
+using namespace crepe;
+using namespace std;
+void PlayerBulletScript::init(){
+	this->subscribe<CollisionEvent>([this](const CollisionEvent& e) -> bool {
+		return this->on_collide(e);
+	});
+}
+void PlayerBulletScript::fixed_update(crepe::duration_t dt){
+	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();
+	
+	vec2 half_screen = camera.viewport_size / 2;
+	float despawn_location = cam_transform.position.x + half_screen.x + 50;
+	if(transform.position.x < despawn_location){
+		this->despawn_bullet();
+	}
+}
+
+void PlayerBulletScript::despawn_bullet(){
+	Transform& transform = this->get_component<Transform>();
+	Rigidbody& bullet_body = this->get_component<Rigidbody>();
+	bullet_body.active = false;
+	transform.position = {0,-850};
+}
+
+bool PlayerBulletScript::on_collide(const CollisionEvent& e){
+	cout << "collision happened with " << e.info.other.metadata.tag << endl;
+	//this->despawn_bullet();
+	return false;
+}
diff --git a/game/player/PlayerBulletScript.h b/game/player/PlayerBulletScript.h
new file mode 100644
index 0000000..559b815
--- /dev/null
+++ b/game/player/PlayerBulletScript.h
@@ -0,0 +1,11 @@
+#pragma once
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Script.h>
+
+class PlayerBulletScript : public crepe::Script{
+	public:
+		void init() override;
+		void fixed_update(crepe::duration_t dt) override;
+		bool on_collide(const crepe::CollisionEvent& e);
+		void despawn_bullet();
+};
diff --git a/game/player/PlayerBulletSubScene.cpp b/game/player/PlayerBulletSubScene.cpp
new file mode 100644
index 0000000..eb34046
--- /dev/null
+++ b/game/player/PlayerBulletSubScene.cpp
@@ -0,0 +1,51 @@
+#include <string>
+
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/BoxCollider.h>
+#include <crepe/api/CircleCollider.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Animator.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/api/AI.h>
+#include "../Config.h"
+
+
+#include "PlayerBulletSubScene.h"
+#include "PlayerScript.h"
+#include "PlayerBulletScript.h"
+using namespace crepe;
+using namespace std;
+int PlayerBulletSubScene::create(Scene & scn){
+	vec2 size = {20, 20};
+
+	static int counter = 0;
+	string unique_name = "playerBullet_" + to_string(counter++);
+	GameObject player_bullet = scn.new_object(unique_name.c_str(),"PlayerBullet",vec2{0,-850},0,1);
+	
+	Rigidbody& player_bullet_body = player_bullet.add_component<Rigidbody>(Rigidbody::Data {
+		.gravity_scale = 0,
+		.body_type = Rigidbody::BodyType::DYNAMIC,
+		.linear_velocity = vec2{-300,0},
+		.collision_layers = {COLL_LAY_PLAYER},
+		.collision_layer = COLL_LAY_BULLET,
+
+		
+	});
+	player_bullet_body.active = false;
+	BoxCollider& player_bullet_collider = player_bullet.add_component<BoxCollider>(vec2(60, 40));
+	player_bullet_collider.active = false;
+	Asset player_bullet_asset {"asset/other_effects/effect_smgbullet_x2.png"};
+	Sprite & player_bullet_sprite = player_bullet.add_component<Sprite>(
+		player_bullet_asset,
+		Sprite::Data {
+			.flip = {true,false},
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.order_in_layer = 1,
+			.size = vec2(60,0),
+		}
+	);
+	player_bullet.add_component<BehaviorScript>().set_script<PlayerBulletScript>();
+	return counter;
+}
diff --git a/game/player/PlayerBulletSubScene.h b/game/player/PlayerBulletSubScene.h
new file mode 100644
index 0000000..4b44dc4
--- /dev/null
+++ b/game/player/PlayerBulletSubScene.h
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace crepe {
+class Scene;
+}
+
+class PlayerBulletSubScene {
+public:
+	int create(crepe::Scene & scn);
+};
diff --git a/game/player/PlayerEndScript.cpp b/game/player/PlayerEndScript.cpp
index e04fb9d..fc3b8a1 100644
--- a/game/player/PlayerEndScript.cpp
+++ b/game/player/PlayerEndScript.cpp
@@ -1,3 +1,4 @@
+#include <iostream>
 #include "PlayerEndScript.h"
 
 #include "../Config.h"
@@ -22,6 +23,7 @@ void PlayerEndScript::init() {
 }
 
 bool PlayerEndScript::on_collision(const crepe::CollisionEvent & ev) {
+	cout << "collision player" << endl;
 	if (ev.info.other.metadata.name == "floor") {
 		Transform & transform_player
 			= this->get_components_by_name<Transform>("player").front();
diff --git a/game/player/PlayerScript.cpp b/game/player/PlayerScript.cpp
index 472d7c8..8372080 100644
--- a/game/player/PlayerScript.cpp
+++ b/game/player/PlayerScript.cpp
@@ -1,10 +1,12 @@
+#include <iostream>
 #include "PlayerScript.h"
 
 #include "../Config.h"
-
+#include "../enemy/BattleScript.h"
 #include <crepe/api/Animator.h>
 #include <crepe/api/ParticleEmitter.h>
 #include <crepe/api/Rigidbody.h>
+#include <crepe/api/BoxCollider.h>
 #include <crepe/api/Transform.h>
 #include <crepe/types.h>
 
@@ -16,7 +18,6 @@ void PlayerScript::init() {
 		return this->on_collision(ev);
 	});
 }
-
 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();
@@ -77,8 +78,16 @@ void PlayerScript::fixed_update(crepe::duration_t dt) {
 	for (ParticleEmitter & emitter : emitters) {
 		emitter.data.boundary.offset = vec2(0, -transform.position.y);
 	}
-
+	
 	Rigidbody & rb = this->get_components_by_name<Rigidbody>("player").front();
+	if (this->get_key_state(Keycode::P)) {
+		this->trigger_event<BattleStartEvent>(BattleStartEvent{
+			.num_enemies = 5,
+		});
+	}
+	if(this->get_key_state(Keycode::ENTER)){
+		this->shoot(transform.position,0);
+	}
 	if (this->get_key_state(Keycode::SPACE)) {
 		rb.add_force_linear(vec2(0, -PLAYER_GRAVITY_SCALE / 2.5) * dt.count() / 0.02);
 		if (prev_anim != 1) {
@@ -117,3 +126,25 @@ void PlayerScript::fixed_update(crepe::duration_t dt) {
 		}
 	}
 }
+
+void PlayerScript::shoot(const vec2& location,float angle){
+	cout << "player shot" << endl;
+	RefVector<Transform> bullet_transforms = this->get_components_by_tag<Transform>("PlayerBullet");
+
+	for(Transform& bullet_pos : bullet_transforms){
+		//cout << "bullet pos  x: " << bullet_pos.position.x << " y: " << bullet_pos.position.y << endl;
+		if(bullet_pos.position.x == 0 && bullet_pos.position.y == -850){
+			
+			cout << "bullet found\n";
+			bullet_pos.position = location;
+			bullet_pos.position.x += 20;
+			cout << "bullet pos  x: " << bullet_pos.position.x << " y: " << bullet_pos.position.y << endl;
+			Rigidbody& bullet_body = this->get_components_by_id<Rigidbody>(bullet_pos.game_object_id).front();
+			BoxCollider bullet_collider = this->get_components_by_id<BoxCollider>(bullet_pos.game_object_id).front();
+			//bullet_collider.active = true;
+			bullet_body.active = true;
+			return;
+		}
+	}
+	cout << "bullet not found\n";
+}
diff --git a/game/player/PlayerScript.h b/game/player/PlayerScript.h
index d8eb098..cdb466f 100644
--- a/game/player/PlayerScript.h
+++ b/game/player/PlayerScript.h
@@ -7,10 +7,11 @@ class PlayerScript : public crepe::Script {
 public:
 	void init();
 	void fixed_update(crepe::duration_t dt);
-
+	
 private:
 	bool on_collision(const crepe::CollisionEvent & ev);
-
+	// bool on_key_up(const crepe::KeyReleaseEvent& ev);
+	void shoot(const crepe::vec2& location,float angle);
 private:
 	int prev_anim = 0;
 };
diff --git a/game/player/PlayerSubScene.cpp b/game/player/PlayerSubScene.cpp
index c1e5e2f..99a0fb4 100644
--- a/game/player/PlayerSubScene.cpp
+++ b/game/player/PlayerSubScene.cpp
@@ -18,7 +18,7 @@ using namespace crepe;
 using namespace std;
 
 PlayerSubScene::PlayerSubScene(Scene & scn) {
-	GameObject player = scn.new_object("player", "player", vec2(-100, 200));
+	GameObject player = scn.new_object("player", "player", vec2(300, 200));
 
 	Asset player_bullet {"asset/other_effects/effect_smgbullet.png"};
 	Sprite & player_bullet_sprite = player.add_component<Sprite>(
@@ -143,11 +143,11 @@ PlayerSubScene::PlayerSubScene(Scene & scn) {
 	player.add_component<Rigidbody>(Rigidbody::Data {
 		.gravity_scale = PLAYER_GRAVITY_SCALE,
 		.body_type = Rigidbody::BodyType::DYNAMIC,
-		.linear_velocity = vec2(PLAYER_SPEED * 0.02, 0),
+		//.linear_velocity = vec2(PLAYER_SPEED * 0.02, 0),
 		.collision_layers
-		= {COLL_LAY_BOT_TOP, COLL_LAY_ZAPPER, COLL_LAY_LASER, COLL_LAY_MISSILE},
+		= {COLL_LAY_BOT_TOP, COLL_LAY_ZAPPER, COLL_LAY_LASER, COLL_LAY_MISSILE,COLL_LAY_BULLET},
 		.collision_layer = COLL_LAY_PLAYER,
 	});
-	player.add_component<BehaviorScript>().set_script<PlayerScript>().active = false;
+	player.add_component<BehaviorScript>().set_script<PlayerScript>().active = true;
 	player.add_component<BehaviorScript>().set_script<PlayerEndScript>().active = false;
 }
-- 
cgit v1.2.3


From b445a1716a46dc875e0b2180c1a1b6022ec7a6d3 Mon Sep 17 00:00:00 2001
From: heavydemon21 <nielsstunnebrink1@gmail.com>
Date: Wed, 8 Jan 2025 14:10:27 +0100
Subject: missile/preview/schedular/PreviewScene

---
 game/CMakeLists.txt                 |  45 ++++++++++--
 game/PreviewScene.cpp               |  99 +++++++++++++++++++++++++++
 game/PreviewScene.h                 |  11 +++
 game/missile/MissilePool.cpp        |  16 +++++
 game/missile/MissilePool.h          |  11 +++
 game/missile/MissileScript.cpp      | 105 ++++++++++++++++++++++++++++
 game/missile/MissileScript.h        |  20 ++++++
 game/missile/MissileSubScene.cpp    | 101 +++++++++++++++++++++++++++
 game/missile/MissileSubScene.h      |  12 ++++
 game/missile/SpawnEvent.cpp         |  47 +++++++++++++
 game/missile/SpawnEvent.h           |  20 ++++++
 game/preview/NpcScript.cpp          |  32 +++++++++
 game/preview/NpcScript.h            |  11 +++
 game/preview/NpcSubScene.cpp        |  69 +++++++++++++++++++
 game/preview/NpcSubScene.h          |  10 +++
 game/preview/PrevPlayerScript.cpp   | 132 ++++++++++++++++++++++++++++++++++++
 game/preview/PrevPlayerScript.h     |  23 +++++++
 game/preview/PrevPlayerSubScene.cpp |  86 +++++++++++++++++++++++
 game/preview/PrevPlayerSubScene.h   |  10 +++
 game/preview/SmokeSubScene.cpp      |  37 ++++++++++
 game/preview/SmokeSubScene.h        |  10 +++
 game/scheduler/ObjectsScheduler.cpp |  41 +++++++++++
 game/scheduler/ObjectsScheduler.h   |  34 ++++++++++
 23 files changed, 977 insertions(+), 5 deletions(-)
 create mode 100644 game/PreviewScene.cpp
 create mode 100644 game/PreviewScene.h
 create mode 100644 game/missile/MissilePool.cpp
 create mode 100644 game/missile/MissilePool.h
 create mode 100644 game/missile/MissileScript.cpp
 create mode 100644 game/missile/MissileScript.h
 create mode 100644 game/missile/MissileSubScene.cpp
 create mode 100644 game/missile/MissileSubScene.h
 create mode 100644 game/missile/SpawnEvent.cpp
 create mode 100644 game/missile/SpawnEvent.h
 create mode 100644 game/preview/NpcScript.cpp
 create mode 100644 game/preview/NpcScript.h
 create mode 100644 game/preview/NpcSubScene.cpp
 create mode 100644 game/preview/NpcSubScene.h
 create mode 100644 game/preview/PrevPlayerScript.cpp
 create mode 100644 game/preview/PrevPlayerScript.h
 create mode 100644 game/preview/PrevPlayerSubScene.cpp
 create mode 100644 game/preview/PrevPlayerSubScene.h
 create mode 100644 game/preview/SmokeSubScene.cpp
 create mode 100644 game/preview/SmokeSubScene.h
 create mode 100644 game/scheduler/ObjectsScheduler.cpp
 create mode 100644 game/scheduler/ObjectsScheduler.h

(limited to 'game/CMakeLists.txt')

diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index 4e31f80..47adb11 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -8,25 +8,56 @@ project(game C CXX)
 
 add_subdirectory(../src crepe)
 add_executable(main
+	#background
 	background/AquariumSubScene.cpp
 	background/AquariumScript.cpp
 	background/BackgroundSubScene.cpp
 	background/ForestParallaxScript.cpp
 	background/ForestSubScene.cpp
-	GameScene.cpp
 	background/HallwaySubScene.cpp
+	background/StartSubScene.cpp
+
+	# mainscenes
+	GameScene.cpp
+	menus/shop/ShopMenuScene.cpp
+	menus/mainmenu/MainMenuScene.cpp
+	PreviewScene.cpp
+	main.cpp
+
+	# missile
+	missile/MissilePool.cpp
+	missile/MissileScript.cpp
+	missile/MissileSubScene.cpp
+	missile/SpawnEvent.cpp
+
+	#scheduling
+	scheduler/ObjectsScheduler.cpp
+
+	# Preview
+	preview/SmokeSubScene.cpp
+	preview/NpcSubScene.cpp
+	preview/NpcScript.cpp
+	preview/PrevPlayerSubScene.cpp
+	preview/PrevPlayerScript.cpp
+
+	# scripts
 	background/HallwayScript.cpp
 	MoveCameraManualyScript.cpp
+	StartGameScript.cpp
+
+	# player
 	player/PlayerScript.cpp
 	player/PlayerSubScene.cpp
-	StartGameScript.cpp
 	player/PlayerEndScript.cpp
 	player/PlayerAudioScript.cpp
-	background/StartSubScene.cpp
+
+	# workers
 	workers/WorkersSubScene.cpp
 	workers/WorkerScript.cpp
 	workers/PanicFromPlayerScript.cpp
 	workers/CollisionScript.cpp
+
+	# menus
 	main.cpp
 	menus/BannerSubScene.cpp
 	menus/ButtonSubScene.cpp
@@ -36,20 +67,24 @@ add_executable(main
 	menus/ButtonNextMainMenuSubScript.cpp
 	menus/FloatingWindowSubScene.cpp
 	menus/IFloatingWindowScript.cpp
-	menus/shop/ShopMenuScene.cpp
 	menus/mainmenu/ButtonTransitionPreviewSubScript.cpp
 	menus/mainmenu/ITransitionScript.cpp
-	menus/mainmenu/MainMenuScene.cpp
 	menus/mainmenu/TransitionStartSubScript.cpp
 	menus/endgame/EndGameSubScene.cpp
 	menus/endgame/EndGameSubScript.cpp
+
+	# coins
 	coins/CoinSubScene.cpp
 	coins/CoinPoolSubScene.cpp
 	coins/CoinSystemScript.cpp
 	coins/CoinScript.cpp
+
+	# hud
 	hud/HudSubScene.cpp
 	hud/HudScript.cpp
 	hud/SpeedScript.cpp
+
+	#random
 	Random.cpp
 )
 
diff --git a/game/PreviewScene.cpp b/game/PreviewScene.cpp
new file mode 100644
index 0000000..6cd9e78
--- /dev/null
+++ b/game/PreviewScene.cpp
@@ -0,0 +1,99 @@
+#include "PreviewScene.h"
+
+#include "Config.h"
+#include "background/BackgroundSubScene.h"
+#include "missile/MissilePool.h"
+#include "missile/SpawnEvent.h"
+#include "preview/NpcSubScene.h"
+#include "preview/PrevPlayerSubScene.h"
+#include "preview/SmokeSubScene.h"
+
+#include "missile/MissileSubScene.h"
+
+#include <cmath>
+#include <crepe/api/Animator.h>
+#include <crepe/api/Asset.h>
+#include <crepe/api/AudioSource.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/BoxCollider.h>
+#include <crepe/api/Camera.h>
+#include <crepe/api/Color.h>
+#include <crepe/api/Event.h>
+#include <crepe/api/GameObject.h>
+#include <crepe/api/ParticleEmitter.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/Script.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/api/Transform.h>
+
+#include <crepe/ValueBroker.h>
+#include <crepe/manager/SaveManager.h>
+#include <crepe/types.h>
+#include <iostream>
+
+using namespace crepe;
+using namespace std;
+
+void PreviewScene::load_scene() {
+
+	BackgroundSubScene background(*this);
+
+	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,
+		}
+	);
+	camera.add_component<Rigidbody>(Rigidbody::Data {});
+	camera.add_component<BehaviorScript>().set_script<MissileSpawnEventHandler>();
+
+	GameObject floor = new_object("floor", "game_world", vec2(0, 325));
+	floor.add_component<Rigidbody>(Rigidbody::Data {
+		.body_type = Rigidbody::BodyType::STATIC,
+		.collision_layer = COLL_LAY_BOT_TOP,
+	});
+	floor.add_component<BoxCollider>(vec2(INFINITY, 200));
+	GameObject floor_low = new_object("floor_low", "game_world", vec2(0, 350));
+	floor_low.add_component<Rigidbody>(Rigidbody::Data {
+		.body_type = Rigidbody::BodyType::STATIC,
+		.collision_layer = COLL_LAY_BOT_LOW,
+	});
+	floor_low.add_component<BoxCollider>(vec2(INFINITY, 200));
+	GameObject floor_high = new_object("floor_high", "game_world", vec2(0, 300));
+	floor_high.add_component<Rigidbody>(Rigidbody::Data {
+		.body_type = Rigidbody::BodyType::STATIC,
+		.collision_layer = COLL_LAY_BOT_HIGH,
+	});
+	GameObject ceiling = new_object("ceiling", "game_world", vec2(0, -325));
+	ceiling.add_component<Rigidbody>(Rigidbody::Data {
+		.body_type = Rigidbody::BodyType::STATIC,
+		.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);
+
+	world.add_component<Rigidbody>(Rigidbody::Data {
+		.body_type = Rigidbody::BodyType::STATIC,
+		.collision_layers = {0},
+	});
+
+	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});
+	}
+	  */
+}
+
+string PreviewScene::get_name() const { return "preview scene"; }
diff --git a/game/PreviewScene.h b/game/PreviewScene.h
new file mode 100644
index 0000000..afe911e
--- /dev/null
+++ b/game/PreviewScene.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <crepe/api/Scene.h>
+#include <string>
+
+class PreviewScene : public crepe::Scene {
+public:
+	void load_scene();
+
+	std::string get_name() const;
+};
diff --git a/game/missile/MissilePool.cpp b/game/missile/MissilePool.cpp
new file mode 100644
index 0000000..e549210
--- /dev/null
+++ b/game/missile/MissilePool.cpp
@@ -0,0 +1,16 @@
+#include "MissilePool.h"
+#include "MissileSubScene.h"
+
+#include <crepe/api/Scene.h>
+
+using namespace std;
+using namespace crepe;
+
+MissilePool::MissilePool(Scene & scn) {
+	int amount = 0;
+	MissileSubScene missile;
+	while (amount < this->MAX_MISSILE_COUNT) {
+		missile.create(scn);
+		amount++;
+	}
+}
diff --git a/game/missile/MissilePool.h b/game/missile/MissilePool.h
new file mode 100644
index 0000000..296701e
--- /dev/null
+++ b/game/missile/MissilePool.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <crepe/api/Scene.h>
+
+class MissilePool {
+public:
+	MissilePool(crepe::Scene & scn);
+
+private:
+	static constexpr unsigned int MAX_MISSILE_COUNT = 5;
+};
diff --git a/game/missile/MissileScript.cpp b/game/missile/MissileScript.cpp
new file mode 100644
index 0000000..6d0e40e
--- /dev/null
+++ b/game/missile/MissileScript.cpp
@@ -0,0 +1,105 @@
+#include "MissileScript.h"
+#include "../Config.h"
+#include "api/BehaviorScript.h"
+
+#include <crepe/api/Animator.h>
+#include <crepe/api/AudioSource.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;
+
+void MissileScript::init() {
+	subscribe<CollisionEvent>([this](const CollisionEvent & ev) -> bool {
+		return this->on_collision(ev);
+	});
+	this->seeking_disabled = false;
+}
+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();
+
+	animations[0].get().active = false;
+	animations[1].get().active = false;
+	animations[2].get().active = true;
+	sprites[0].get().active = false;
+	sprites[1].get().active = false;
+	sprites[2].get().active = true;
+
+	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;
+}
+
+bool MissileScript::on_collision(const CollisionEvent & ev) {
+	auto & explosion_sound = this->get_components<AudioSource>().back().get();
+
+	this->kill_missile();
+	explosion_sound.play();
+
+	return false;
+}
+
+bool MissileScript::is_in_x_range(const Transform & missile, const Transform & player) {
+	return fabs(missile.position.x - player.position.x) <= this->X_RANGE;
+}
+
+void MissileScript::fixed_update(crepe::duration_t dt) {
+	auto & explosion_anim = this->get_components<Animator>().back().get();
+	auto & missile = this->get_component<Transform>();
+	auto & m_ai = this->get_component<AI>();
+
+	const auto & player = this->get_components_by_name<Transform>("player").front().get();
+	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;
+	}
+
+	if (this->seeking_disabled) {
+		m_ai.seek_off();
+	} else {
+		m_ai.seek_target = player.position;
+		m_ai.seek_on();
+
+		if (is_in_x_range(missile, player)) {
+			this->seeking_disabled = true;
+			m_ai.seek_off();
+		}
+	}
+
+	vec2 angle_pos = velocity;
+	float angle = atan2(angle_pos.y, angle_pos.x) * (180 / M_PI);
+
+	missile.rotation = angle;
+	missile.position += velocity * dt.count();
+}
diff --git a/game/missile/MissileScript.h b/game/missile/MissileScript.h
new file mode 100644
index 0000000..a492e18
--- /dev/null
+++ b/game/missile/MissileScript.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <crepe/api/Script.h>
+
+class MissileScript : public crepe::Script {
+private:
+	bool on_collision(const crepe::CollisionEvent & ev);
+
+	bool seeking_disabled;
+
+	// will be used to calculate when ai will be stopped
+	static constexpr int X_RANGE = 90;
+	bool is_in_x_range(const crepe::Transform & missile, const crepe::Transform & player);
+	void kill_missile();
+	void activate();
+
+public:
+	void init();
+	void fixed_update(crepe::duration_t dt);
+};
diff --git a/game/missile/MissileSubScene.cpp b/game/missile/MissileSubScene.cpp
new file mode 100644
index 0000000..db49f88
--- /dev/null
+++ b/game/missile/MissileSubScene.cpp
@@ -0,0 +1,101 @@
+#include "MissileSubScene.h"
+#include "../Config.h"
+#include "../missile/MissileScript.h"
+
+#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/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"};
+	Asset missle_thruster_ss {"asset/obstacles/missile/missileEffects.png"};
+	Asset missile_explosion_ss {"asset/obstacles/missile/missileExplosion.png"};
+	Asset explosion_sound {"asset/sfx/rocket_explode_1.ogg"};
+	Asset missile_fire {"asset/sfx/missile_launch.ogg"};
+
+	missle.add_component<BehaviorScript>().set_script<MissileScript>().active = false;
+
+	auto & sound = missle.add_component<AudioSource>(missile_fire);
+	sound.volume = 0.1;
+	auto & sound2 = missle.add_component<AudioSource>(explosion_sound);
+	sound2.volume = 0.1;
+
+	// sprites
+	auto & missle_sprite = missle.add_component<Sprite>(
+		missle_ss,
+		Sprite::Data {
+			.flip = {true, false},
+			.sorting_in_layer = SORT_IN_LAY_OBSTACLES,
+			.size = {0, 35},
+		}
+	);
+
+	auto & missle_thruster_sprite = missle.add_component<Sprite>(
+		missle_thruster_ss,
+		Sprite::Data {
+			.flip = {true, false},
+			.sorting_in_layer = SORT_IN_LAY_OBSTACLES,
+			.size = {0, 35},
+			.position_offset = {-20, 0},
+		}
+	);
+
+	auto & missile_explosion_sprite = missle.add_component<Sprite>(
+		missile_explosion_ss,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_OBSTACLES,
+			.size = {0, 50},
+		}
+	);
+
+	// Animations
+	missle.add_component<Animator>(
+		missle_sprite, ivec2 {32, 32}, uvec2 {4, 1},
+		Animator::Data {
+			.looping = true,
+		}
+	);
+
+	missle.add_component<Animator>(
+		missle_thruster_sprite, ivec2 {64, 64}, uvec2 {4, 2},
+		Animator::Data {
+			.looping = true,
+		}
+	);
+
+	auto & explosion_anim = missle.add_component<Animator>(
+		missile_explosion_sprite, ivec2 {64, 64}, uvec2 {8, 1},
+		Animator::Data {
+			.fps = 10,
+		}
+	);
+
+	missile_explosion_sprite.active = false;
+	explosion_anim.active = false;
+
+	std::uniform_int_distribution<> dist(140, 200);
+	missle.add_component<Rigidbody>(Rigidbody::Data {
+		.body_type = Rigidbody::BodyType::KINEMATIC,
+		.max_linear_velocity = static_cast<float>(dist(gen)),
+		.kinematic_collision = false,
+		.collision_layers = {COLL_LAY_PLAYER, COLL_LAY_BOT_TOP},
+		.collision_layer = COLL_LAY_MISSILE,
+	});
+
+	missle.add_component<CircleCollider>(3);
+
+	auto & missle_ai = missle.add_component<AI>(1000);
+}
diff --git a/game/missile/MissileSubScene.h b/game/missile/MissileSubScene.h
new file mode 100644
index 0000000..9ea422a
--- /dev/null
+++ b/game/missile/MissileSubScene.h
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace crepe {
+class Scene;
+}
+
+class MissileSubScene {
+public:
+	MissileSubScene() = default;
+
+	void create(crepe::Scene & scn);
+};
diff --git a/game/missile/SpawnEvent.cpp b/game/missile/SpawnEvent.cpp
new file mode 100644
index 0000000..03a9b8c
--- /dev/null
+++ b/game/missile/SpawnEvent.cpp
@@ -0,0 +1,47 @@
+#include "SpawnEvent.h"
+
+#include <crepe/api/Animator.h>
+#include <crepe/api/AudioSource.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Camera.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/api/Transform.h>
+
+#include <cstdlib>
+#include <random>
+
+using namespace crepe;
+
+void MissileSpawnEventHandler::init() {
+	subscribe<MissileSpawnEvent>([this](const MissileSpawnEvent & ev) -> bool {
+		return this->on_event(ev);
+	});
+}
+
+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 missile_transforms = this->get_components_by_name<Transform>("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();
+		if (script.active) continue;
+		script.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);
+
+		break;
+	}
+
+	return false;
+}
diff --git a/game/missile/SpawnEvent.h b/game/missile/SpawnEvent.h
new file mode 100644
index 0000000..ce301fd
--- /dev/null
+++ b/game/missile/SpawnEvent.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <crepe/api/Event.h>
+#include <crepe/api/Script.h>
+
+#include "../Config.h"
+
+struct MissileSpawnEvent : public crepe::Event {};
+
+class MissileSpawnEventHandler : public crepe::Script {
+private:
+	static constexpr int MISSILE_OFFSET = VIEWPORT_X / 1.8;
+	static constexpr int RANGE = GAME_HEIGHT / 4;
+	static constexpr int MIN_RANGE = -RANGE;
+	static constexpr int MAX_RANGE = RANGE;
+
+public:
+	void init();
+	bool on_event(const MissileSpawnEvent & ev);
+};
diff --git a/game/preview/NpcScript.cpp b/game/preview/NpcScript.cpp
new file mode 100644
index 0000000..c4148f2
--- /dev/null
+++ b/game/preview/NpcScript.cpp
@@ -0,0 +1,32 @@
+#include "NpcScript.h"
+
+#include <crepe/api/Sprite.h>
+#include <crepe/api/Transform.h>
+#include <crepe/manager/SaveManager.h>
+
+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 & transform = this->get_component<Transform>();
+
+	if (transform.position.x < -990) {
+		rb.data.linear_velocity.x *= -1;
+	}
+	if (transform.position.x > 990) {
+		rb.data.linear_velocity.x *= -1;
+	}
+
+	if (rb.data.linear_velocity.x < 0) {
+		npc.data.flip = {true, false};
+	} else {
+		npc.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
new file mode 100644
index 0000000..8d856fd
--- /dev/null
+++ b/game/preview/NpcScript.h
@@ -0,0 +1,11 @@
+
+#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
new file mode 100644
index 0000000..bd6cfb2
--- /dev/null
+++ b/game/preview/NpcSubScene.cpp
@@ -0,0 +1,69 @@
+
+
+#include "NpcSubScene.h"
+
+#include "../Config.h"
+#include "NpcScript.h"
+
+#include <crepe/ValueBroker.h>
+#include <crepe/api/Animator.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/manager/SaveManager.h>
+
+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);
+	Asset npc_body {"asset/workers/worker1Body.png"};
+	Asset npc_head {"asset/workers/worker1Head.png"};
+
+	auto & npc_body_sprite = npc.add_component<Sprite>(
+		npc_body,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.size = {0, 50},
+		}
+	);
+	auto & npc_head_sprite = npc.add_component<Sprite>(
+		npc_head,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.size = {0, 50},
+			.position_offset = {0, -20},
+		}
+	);
+
+	npc.add_component<Animator>(
+		npc_body_sprite, ivec2 {32, 32}, uvec2 {4, 8},
+		Animator::Data {
+			.fps = 5,
+			.looping = true,
+		}
+	);
+	npc.add_component<Animator>(
+		npc_head_sprite, ivec2 {32, 32}, uvec2 {4, 8},
+		Animator::Data {
+			.fps = 5,
+			.looping = true,
+		}
+	);
+	npc.add_component<BoxCollider>(vec2 {50, 50});
+
+	npc.add_component<Rigidbody>(Rigidbody::Data {
+		.mass = 10,
+		.gravity_scale = 1,
+		.body_type = Rigidbody::BodyType::DYNAMIC,
+		.linear_velocity = {-50, 0},
+		//.max_linear_velocity = 40,
+		.collision_layers = {COLL_LAY_BOT_TOP, COLL_LAY_PLAYER},
+		.collision_layer = COLL_LAY_PLAYER,
+	});
+
+	npc.add_component<BehaviorScript>().set_script<NpcScript>();
+}
diff --git a/game/preview/NpcSubScene.h b/game/preview/NpcSubScene.h
new file mode 100644
index 0000000..a226195
--- /dev/null
+++ b/game/preview/NpcSubScene.h
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace crepe {
+class Scene;
+}
+
+class NpcSubScene {
+public:
+	NpcSubScene(crepe::Scene & scn);
+};
diff --git a/game/preview/PrevPlayerScript.cpp b/game/preview/PrevPlayerScript.cpp
new file mode 100644
index 0000000..2657b8d
--- /dev/null
+++ b/game/preview/PrevPlayerScript.cpp
@@ -0,0 +1,132 @@
+#include "PrevPlayerScript.h"
+
+#include "../missile/SpawnEvent.h"
+#include "api/Transform.h"
+#include <crepe/api/AudioSource.h>
+#include <crepe/api/Camera.h>
+#include <crepe/manager/SaveManager.h>
+#include <iostream>
+#include <ostream>
+
+using namespace crepe;
+
+bool PrevPlayerScript::key_pressed(const KeyPressEvent & ev) {
+	switch (ev.key) {
+		case Keycode::A:
+			this->get_component<Rigidbody>().data.linear_velocity.x = -move_speed;
+			this->body->data.flip = {true, false};
+			this->head->data.flip = {true, false};
+			break;
+		case Keycode::D:
+			this->get_component<Rigidbody>().data.linear_velocity.x = move_speed;
+			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);
+			break;
+		case Keycode::D1:
+			this->body_anim->set_anim(1);
+			this->head_anim->set_anim(1);
+			break;
+		case Keycode::D2:
+			this->body_anim->set_anim(2);
+			this->head_anim->set_anim(2);
+			break;
+		case Keycode::D3:
+			this->body_anim->set_anim(3);
+			this->head_anim->set_anim(3);
+			break;
+		case Keycode::D4:
+			this->body_anim->set_anim(4);
+			this->head_anim->set_anim(4);
+			break;
+		case Keycode::D5:
+			this->body_anim->set_anim(5);
+			this->head_anim->set_anim(5);
+			break;
+		case Keycode::D6:
+			this->body_anim->set_anim(6);
+			this->head_anim->set_anim(6);
+			break;
+		case Keycode::D7:
+			this->body_anim->set_anim(7);
+			this->head_anim->set_anim(7);
+			break;
+		case Keycode::LEFT:
+			this->head->data.angle_offset -= 1;
+			break;
+		case Keycode::RIGHT:
+			this->head->data.angle_offset += 1;
+			break;
+		case Keycode::UP:
+			this->head->data.scale_offset += 0.1;
+			break;
+		case Keycode::DOWN:
+			this->head->data.scale_offset -= 0.1;
+			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;
+			break;
+		case Keycode::J:
+			this->get_components_by_name<Transform>("camera").front().get().position.x
+				-= move_speed;
+			break;
+		case Keycode::K:
+			this->get_components_by_name<Transform>("camera").front().get().position.y
+				-= move_speed;
+			break;
+		case Keycode::L:
+			this->get_components_by_name<Transform>("camera").front().get().position.x
+				+= move_speed;
+			break;
+		case Keycode::I:
+			this->get_components_by_name<Transform>("camera").front().get().position.y
+				+= move_speed;
+			break;
+		case Keycode::M:
+			trigger_event<MissileSpawnEvent>(MissileSpawnEvent {});
+			break;
+			//todo
+		case Keycode::PAGE_UP:
+		case Keycode::PAGE_DOWN:
+		case Keycode::HOME:
+			break;
+		default:
+			break;
+	}
+	return false;
+}
+
+void PrevPlayerScript::init() {
+	auto animations = this->get_components<Animator>();
+	body_anim = animations[0];
+	head_anim = animations[1];
+
+	auto sprites = this->get_components<Sprite>();
+	body = sprites[0];
+	head = sprites[1];
+
+	subscribe<KeyPressEvent>([this](const KeyPressEvent & ev) -> bool {
+		return this->key_pressed(ev);
+	});
+};
+
+void PrevPlayerScript::fixed_update(crepe::duration_t dt) {
+	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);
+};
diff --git a/game/preview/PrevPlayerScript.h b/game/preview/PrevPlayerScript.h
new file mode 100644
index 0000000..cc3184e
--- /dev/null
+++ b/game/preview/PrevPlayerScript.h
@@ -0,0 +1,23 @@
+
+#include <crepe/api/Event.h>
+#include <crepe/api/Script.h>
+#include <crepe/util/OptionalRef.h>
+
+#include <crepe/api/Animator.h>
+#include <crepe/api/Sprite.h>
+
+class PrevPlayerScript : public crepe::Script {
+private:
+	crepe::OptionalRef<crepe::Animator> head_anim;
+	crepe::OptionalRef<crepe::Animator> body_anim;
+	crepe::OptionalRef<crepe::Sprite> head;
+	crepe::OptionalRef<crepe::Sprite> body;
+
+private:
+	float move_speed = 100;
+
+private:
+	void init();
+	void fixed_update(crepe::duration_t dt);
+	bool key_pressed(const crepe::KeyPressEvent & ev);
+};
diff --git a/game/preview/PrevPlayerSubScene.cpp b/game/preview/PrevPlayerSubScene.cpp
new file mode 100644
index 0000000..b59a0af
--- /dev/null
+++ b/game/preview/PrevPlayerSubScene.cpp
@@ -0,0 +1,86 @@
+
+#include "PrevPlayerSubScene.h"
+
+#include "../Config.h"
+#include "PrevPlayerScript.h"
+
+#include <crepe/api/Animator.h>
+#include <crepe/api/AudioSource.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/Sprite.h>
+
+#include <crepe/ValueBroker.h>
+#include <crepe/manager/SaveManager.h>
+
+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);
+	Asset player_body_asset {"asset/barry/defaultBody.png"};
+	Sprite & player_body_sprite = player.add_component<Sprite>(
+		player_body_asset,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.order_in_layer = 0,
+			.size = vec2(0, 50),
+		}
+	);
+	player.add_component<Animator>(
+		player_body_sprite, ivec2(32, 32), uvec2(4, 8),
+		Animator::Data {
+			.fps = 5,
+			.looping = true,
+		}
+	);
+	Asset player_head_asset {"asset/barry/defaultHead.png"};
+	Sprite & player_head_sprite = player.add_component<Sprite>(
+		player_head_asset,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.order_in_layer = 1,
+			.size = vec2(0, 50),
+			.position_offset = vec2(0, -20),
+		}
+	);
+	player.add_component<Animator>(
+		player_head_sprite, ivec2(32, 32), uvec2(4, 8),
+		Animator::Data {
+			.fps = 5,
+			.looping = true,
+		}
+	);
+	Asset player_jetpack_asset {"asset/barry/jetpackDefault.png"};
+	Sprite & player_jetpack_sprite = player.add_component<Sprite>(
+		player_jetpack_asset,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_PLAYER,
+			.order_in_layer = 2,
+			.size = vec2(0, 60),
+			.position_offset = vec2(-20, 0),
+		}
+	);
+	player_jetpack_sprite.active = false;
+	player.add_component<Animator>(
+		player_jetpack_sprite, ivec2(32, 44), uvec2(4, 4),
+		Animator::Data {
+			.fps = 5,
+			.looping = true,
+		}
+	);
+	player.add_component<Rigidbody>(Rigidbody::Data {
+		.gravity_scale = 20,
+		.body_type = Rigidbody::BodyType::DYNAMIC,
+		.linear_velocity = vec2(100, 0),
+		.collision_layers = {COLL_LAY_BOT_TOP},
+		.collision_layer = COLL_LAY_PLAYER,
+	});
+	player.add_component<BoxCollider>(vec2(50, 50));
+	player.add_component<BehaviorScript>().set_script<PrevPlayerScript>();
+}
diff --git a/game/preview/PrevPlayerSubScene.h b/game/preview/PrevPlayerSubScene.h
new file mode 100644
index 0000000..a61f341
--- /dev/null
+++ b/game/preview/PrevPlayerSubScene.h
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace crepe {
+class Scene;
+}
+
+class PrevPlayerSubScene {
+public:
+	PrevPlayerSubScene(crepe::Scene & scn);
+};
diff --git a/game/preview/SmokeSubScene.cpp b/game/preview/SmokeSubScene.cpp
new file mode 100644
index 0000000..e363f95
--- /dev/null
+++ b/game/preview/SmokeSubScene.cpp
@@ -0,0 +1,37 @@
+
+#include "SmokeSubScene.h"
+
+#include "../Config.h"
+
+#include <crepe/api/ParticleEmitter.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/Sprite.h>
+
+using namespace crepe;
+
+SmokeSubScene::SmokeSubScene(Scene & scn) {
+	GameObject smoke = scn.new_object("smoke_particle", "TAG", vec2 {500, -210}, 0, 1);
+
+	Asset smoke_ss {"asset/particles/smoke.png"};
+
+	auto & smoke_sprite = smoke.add_component<Sprite>(
+		smoke_ss,
+		Sprite::Data {
+			.sorting_in_layer = SORT_IN_LAY_PARTICLES_FOREGROUND,
+			.size = {0, 30},
+		}
+	);
+
+	smoke.add_component<ParticleEmitter>(
+		smoke_sprite,
+		ParticleEmitter::Data {
+			.offset = {0, -60},
+			.max_particles = 10,
+			.emission_rate = 25,
+			.min_angle = 60,
+			.max_angle = 120,
+			.begin_lifespan = 1,
+			.end_lifespan = 2,
+		}
+	);
+}
diff --git a/game/preview/SmokeSubScene.h b/game/preview/SmokeSubScene.h
new file mode 100644
index 0000000..93d8a2d
--- /dev/null
+++ b/game/preview/SmokeSubScene.h
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace crepe {
+class Scene;
+}
+
+class SmokeSubScene {
+public:
+	SmokeSubScene(crepe::Scene & scn);
+};
diff --git a/game/scheduler/ObjectsScheduler.cpp b/game/scheduler/ObjectsScheduler.cpp
new file mode 100644
index 0000000..f354e70
--- /dev/null
+++ b/game/scheduler/ObjectsScheduler.cpp
@@ -0,0 +1,41 @@
+
+
+#include "ObjectsScheduler.h"
+
+#include "../Random.h"
+#include "../missile/SpawnEvent.h"
+#include "api/Transform.h"
+#include <iostream>
+
+using namespace crepe;
+
+void ObjectsScheduler::preset_0() { trigger_event<MissileSpawnEvent>(MissileSpawnEvent {}); }
+void ObjectsScheduler::preset_1() { trigger_event<MissileSpawnEvent>(MissileSpawnEvent {}); }
+void ObjectsScheduler::preset_2() {}
+void ObjectsScheduler::preset_3() {}
+void ObjectsScheduler::preset_4() {}
+void ObjectsScheduler::boss_fight_1() { std::cout << "Boss fight" << std::endl; }
+
+void ObjectsScheduler::init() {
+	this->obstacles.push_back([this]() { preset_0(); });
+	this->obstacles.push_back([this]() { preset_1(); });
+	this->obstacles.push_back([this]() { boss_fight_1(); });
+
+	// subscribe to battlewonevent
+}
+
+void ObjectsScheduler::fixed_update(duration_t dt) {
+	int pos_x
+		= (int) this->get_components_by_name<Transform>("camera").front().get().position.x;
+
+	int boss_check = (pos_x - this->start_offset) / this->boss_fight_interval;
+	if (boss_check > this->last_boss_check) {
+		this->obstacles[2]();
+		this->last_boss_check = boss_check;
+	}
+	int obstacle_check = (pos_x - this->start_offset) / this->obstacle_interval;
+	if (obstacle_check > this->last_obstacle_check) {
+		this->obstacles[Random::i(this->obstacles.size() - 1, 0)]();
+		this->last_obstacle_check = obstacle_check;
+	}
+}
diff --git a/game/scheduler/ObjectsScheduler.h b/game/scheduler/ObjectsScheduler.h
new file mode 100644
index 0000000..d2d0f55
--- /dev/null
+++ b/game/scheduler/ObjectsScheduler.h
@@ -0,0 +1,34 @@
+#pragma once
+
+
+
+#include "api/Script.h"
+#include <functional>
+#include <vector>
+
+
+class ObjectsScheduler : public crepe::Script {
+
+private:
+	std::vector<std::function<void()>> obstacles;
+	
+	int last_boss_check = 0;
+	int last_obstacle_check = 0;
+
+	int boss_fight_interval = 2000;
+	int obstacle_interval = 300;
+	int start_offset = 1300;
+
+
+	void preset_0();
+	void preset_1();
+	void preset_2();
+	void preset_3();
+	void preset_4();
+	void boss_fight_1();
+
+public:
+	void init();
+	void fixed_update(crepe::duration_t dt);
+
+};
-- 
cgit v1.2.3


From 0729209117a4393e66d7f5b6d83083e2d7c0694c Mon Sep 17 00:00:00 2001
From: heavydemon21 <nielsstunnebrink1@gmail.com>
Date: Wed, 8 Jan 2025 14:33:38 +0100
Subject: made my code work by adding it to the gamescene,main and config

---
 game/CMakeLists.txt      | 4 ++--
 game/GameScene.cpp       | 7 +++++++
 game/main.cpp            | 2 ++
 game/menus/MenusConfig.h | 2 +-
 4 files changed, 12 insertions(+), 3 deletions(-)

(limited to 'game/CMakeLists.txt')

diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index 47adb11..9251b2c 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -16,6 +16,7 @@ add_executable(main
 	background/ForestSubScene.cpp
 	background/HallwaySubScene.cpp
 	background/StartSubScene.cpp
+	background/HallwayScript.cpp
 
 	# mainscenes
 	GameScene.cpp
@@ -39,9 +40,9 @@ add_executable(main
 	preview/NpcScript.cpp
 	preview/PrevPlayerSubScene.cpp
 	preview/PrevPlayerScript.cpp
+	main.cpp
 
 	# scripts
-	background/HallwayScript.cpp
 	MoveCameraManualyScript.cpp
 	StartGameScript.cpp
 
@@ -58,7 +59,6 @@ add_executable(main
 	workers/CollisionScript.cpp
 
 	# menus
-	main.cpp
 	menus/BannerSubScene.cpp
 	menus/ButtonSubScene.cpp
 	menus/IButtonScript.cpp
diff --git a/game/GameScene.cpp b/game/GameScene.cpp
index 9376eab..f2471fc 100644
--- a/game/GameScene.cpp
+++ b/game/GameScene.cpp
@@ -10,7 +10,10 @@
 #include "hud/HudSubScene.h"
 #include "hud/SpeedScript.h"
 #include "menus/endgame/EndGameSubScene.h"
+#include "missile/MissilePool.h"
+#include "missile/SpawnEvent.h"
 #include "player/PlayerSubScene.h"
+#include "scheduler/ObjectsScheduler.h"
 #include "workers/WorkersSubScene.h"
 
 #include <cmath>
@@ -47,11 +50,15 @@ void GameScene::load_scene() {
 	camera.add_component<BehaviorScript>().set_script<CoinSystemScript>();
 	camera.add_component<BehaviorScript>().set_script<HudScript>();
 	camera.add_component<BehaviorScript>().set_script<SpeedScript>();
+	camera.add_component<BehaviorScript>().set_script<ObjectsScheduler>();
+	camera.add_component<BehaviorScript>().set_script<MissileSpawnEventHandler>();
 
 	camera.add_component<Rigidbody>(Rigidbody::Data {});
 
 	PlayerSubScene player(*this);
 
+	MissilePool missile_pool(*this);
+
 	WorkersSubScene workers(*this);
 
 	GameObject floor = new_object("floor", "game_world", vec2(0, 325));
diff --git a/game/main.cpp b/game/main.cpp
index e341353..5c050f4 100644
--- a/game/main.cpp
+++ b/game/main.cpp
@@ -2,6 +2,7 @@
 #include <crepe/api/Script.h>
 
 #include "GameScene.h"
+#include "PreviewScene.h"
 #include "menus/mainmenu/MainMenuScene.h"
 #include "menus/shop/ShopMenuScene.h"
 
@@ -12,6 +13,7 @@ int main() {
 	gameloop.add_scene<MainMenuScene>();
 	gameloop.add_scene<ShopMenuScene>();
 	gameloop.add_scene<GameScene>();
+	gameloop.add_scene<PreviewScene>();
 
 	return gameloop.main();
 }
diff --git a/game/menus/MenusConfig.h b/game/menus/MenusConfig.h
index 6ec5689..968f8cc 100644
--- a/game/menus/MenusConfig.h
+++ b/game/menus/MenusConfig.h
@@ -6,7 +6,7 @@ static constexpr int STARTING_SORTING_IN_LAYER = 7;
 static constexpr const char * CAMERA_NAME = "camera";
 //Scene names
 static constexpr const char * START_SCENE = "scene1";
-static constexpr const char * PREVIEW_SCENE = "scene1";
+static constexpr const char * PREVIEW_SCENE = "preview scene";
 static constexpr const char * SHOP_SCENE = "shopmenu";
 static constexpr const char * MAINMENU_SCENE = "mainmenu";
 //button config
-- 
cgit v1.2.3


From d989c1c51bf4d4fbb301493e73bc77e1873143b2 Mon Sep 17 00:00:00 2001
From: heavydemon21 <nielsstunnebrink1@gmail.com>
Date: Wed, 8 Jan 2025 14:51:10 +0100
Subject: working zapper, missilies with scheduler

---
 game/CMakeLists.txt                 | 7 +------
 game/menus/MenusConfig.h            | 1 -
 game/prefab/ZapperPoolScript.cpp    | 4 ----
 game/scheduler/ObjectsScheduler.cpp | 6 ++++--
 game/scheduler/ObjectsScheduler.h   | 2 +-
 5 files changed, 6 insertions(+), 14 deletions(-)

(limited to 'game/CMakeLists.txt')

diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index dec161d..d1f49ed 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -10,7 +10,7 @@ add_subdirectory(../src crepe)
 
 add_executable(main)
 
-add_executable(main PUBLIC
+target_sources(main PUBLIC
 	#background
 	background/AquariumSubScene.cpp
 	background/AquariumScript.cpp
@@ -43,13 +43,8 @@ add_executable(main PUBLIC
 	preview/NpcScript.cpp
 	preview/PrevPlayerSubScene.cpp
 	preview/PrevPlayerScript.cpp
-	main.cpp
 
 	# scripts
-
-add_executable(main)
-
-target_sources(main PUBLIC
 	GameScene.cpp
 	MoveCameraManualyScript.cpp
 	StartGameScript.cpp
diff --git a/game/menus/MenusConfig.h b/game/menus/MenusConfig.h
index 968f8cc..3e357a5 100644
--- a/game/menus/MenusConfig.h
+++ b/game/menus/MenusConfig.h
@@ -3,7 +3,6 @@
 
 //generic menu config
 static constexpr int STARTING_SORTING_IN_LAYER = 7;
-static constexpr const char * CAMERA_NAME = "camera";
 //Scene names
 static constexpr const char * START_SCENE = "scene1";
 static constexpr const char * PREVIEW_SCENE = "preview scene";
diff --git a/game/prefab/ZapperPoolScript.cpp b/game/prefab/ZapperPoolScript.cpp
index ac6ce96..b9b2a76 100644
--- a/game/prefab/ZapperPoolScript.cpp
+++ b/game/prefab/ZapperPoolScript.cpp
@@ -30,10 +30,6 @@ void ZapperPoolScript::fixed_update(crepe::duration_t) {
 		if (zapper.transform.position.x < threshold)
 			zapper.set_active(false);
 	}
-
-	if (i-- > 0) return;
-	i = 200;
-	queue_event<CreateZapperEvent>();
 }
 
 void ZapperPoolScript::spawn_random() {
diff --git a/game/scheduler/ObjectsScheduler.cpp b/game/scheduler/ObjectsScheduler.cpp
index f354e70..21465e3 100644
--- a/game/scheduler/ObjectsScheduler.cpp
+++ b/game/scheduler/ObjectsScheduler.cpp
@@ -5,13 +5,13 @@
 #include "../Random.h"
 #include "../missile/SpawnEvent.h"
 #include "api/Transform.h"
+#include "prefab/ZapperPoolSubScene.h"
 #include <iostream>
 
 using namespace crepe;
-
 void ObjectsScheduler::preset_0() { trigger_event<MissileSpawnEvent>(MissileSpawnEvent {}); }
 void ObjectsScheduler::preset_1() { trigger_event<MissileSpawnEvent>(MissileSpawnEvent {}); }
-void ObjectsScheduler::preset_2() {}
+void ObjectsScheduler::preset_2() { trigger_event<CreateZapperEvent>(CreateZapperEvent {}); }
 void ObjectsScheduler::preset_3() {}
 void ObjectsScheduler::preset_4() {}
 void ObjectsScheduler::boss_fight_1() { std::cout << "Boss fight" << std::endl; }
@@ -19,6 +19,8 @@ void ObjectsScheduler::boss_fight_1() { std::cout << "Boss fight" << std::endl;
 void ObjectsScheduler::init() {
 	this->obstacles.push_back([this]() { preset_0(); });
 	this->obstacles.push_back([this]() { preset_1(); });
+	this->obstacles.push_back([this]() { preset_2(); });
+
 	this->obstacles.push_back([this]() { boss_fight_1(); });
 
 	// subscribe to battlewonevent
diff --git a/game/scheduler/ObjectsScheduler.h b/game/scheduler/ObjectsScheduler.h
index d2d0f55..7bc9337 100644
--- a/game/scheduler/ObjectsScheduler.h
+++ b/game/scheduler/ObjectsScheduler.h
@@ -15,7 +15,7 @@ private:
 	int last_boss_check = 0;
 	int last_obstacle_check = 0;
 
-	int boss_fight_interval = 2000;
+	int boss_fight_interval = 2500;
 	int obstacle_interval = 300;
 	int start_offset = 1300;
 
-- 
cgit v1.2.3