diff --git a/include/game/constants.hpp b/include/game/constants.hpp index d66736c..ee3fcc4 100644 --- a/include/game/constants.hpp +++ b/include/game/constants.hpp @@ -1,11 +1,16 @@ #pragma once +#include "tinyengine/libmath.hpp" + constexpr float FreightShipMaxSpeed = 100; -constexpr float FightShipMaxSpeed = 300; +constexpr float FightShipMaxSpeed = 250; constexpr int FreightLife = 10; constexpr float LazerDamage = 2; constexpr float LazerShooterSpeed = 500; constexpr float LazerShooterMaxSpeed = 1000; constexpr float LazerShooterCooldown = 0.3; -constexpr int GameWindowWidth = 1024; -constexpr int GameWindowHeight = 720; + +constexpr Size GameWindowSize = {1024, 720}; + +constexpr Rect BulletRefreshArea{-100, -100, 1124, 820}; +constexpr Rect SpaceshipRefreshArea{-1024 * 3, -720 * 3, 1024 * 4, 720 * 4}; diff --git a/include/game/global.hpp b/include/game/global.hpp index bb226e5..0e38b9a 100644 --- a/include/game/global.hpp +++ b/include/game/global.hpp @@ -9,7 +9,9 @@ extern Unique GameTileSheet; extern std::unordered_map> Sounds; extern QuickList Bullets; - extern QuickList Entities; +extern Entity* PlayerSpaceship; + void LoadResources(); +Point MapGlobal2PlayerCoord(const Point& pos); diff --git a/include/game/stages/gamelogo.hpp b/include/game/stages/gamelogo.hpp index 79178ce..309e27c 100644 --- a/include/game/stages/gamelogo.hpp +++ b/include/game/stages/gamelogo.hpp @@ -7,7 +7,7 @@ public: void OnRender() override; private: - Camera camera; + Camera camera_; float initTime_; Unique sound_; bool soundPlayed_; diff --git a/include/game/stages/space.hpp b/include/game/stages/space.hpp index d837121..c44cb3b 100644 --- a/include/game/stages/space.hpp +++ b/include/game/stages/space.hpp @@ -15,11 +15,11 @@ public: void OnQuit() override; private: - Entity* spaceship_; Unique freightController_; Unique fightController_; void renderGUI(); + void renderMiniMap(); Camera guiCamera_; Camera gameCamera_; diff --git a/include/tinyengine/camera.hpp b/include/tinyengine/camera.hpp index 555767a..f74cc8a 100644 --- a/include/tinyengine/camera.hpp +++ b/include/tinyengine/camera.hpp @@ -9,11 +9,13 @@ public: void MoveTo(const Point& pos); /* scale screen in [1.0, 2.0] */ void Scale(const Point& scale); + void SetAnchor(const Point& anchor); bool TryCalcView(); private: Mat44 viewMat_; Point position_ = {0, 0}; Point scale_ = {1, 1}; - bool dirty_ = false; + Point anchor_ = {0, 0}; + bool dirty_ = true; }; diff --git a/include/tinyengine/renderer.hpp b/include/tinyengine/renderer.hpp index d100664..0e022a2 100644 --- a/include/tinyengine/renderer.hpp +++ b/include/tinyengine/renderer.hpp @@ -47,7 +47,6 @@ public: static void SetViewport(int x, int y, int w, int h); static const Color& GetDrawColor(); static void SetCamera(Camera& camera); - static void Update(); private: static Color color_; diff --git a/src/game/action.cpp b/src/game/action.cpp index eb00025..3665e26 100644 --- a/src/game/action.cpp +++ b/src/game/action.cpp @@ -5,7 +5,8 @@ void Shoot(SpaceshipWeaponCmpt& weapon, const Point& dir) { Point playerCenterPos = weapon.owner->Get()->position; - auto bullet = weapon.ShootBullet(dir); + Entity* bullet; + bullet = weapon.ShootBullet(dir); Bullets.Add(bullet); weapon.coolDown = weapon.shootDuration; diff --git a/src/game/controllers/fightship_controller.cpp b/src/game/controllers/fightship_controller.cpp index d69495e..511cec7 100644 --- a/src/game/controllers/fightship_controller.cpp +++ b/src/game/controllers/fightship_controller.cpp @@ -26,8 +26,14 @@ void FightShipController::Update(float dt) { if (IsLeftPressing()) { if (entity_->Has()) { - Shoot(*entity_->Use(), - GetMousePosition() - entity_->Get()->position); + auto weapon = entity_->Use(); + if (weapon->type == SpaceshipWeaponCmpt::Orientation) { + Shoot(*weapon, + Rotate(Point{0, -1}, -entity_->Get()->degree)); + } else { + Shoot(*weapon, + GetMousePosition() - entity_->Get()->position); + } } } } diff --git a/src/game/controllers/freightship_controller.cpp b/src/game/controllers/freightship_controller.cpp index 86df5eb..583703b 100644 --- a/src/game/controllers/freightship_controller.cpp +++ b/src/game/controllers/freightship_controller.cpp @@ -30,8 +30,15 @@ void FreightShipController::Update(float dt) { if (IsLeftPressing()) { if (entity_->Has()) { - Shoot(*entity_->Use(), - GetMousePosition() - entity_->Get()->position); + // FIXME duplicated codes in here and fightship_controller.cpp + auto weapon = entity_->Use(); + if (weapon->type == SpaceshipWeaponCmpt::Orientation) { + Shoot(*weapon, + Rotate(Point{0, -1}, entity_->Get()->degree)); + } else { + Shoot(*weapon, + GetMousePosition() - entity_->Get()->position); + } } } } diff --git a/src/game/entity.cpp b/src/game/entity.cpp index 8c548a7..ccb248f 100644 --- a/src/game/entity.cpp +++ b/src/game/entity.cpp @@ -6,7 +6,7 @@ Entity* CreateFreightShip() { entity->Add(Point{0, 0}); entity->Add(Point{0, 0}, FreightShipMaxSpeed); entity->Add(GameTileSheet->GetTile(0, 0)); - entity->Add(SpaceshipWeaponCmpt::Orientation, + entity->Add(SpaceshipWeaponCmpt::FreeRotation, entity, LazerDamage, LazerShooterSpeed, diff --git a/src/game/global.cpp b/src/game/global.cpp index 9e1819f..ebd357c 100644 --- a/src/game/global.cpp +++ b/src/game/global.cpp @@ -1,12 +1,16 @@ #include "game/global.hpp" +#include "game/component.hpp" Context ECSContext; SystemManager SystemMgr; Unique GameTileSheet; std::unordered_map> Sounds; + QuickList Bullets; QuickList Entities; +Entity* PlayerSpaceship; + void loadImages() { GameTileSheet.reset(new TileSheet("assets/tilesheet.png", 8, 8)); } @@ -19,3 +23,11 @@ void LoadResources() { loadImages(); loadSounds(); } + +Point MapGlobal2PlayerCoord(const Point& pos) { + if (PlayerSpaceship && PlayerSpaceship->Has()) { + return pos - PlayerSpaceship->Get()->position + GameWindowSize / 2; + } else { + return pos; + } +} diff --git a/src/game/main.cpp b/src/game/main.cpp index b0ab3cb..901e4a9 100644 --- a/src/game/main.cpp +++ b/src/game/main.cpp @@ -2,4 +2,4 @@ #include "game/stages/space.hpp" #include "game/constants.hpp" -RUN_WINDOW("Space Sector", GameWindowWidth, GameWindowHeight, SpaceScence) +RUN_WINDOW("Space Sector", GameWindowSize.w, GameWindowSize.h, SpaceScence) diff --git a/src/game/stages/gamelogo.cpp b/src/game/stages/gamelogo.cpp index dc2839b..31937aa 100644 --- a/src/game/stages/gamelogo.cpp +++ b/src/game/stages/gamelogo.cpp @@ -10,6 +10,8 @@ void GameLogoScence::OnInit() { initTime_ = GetTime(); sound_.reset(new Sound("assets/1mgame_sound.wav")); soundPlayed_ = false; + + Renderer::SetCamera(camera_); } void GameLogoScence::OnRender() { diff --git a/src/game/stages/space.cpp b/src/game/stages/space.cpp index 226db14..66aba08 100644 --- a/src/game/stages/space.cpp +++ b/src/game/stages/space.cpp @@ -4,9 +4,12 @@ void SpaceScence::OnInit() { Renderer::SetClearColor(Color{0, 0, 0, 255}); LoadResources(); - spaceship_ = CreateFightShip(); - Entities.Add(spaceship_); - spaceship_->Use()->position = Point{400, 400}; + Entities.Clear(); + Bullets.Clear(); + + PlayerSpaceship = CreateFightShip(); + Entities.Add(PlayerSpaceship); + PlayerSpaceship->Use()->position = Point{400, 400}; Entity* enemy = CreateFreightShip(); enemy->Use()->position = Point{100, 100}; @@ -21,7 +24,9 @@ void SpaceScence::OnInit() { Entities.Add(enemy); // freightController_.reset(new FreightShipController(spaceship_)); - fightController_.reset(new FightShipController(spaceship_)); + fightController_.reset(new FightShipController(PlayerSpaceship)); + + gameCamera_.SetAnchor(GameWindowSize / 2); SystemMgr.Clear(); SystemMgr.AddUpdateSystem(new BulletCooldownSystem); @@ -35,22 +40,53 @@ void SpaceScence::OnInit() { void SpaceScence::OnUpdate(float dt) { fightController_->Update(dt); SystemMgr.Update(dt); + gameCamera_.MoveTo(PlayerSpaceship->Get()->position); } void SpaceScence::OnRender() { Renderer::SetCamera(gameCamera_); SystemMgr.Render(); + + Renderer::SetCamera(guiCamera_); renderGUI(); } void SpaceScence::renderGUI() { Renderer::SetCamera(guiCamera_); - auto life = spaceship_->Get()->hp; + auto life = PlayerSpaceship->Get()->hp; float xOffset = 16 * life; for (int i = 0; i < life; i++) { Renderer::DrawTile(GameTileSheet->GetTile(1, 1), - Point{GameWindowWidth - xOffset + i * 16, 8}); + Point{GameWindowSize.w - xOffset + i * 16, 8}); + } + + renderMiniMap(); +} + +void SpaceScence::renderMiniMap() { + Rect mapRect = {1, 0, 100, 100}; + mapRect.y = GameWindowSize.h - mapRect.h; + + Renderer::SetDrawColor(Color{0, 0, 0, 255}); + Renderer::FillRect(mapRect); + Renderer::SetDrawColor(Color{255, 255, 255, 255}); + Renderer::DrawRect(mapRect); + + for (auto& entity: Entities) { + if (entity != PlayerSpaceship) { + const auto& pos = entity->Get()->position; + Point entityOnMapPos = (pos - PlayerSpaceship->Get()->position) * Size{mapRect.w, mapRect.h} / GameWindowSize + + Point{mapRect.x, mapRect.y} + Size{mapRect.w, mapRect.h} / 2; + if (IsPointInRect(entityOnMapPos, mapRect)) { + if (entity->Has()) { + Renderer::SetDrawColor(Color{255, 255, 255, 255}); + } else { + Renderer::SetDrawColor(Color{0, 0, 255, 255}); + } + Renderer::FillRect(Rect{entityOnMapPos.x - 1, entityOnMapPos.y - 1, 2, 2}); + } + } } } diff --git a/src/game/system.cpp b/src/game/system.cpp index 674b56d..f045f00 100644 --- a/src/game/system.cpp +++ b/src/game/system.cpp @@ -75,21 +75,26 @@ void CollideSystem::Update(float dt) { void CleanupSystem::Update(float dt) { using EntityPtr = Entity*; + auto destroyFunc = [&](const EntityPtr& entity){ + ECSContext.DestroyEntity(entity); + }; + Bullets.RemoveAll([](const EntityPtr& entity){ - return !entity->Get()->alive || !IsPointInRect(entity->Get()->position, - Rect{0, 0, GameWindowWidth, GameWindowHeight}); - }); + return !entity->Get()->alive || + !IsPointInRect(MapGlobal2PlayerCoord(entity->Get()->position), + BulletRefreshArea); + }, destroyFunc); + Entities.RemoveAll([](const EntityPtr& entity){ if (entity->Has() && - entity->Get()->hp <= 0) { + entity->Get()->hp <= 0 || + entity->Has() && + !IsPointInRect(MapGlobal2PlayerCoord(entity->Get()->position), SpaceshipRefreshArea)) { return true; } else { return false; } - }, - [&](const EntityPtr& entity){ - ECSContext.DestroyEntity(entity); - }); + }, destroyFunc); } void BulletCooldownSystem::Update(float dt) { diff --git a/src/tinyengine/camera.cpp b/src/tinyengine/camera.cpp index c484974..430f24a 100644 --- a/src/tinyengine/camera.cpp +++ b/src/tinyengine/camera.cpp @@ -3,8 +3,8 @@ bool Camera::TryCalcView() { if (dirty_) { viewMat_ = Mat44({ - scale_.x, 0, 0, -position_.x, - 0, scale_.y, 0, -position_.y, + scale_.x, 0, 0, -position_.x + anchor_.x, + 0, scale_.y, 0, -position_.y + anchor_.y, 0, 0, 1, 0, 0, 0, 0, 1, }); @@ -30,3 +30,8 @@ void Camera::Scale(const Point& scale) { scale_.y = Clamp(1.0f, 2.0f, scale.y); dirty_ = true; } + +void Camera::SetAnchor(const Point& anchor) { + anchor_ = anchor; + dirty_ = true; +} diff --git a/src/tinyengine/engine.cpp b/src/tinyengine/engine.cpp index d0ed153..614be92 100644 --- a/src/tinyengine/engine.cpp +++ b/src/tinyengine/engine.cpp @@ -89,7 +89,6 @@ void Engine::Shutdown() { void Engine::Update(float deltaTime) { if (scence_) scence_->OnUpdate(deltaTime); - Renderer::Update(); } void Engine::Render() { diff --git a/src/tinyengine/renderer.cpp b/src/tinyengine/renderer.cpp index 188e6f7..0e1b808 100644 --- a/src/tinyengine/renderer.cpp +++ b/src/tinyengine/renderer.cpp @@ -229,14 +229,8 @@ void Renderer::SetViewport(int x, int y, int w, int h) { void Renderer::SetCamera(Camera& camera) { Context.camera = &camera; -} - -void Renderer::Update() { - if (Context.camera && Context.camera->TryCalcView()) { - Context.shader->SetMat4("view", Context.camera->GetView()); - } else { - Context.shader->SetMat4("view", Mat44::Eye); - } + Context.camera->TryCalcView(); + Context.shader->SetMat4("view", Context.camera->GetView()); } void Renderer::Shutdown() {