diff options
Diffstat (limited to 'game/prefab')
-rw-r--r-- | game/prefab/CMakeLists.txt | 6 | ||||
-rw-r--r-- | game/prefab/ZapperObject.cpp | 122 | ||||
-rw-r--r-- | game/prefab/ZapperObject.h | 40 | ||||
-rw-r--r-- | game/prefab/ZapperPoolScript.cpp | 69 | ||||
-rw-r--r-- | game/prefab/ZapperPoolScript.h | 33 | ||||
-rw-r--r-- | game/prefab/ZapperPoolSubScene.cpp | 19 | ||||
-rw-r--r-- | game/prefab/ZapperPoolSubScene.h | 19 |
7 files changed, 308 insertions, 0 deletions
diff --git a/game/prefab/CMakeLists.txt b/game/prefab/CMakeLists.txt new file mode 100644 index 0000000..6c36ef2 --- /dev/null +++ b/game/prefab/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(main PUBLIC + ZapperObject.cpp + ZapperPoolSubScene.cpp + ZapperPoolScript.cpp +) + diff --git a/game/prefab/ZapperObject.cpp b/game/prefab/ZapperObject.cpp new file mode 100644 index 0000000..0a290e0 --- /dev/null +++ b/game/prefab/ZapperObject.cpp @@ -0,0 +1,122 @@ +#include <crepe/api/Transform.h> + +#include "Config.h" +#include "ZapperObject.h" + +using namespace crepe; + +ZapperObject::ZapperObject(crepe::GameObject && base) + : GameObject(std::move(base)), + sprite { + .orb_start = add_component<Sprite>( + Asset {"asset/obstacles/zapper/orbAnim.png"}, + Sprite::Data { + .sorting_in_layer = SORT_IN_LAY_OBSTACLES, + .order_in_layer = 1, + .size = vec2(0, 50) * SCALE, + } + ), + .orb_end = add_component<Sprite>( + sprite.orb_start.source, + Sprite::Data { + .flip = {true, true}, + .sorting_in_layer = SORT_IN_LAY_OBSTACLES, + .order_in_layer = 1, + .size = vec2(0, 50) * SCALE, + } + ), + .glow_start = add_component<Sprite>( + Asset {"asset/obstacles/zapper/regular_zappers/glow.png"}, + Sprite::Data { + .sorting_in_layer = SORT_IN_LAY_OBSTACLES, + .order_in_layer = -1, + .size = vec2(128, 128) * SCALE, + } + ), + .glow_end = add_component<Sprite>( + sprite.glow_start.source, + Sprite::Data { + .flip = {true, true}, + .sorting_in_layer = SORT_IN_LAY_OBSTACLES, + .order_in_layer = -1, + .size = vec2(128, 128) * SCALE, + } + ), + .beam = add_component<Sprite>( + Asset {"asset/obstacles/zapper/regular_zappers/zapEffect.png"}, + Sprite::Data { + .sorting_in_layer = SORT_IN_LAY_OBSTACLES, + .order_in_layer = 0, + .size = vec2(0, 40 * SCALE), + .angle_offset = 90, + } + ), + }, + animator { + .orb_start = add_component<Animator>( + sprite.orb_start, ivec2(62, 42), uvec2(4, 1), + Animator::Data { + .fps = 10, + .looping = true, + } + ), + .orb_end = add_component<Animator>( + sprite.orb_end, ivec2(62, 42), uvec2(4, 1), animator.orb_start.data + ), + .glow_start = add_component<Animator>( + sprite.glow_start, ivec2(128, 128), uvec2(16, 1), + Animator::Data { + .fps = 30, + .looping = true, + } + ), + .glow_end = add_component<Animator>( + sprite.glow_end, ivec2(128, 128), uvec2(16, 1), animator.glow_start.data + ), + }, + body {add_component<Rigidbody>(Rigidbody::Data { + .body_type = Rigidbody::BodyType::KINEMATIC, + .kinematic_collision = false, + .collision_layer = COLL_LAY_ZAPPER, + })}, + collider {add_component<BoxCollider>(vec2(0, 0))} { + this->set_active(false); + Log::logf(Log::DEBUG, "Creating zapper"); +} + +void ZapperObject::place(const crepe::vec2 & position, float rotation, float length) { + Log::logf(Log::DEBUG, "Placing zapper [position = {}, rotation = {}, length = {}]", position, rotation, length); + + this->transform.position = position; + this->transform.rotation = rotation; + + vec2 offset = vec2(0, 1) * length / 2; + + this->sprite.orb_start.data.position_offset = offset; + this->sprite.glow_start.data.position_offset = offset; + this->sprite.orb_end.data.position_offset = -offset; + this->sprite.glow_end.data.position_offset = -offset; + + this->sprite.beam.data.size.x = length; + + this->collider.dimensions = offset.rotate(rotation) * 2 + vec2(30, 30) * SCALE; +} + +void ZapperObject::set_active(bool active) { + this->sprite.orb_start.active = active; + this->sprite.orb_end.active = active; + this->sprite.glow_start.active = active; + this->sprite.glow_end.active = active; + this->sprite.beam.active = active; + + this->animator.orb_start.active = active; + this->animator.orb_end.active = active; + this->animator.glow_start.active = active; + this->animator.glow_end.active = active; + + this->body.active = active; + this->collider.active = active; + + this->active = active; +} + diff --git a/game/prefab/ZapperObject.h b/game/prefab/ZapperObject.h new file mode 100644 index 0000000..42edc51 --- /dev/null +++ b/game/prefab/ZapperObject.h @@ -0,0 +1,40 @@ +#pragma once + +#include <crepe/api/Animator.h> +#include <crepe/api/BoxCollider.h> +#include <crepe/api/GameObject.h> +#include <crepe/api/Rigidbody.h> +#include <crepe/api/Sprite.h> + +class ZapperObject : public crepe::GameObject { +public: + ZapperObject(crepe::GameObject &&); + +public: + bool active = true; + + struct { + crepe::Sprite & orb_start; + crepe::Sprite & orb_end; + crepe::Sprite & glow_start; + crepe::Sprite & glow_end; + crepe::Sprite & beam; + } sprite; + + struct { + crepe::Animator & orb_start; + crepe::Animator & orb_end; + crepe::Animator & glow_start; + crepe::Animator & glow_end; + } animator; + + crepe::Rigidbody & body; + crepe::BoxCollider & collider; + +private: + static constexpr float SCALE = 0.8; + +public: + void place(const crepe::vec2 & position, float rotation, float length); + void set_active(bool active); +}; diff --git a/game/prefab/ZapperPoolScript.cpp b/game/prefab/ZapperPoolScript.cpp new file mode 100644 index 0000000..b9b2a76 --- /dev/null +++ b/game/prefab/ZapperPoolScript.cpp @@ -0,0 +1,69 @@ +#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; + +ZapperPoolScript::ZapperPoolScript(std::vector<ZapperObject> && pool) : pool(pool) {} + +void ZapperPoolScript::init() { + subscribe<CreateZapperEvent>([this](const CreateZapperEvent &) { + this->spawn_random(); + return true; + }); + + camera_transform = get_components_by_name<Transform>(CAMERA_NAME).back(); + camera_camera = get_components_by_name<Camera>(CAMERA_NAME).back(); +} + +void ZapperPoolScript::fixed_update(crepe::duration_t) { + float threshold = camera_transform->position.x - camera_camera->viewport_size.x / 2 - OFFSCREEN_MARGIN; + for (ZapperObject & zapper : this->pool) { + if (!zapper.active) continue; + + if (zapper.transform.position.x < threshold) + zapper.set_active(false); + } +} + +void ZapperPoolScript::spawn_random() { + OptionalRef<ZapperObject> zapper = this->get_next_zapper(); + if (!zapper) return; // pool exhausted + + vec2 pos = { + .x = camera_transform->position.x + camera_camera->viewport_size.x / 2 + OFFSCREEN_MARGIN, + .y = Random::f(0.5, -0.5) * HALLWAY_HEIGHT, + }; + + bool horizontal = Random::b(); + float rotation, length; + + if (horizontal) { + rotation = 90; + length = Random::f(400, 200); + } else { + rotation = 0; + length = Random::f(200, 50); + if (abs(pos.y) + length / 2 > HALLWAY_HEIGHT / 2) { + // TODO: fix offset + } + } + + zapper->place(pos, rotation, length); + zapper->set_active(true); +} + +OptionalRef<ZapperObject> ZapperPoolScript::get_next_zapper() { + for (ZapperObject & zapper : this->pool) { + if (zapper.active) continue; + return zapper; + } + return {}; +} + diff --git a/game/prefab/ZapperPoolScript.h b/game/prefab/ZapperPoolScript.h new file mode 100644 index 0000000..6aee8b2 --- /dev/null +++ b/game/prefab/ZapperPoolScript.h @@ -0,0 +1,33 @@ +#pragma once + +#include <crepe/api/Script.h> + +#include "ZapperObject.h" +#include "util/OptionalRef.h" + +class ZapperPoolSubScene; + +class ZapperPoolScript : public crepe::Script { +public: + ZapperPoolScript(std::vector<ZapperObject> && pool); + + void init(); + void fixed_update(crepe::duration_t); + + unsigned i = 0; + +private: + std::vector<ZapperObject> pool; + +private: + crepe::OptionalRef<crepe::Transform> camera_transform; + crepe::OptionalRef<crepe::Camera> camera_camera; + crepe::OptionalRef<ZapperObject> get_next_zapper(); + +private: + void spawn_random(); + +private: + static constexpr float OFFSCREEN_MARGIN = 40; +}; + diff --git a/game/prefab/ZapperPoolSubScene.cpp b/game/prefab/ZapperPoolSubScene.cpp new file mode 100644 index 0000000..e341090 --- /dev/null +++ b/game/prefab/ZapperPoolSubScene.cpp @@ -0,0 +1,19 @@ +#include <crepe/api/BehaviorScript.h> + +#include "ZapperPoolSubScene.h" +#include "ZapperPoolScript.h" + +using namespace crepe; +using namespace std; + +ZapperPoolSubScene::ZapperPoolSubScene(Scene & scene) + : controller { scene.new_object("controller") } { + + Log::logf(Log::DEBUG, "Building zapper pool..."); + vector<ZapperObject> pool; + for (size_t i = 0; i < this->POOL_SIZE; i++) + pool.emplace_back(scene.new_object("zapper", "zapper")); + BehaviorScript & behavior = this->controller.add_component<BehaviorScript>(); + behavior.set_script<ZapperPoolScript>(std::move(pool)); +} + diff --git a/game/prefab/ZapperPoolSubScene.h b/game/prefab/ZapperPoolSubScene.h new file mode 100644 index 0000000..f930e22 --- /dev/null +++ b/game/prefab/ZapperPoolSubScene.h @@ -0,0 +1,19 @@ +#pragma once + +#include <crepe/api/Scene.h> +#include <crepe/api/GameObject.h> +#include <crepe/api/Event.h> +#include <crepe/util/OptionalRef.h> + +class CreateZapperEvent : public crepe::Event {}; + +class ZapperPoolSubScene { +public: + ZapperPoolSubScene(crepe::Scene & scene); + +private: + crepe::GameObject controller; + +private: + static constexpr size_t POOL_SIZE = 4; +}; |