diff --git a/.gitignore b/.gitignore index ee8655c..b5b5a15 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ build xcode-build .cache macos +TODO.txt +design.txt +compile_commands.json diff --git a/assets/game_finish_btn.aseprite b/assets/game_finish_btn.aseprite deleted file mode 100644 index ae3bf94..0000000 Binary files a/assets/game_finish_btn.aseprite and /dev/null differ diff --git a/include/game/component.hpp b/include/game/component.hpp index dc5604c..01024a6 100644 --- a/include/game/component.hpp +++ b/include/game/component.hpp @@ -50,6 +50,7 @@ public: this->type = type; rotation = 0; alive = true; + liveTime = 0; } inline void Release() override {} @@ -59,6 +60,7 @@ public: Entity* target; float rotation; bool alive; + float liveTime; }; diff --git a/include/game/constants.hpp b/include/game/constants.hpp index 6fa40d9..bbd5fd0 100644 --- a/include/game/constants.hpp +++ b/include/game/constants.hpp @@ -25,7 +25,7 @@ constexpr int CoreEnergyProductAmount = 1; constexpr Size GameWindowSize = {1024, 720}; -constexpr Rect BulletRefreshArea{-100, -100, 1124, 820}; +constexpr float BulletDieTime = 10; constexpr int BlockSize = 16; constexpr int PlayerGroup = 0; diff --git a/include/game/init_info.hpp b/include/game/init_info.hpp index 692d511..e5fc505 100644 --- a/include/game/init_info.hpp +++ b/include/game/init_info.hpp @@ -8,5 +8,6 @@ enum PlaneType { struct GameInitInfo { int planeType; int groupNum; - int planeNum; + int fightShipNum; + int freightShipNum; }; diff --git a/include/game/stages/space.hpp b/include/game/stages/space.hpp index 8f046de..0f1c653 100644 --- a/include/game/stages/space.hpp +++ b/include/game/stages/space.hpp @@ -38,7 +38,7 @@ private: void renderWeapons(SpaceshipWeaponCmpt* weapon1, SpaceshipWeaponCmpt* weapon2); void initEnemies(); void attachController(); - void generateEnemiesAt(int group, const Point& p, int num); + void generateEnemiesAt(int group, const Point& p, int fightShipNum, int freightShipNum); void initPlayer(); void calcGroupHps(); void drawGroupHp(); diff --git a/include/game/system.hpp b/include/game/system.hpp index 470f23c..1d02edb 100644 --- a/include/game/system.hpp +++ b/include/game/system.hpp @@ -14,12 +14,13 @@ private: void physicalStep(Entity* entity, float dt, MoveCmpt&, MotionCmpt&); }; -class MissileUpdateSystem: public UpdateSystem { +class BulletUpdateSystem: public UpdateSystem { public: void Update(float dt) override; private: void updateMissile(float dt, BulletCmpt&, MoveCmpt&, MotionCmpt&); + void updateBulletLife(float dt, BulletCmpt&); }; class ColliRectCorrectSystem: public UpdateSystem { diff --git a/src/game/controllers/freightship_controller.cpp b/src/game/controllers/freightship_controller.cpp index b3601ea..a2d49ba 100644 --- a/src/game/controllers/freightship_controller.cpp +++ b/src/game/controllers/freightship_controller.cpp @@ -27,13 +27,12 @@ void FreightShipController::Update(float dt) { if (IsLeftPressing()) { auto weapon = entity_->Use()->weapon; if (weapon) { - // FIXME duplicated codes in here and fightship_controller.cpp if (weapon->type == SpaceshipWeaponCmpt::Orientation) { Shoot(*weapon, Rotate(Point{0, -1}, entity_->Get()->degree)); } else { Shoot(*weapon, - GetMousePosition() - GameWindowSize / 2); + GetMousePositionMapped() - GameWindowSize / 2); } } } diff --git a/src/game/init_info.cpp b/src/game/init_info.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/game/stages/select.cpp b/src/game/stages/select.cpp index bf2a001..766f92e 100644 --- a/src/game/stages/select.cpp +++ b/src/game/stages/select.cpp @@ -5,15 +5,15 @@ #include "game/stages/space.hpp" void SelectScence::OnInit() { - // TODO move it to welcome stage - LoadResources(); + Renderer::SetClearColor(Color{0.1, 0.1, 0.1, 1}); switchBtn_.reset(new Texture("assets/switch_btn.png")); goBtn_.reset(new Texture("assets/go_btn.png")); Renderer::SetCamera(camera_); InitInfo.planeType = 1; - InitInfo.planeNum = 5; + InitInfo.fightShipNum = 3; + InitInfo.freightShipNum = 2; InitInfo.groupNum = 2; } @@ -83,7 +83,11 @@ void SelectScence::renderSelectShip() { void SelectScence::renderProperties() { auto& font = engine.GetInnerBmpFont(); - if (InitInfo.planeType == 1) { + if (InitInfo.planeType == FreightShip) { + font.Render("FREIGHT SHIP", + 20, + Point{80, 380}, + Color{0.8, 0.1, 0.8, 1}); font.Render("HP: " + std::to_string(FreightShipLife), 20, Point{80, 400}, @@ -108,7 +112,11 @@ void SelectScence::renderProperties() { 20, Point{80, 500}, Color{0, 0.7, 0.7, 1}); - } else if (InitInfo.planeType == 2) { + } else if (InitInfo.planeType == FightShip) { + font.Render("FIGHT SHIP", + 20, + Point{80, 380}, + Color{0.8, 0.1, 0.8, 1}); font.Render("HP: " + std::to_string(FightShipLife), 20, Point{80, 400}, @@ -158,22 +166,41 @@ void SelectScence::renderGroupNumPanel() { void SelectScence::renderPlaneNumPanel() { auto& font = engine.GetInnerBmpFont(); - font.Render("PLANE NUMBER:", + + font.Render("FIGHTSHIPS:", 20, Point{600, 400}, Color{0.3, 0.6, 0.8, 1}); if (Button(switchBtn_.get(), Point{870, 410}, Size{switchBtn_->GetSize().w, 20})) { - InitInfo.planeNum --; - if (InitInfo.planeNum <= 0) - InitInfo.planeNum = 100; + InitInfo.fightShipNum --; + if (InitInfo.fightShipNum <= 0) + InitInfo.fightShipNum = 100; } - font.Render(std::to_string(InitInfo.planeNum), 20, Point{890, 400}, Color{0.6, 0.3, 0.8, 1}); + font.Render(std::to_string(InitInfo.fightShipNum), 20, Point{890, 400}, Color{0.6, 0.3, 0.8, 1}); if (Button(switchBtn_.get(), Point{960, 410}, Size{switchBtn_->GetSize().w, 20}, true)) { - InitInfo.planeNum ++; - if (InitInfo.planeNum > 100) - InitInfo.planeNum = 1; + InitInfo.fightShipNum ++; + if (InitInfo.fightShipNum> 100) + InitInfo.fightShipNum = 1; } + + font.Render("FREIGHTSHIPS:", + 20, + Point{600, 420}, + Color{0.3, 0.6, 0.8, 1}); + + if (Button(switchBtn_.get(), Point{870, 430}, Size{switchBtn_->GetSize().w, 20})) { + InitInfo.freightShipNum --; + if (InitInfo.freightShipNum <= 0) + InitInfo.freightShipNum = 100; + } + font.Render(std::to_string(InitInfo.freightShipNum), 20, Point{890, 420}, Color{0.6, 0.3, 0.8, 1}); + if (Button(switchBtn_.get(), Point{960, 430}, Size{switchBtn_->GetSize().w, 20}, true)) { + InitInfo.freightShipNum ++; + if (InitInfo.freightShipNum> 100) + InitInfo.freightShipNum = 1; + } + } void SelectScence::renderGoBtn() { diff --git a/src/game/stages/space.cpp b/src/game/stages/space.cpp index cae2772..229ca32 100644 --- a/src/game/stages/space.cpp +++ b/src/game/stages/space.cpp @@ -1,4 +1,6 @@ #include "game/stages/space.hpp" +#include "game/gui.hpp" +#include "game/stages/select.hpp" void SpaceScence::OnInit() { Renderer::SetClearColor(Color{0, 0, 0, 255}); @@ -15,8 +17,7 @@ void SpaceScence::OnInit() { SystemMgr.Clear(); SystemMgr.AddUpdateSystem(new AIUpdateSystem); SystemMgr.AddUpdateSystem(new WeaponCooldownSystem); - SystemMgr.AddUpdateSystem(new EnergyProductSystem); - SystemMgr.AddUpdateSystem(new MissileUpdateSystem); + SystemMgr.AddUpdateSystem(new BulletUpdateSystem); SystemMgr.AddUpdateSystem(new PhysicalSystem); SystemMgr.AddUpdateSystem(new ColliRectCorrectSystem); SystemMgr.AddUpdateSystem(new CollideSystem); @@ -57,27 +58,36 @@ void SpaceScence::initPlayer() { } void SpaceScence::initEnemies() { - generateEnemiesAt(PlayerGroup, Point{0, 0}, InitInfo.planeNum - 1); + if (InitInfo.planeType == FightShip) { + generateEnemiesAt(PlayerGroup, Point{0, 0}, InitInfo.fightShipNum - 1, InitInfo.freightShipNum); + } else { + generateEnemiesAt(PlayerGroup, Point{0, 0}, InitInfo.fightShipNum, InitInfo.freightShipNum - 1); + } if (InitInfo.groupNum == 2) { - generateEnemiesAt(Enemy1Group, Point{0, -720 * 4}, InitInfo.planeNum); + generateEnemiesAt(Enemy1Group, Point{0, -720 * 4}, InitInfo.fightShipNum, InitInfo.freightShipNum); } else if (InitInfo.groupNum == 3) { - generateEnemiesAt(Enemy1Group, Point{-720 * 4, -720 * 4}, InitInfo.planeNum); - generateEnemiesAt(Enemy2Group, Point{720 * 4, -720 * 4}, InitInfo.planeNum); + generateEnemiesAt(Enemy1Group, Point{-720 * 4, -720 * 4}, InitInfo.fightShipNum, InitInfo.freightShipNum); + generateEnemiesAt(Enemy2Group, Point{720 * 4, -720 * 4}, InitInfo.fightShipNum, InitInfo.freightShipNum); } else if (InitInfo.groupNum == 4) { - generateEnemiesAt(Enemy1Group, Point{0, -720 * 4}, InitInfo.planeNum); - generateEnemiesAt(Enemy2Group, Point{720 * 4, 0}, InitInfo.planeNum); - generateEnemiesAt(Enemy3Group, Point{720 * 4, -720 * 4}, InitInfo.planeNum); + generateEnemiesAt(Enemy1Group, Point{0, -720 * 4}, InitInfo.fightShipNum, InitInfo.freightShipNum); + generateEnemiesAt(Enemy2Group, Point{720 * 4, 0}, InitInfo.fightShipNum, InitInfo.freightShipNum); + generateEnemiesAt(Enemy3Group, Point{720 * 4, -720 * 4}, InitInfo.fightShipNum, InitInfo.freightShipNum); } else { Log("group num invalid"); } } -void SpaceScence::generateEnemiesAt(int group, const Point& p, int num) { - for (int i = 0; i < num; i++) { +void SpaceScence::generateEnemiesAt(int group, const Point& p, int fightShipNum, int freightShipNum) { + for (int i = 0; i < freightShipNum; i++) { Entity* enemy = CreateFreightShip(group); enemy->Add(FreightShipAI); - // Entity* enemy = CreateFightShip(group); - // enemy->Add(FightShipAI); + enemy->Use()->position += p + Point{Random(-400, 400), Random(-100, 100)}; + Entities.Add(enemy); + Groups[group].Add(enemy); + } + for (int i = 0; i < fightShipNum; i++) { + Entity* enemy = CreateFightShip(group); + enemy->Add(FightShipAI); enemy->Use()->position += p + Point{Random(-400, 400), Random(-100, 100)}; Entities.Add(enemy); Groups[group].Add(enemy); @@ -85,8 +95,14 @@ void SpaceScence::generateEnemiesAt(int group, const Point& p, int num) { } void SpaceScence::OnUpdate(float dt) { - controller_->Update(dt); + if (PlayerSpaceship && PlayerSpaceship->IsAlive()) { + controller_->Update(dt); + } SystemMgr.Update(dt); + + if (PlayerSpaceship && !PlayerSpaceship->IsAlive()) { + PlayerSpaceship = nullptr; + } if (lookAtEntity_ && lookAtEntity_->IsAlive()) { gameCamera_.MoveTo(lookAtEntity_->Get()->position); @@ -105,6 +121,17 @@ void SpaceScence::OnUpdate(float dt) { attachController(); } } + + if (Groups[PlayerGroup].Empty()) { + mode_ = Lost; + } + bool win = true; + for (int i = 1; i < 4; i++) { + win = win && Groups[i].Empty(); + } + if (win) { + mode_ = Win; + } } void SpaceScence::attachController() { @@ -122,6 +149,20 @@ void SpaceScence::OnRender() { Renderer::SetCamera(guiCamera_); renderGUI(); + + auto& font = engine.GetInnerBmpFont(); + if (mode_ == Win) { + font.Render("WIN", 40, GameWindowSize / 2 - Point{60, 60}, Color{0, 1, 0, 1}); + } else if (mode_ == Lost) { + font.Render("LOST", 40, GameWindowSize / 2 - Point{80, 60}, Color{1, 0, 0, 1}); + } + if (mode_ != Gaming) { + std::string msg = "PRESS SPACE TO RESTART"; + font.Render(msg, 20, GameWindowSize / 2 - Point{msg.length() * 20 / 2.0f, 0}, Color{1, 1, 1, 1}); + if (IsKeyPressing(GLFW_KEY_SPACE)) { + engine.ChangeScence(new SelectScence); + } + } } void SpaceScence::renderBackground() { @@ -202,17 +243,15 @@ void SpaceScence::renderMiniMap() { if (!PlayerSpaceship || !PlayerSpaceship->IsAlive()) { return; } - + 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 entityOnMapPos = (pos - PlayerSpaceship->Get()->position) * Size{mapRect.w, mapRect.h} / (GameWindowSize * 8) + 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}); + if (entity->Has()) { + Renderer::SetDrawColor(GroupSpecColor[entity->Get()->groupIdx]); } Renderer::FillRect(Rect{entityOnMapPos.x - 1, entityOnMapPos.y - 1, 2, 2}); } diff --git a/src/game/stages/welcome.cpp b/src/game/stages/welcome.cpp index d589863..4862308 100644 --- a/src/game/stages/welcome.cpp +++ b/src/game/stages/welcome.cpp @@ -2,8 +2,11 @@ #include "game/gui.hpp" #include "game/constants.hpp" #include "game/stages/select.hpp" +#include "game/global.hpp" void WelcomeScence::OnInit() { + Renderer::SetClearColor(Color{0.1, 0.1, 0.1, 1}); + startImage_.reset(new Texture("assets/start_btn.png")); exitImage_.reset(new Texture("assets/exit_btn.png")); @@ -12,6 +15,8 @@ void WelcomeScence::OnInit() { auto cursor = glfwCreateCursor(&image, image.width / 2, image.height / 2); glfwSetCursor(engine.GetWindow(), cursor); stbi_image_free(image.pixels); + + LoadResources(); } void WelcomeScence::OnRender() { diff --git a/src/game/system.cpp b/src/game/system.cpp index 31f6864..28c311b 100644 --- a/src/game/system.cpp +++ b/src/game/system.cpp @@ -36,7 +36,7 @@ void PhysicalSystem::physicalStep(Entity* entity, motionCmpt.acceleration = Point{0, 0}; } -void MissileUpdateSystem::Update(float dt) { +void BulletUpdateSystem::Update(float dt) { for (auto& bullet : Bullets) { if (bullet->Get()->type == BulletCmpt::Missile) { updateMissile(dt, @@ -44,10 +44,11 @@ void MissileUpdateSystem::Update(float dt) { *bullet->Use(), *bullet->Use()); } + updateBulletLife(dt, *bullet->Use()); } } -void MissileUpdateSystem::updateMissile(float dt, +void BulletUpdateSystem::updateMissile(float dt, BulletCmpt& bullet, MoveCmpt& move, MotionCmpt& motion) { @@ -68,6 +69,10 @@ void MissileUpdateSystem::updateMissile(float dt, } } +void BulletUpdateSystem::updateBulletLife(float dt, BulletCmpt& bullet) { + bullet.liveTime += dt; +} + void ColliRectCorrectSystem::Update(float dt) { for (auto& entity: Entities) { if (entity->Has()) { @@ -124,8 +129,7 @@ void CleanupSystem::Update(float dt) { Bullets.RemoveAll([](const EntityPtr& entity){ return !entity->Get()->alive || - !IsPointInRect(MapGlobal2PlayerCoord(entity->Get()->position), - BulletRefreshArea); + entity->Get()->liveTime >= BulletDieTime; }, destroyFunc); Entities.RemoveAll([&](const EntityPtr& entity){