add restart btn

This commit is contained in:
VisualGMQ 2022-02-17 16:54:05 +08:00
parent cb6a442fa1
commit 831e767cf9
13 changed files with 124 additions and 43 deletions

3
.gitignore vendored
View File

@ -4,3 +4,6 @@ build
xcode-build xcode-build
.cache .cache
macos macos
TODO.txt
design.txt
compile_commands.json

Binary file not shown.

View File

@ -50,6 +50,7 @@ public:
this->type = type; this->type = type;
rotation = 0; rotation = 0;
alive = true; alive = true;
liveTime = 0;
} }
inline void Release() override {} inline void Release() override {}
@ -59,6 +60,7 @@ public:
Entity* target; Entity* target;
float rotation; float rotation;
bool alive; bool alive;
float liveTime;
}; };

View File

@ -25,7 +25,7 @@ constexpr int CoreEnergyProductAmount = 1;
constexpr Size GameWindowSize = {1024, 720}; constexpr Size GameWindowSize = {1024, 720};
constexpr Rect BulletRefreshArea{-100, -100, 1124, 820}; constexpr float BulletDieTime = 10;
constexpr int BlockSize = 16; constexpr int BlockSize = 16;
constexpr int PlayerGroup = 0; constexpr int PlayerGroup = 0;

View File

@ -8,5 +8,6 @@ enum PlaneType {
struct GameInitInfo { struct GameInitInfo {
int planeType; int planeType;
int groupNum; int groupNum;
int planeNum; int fightShipNum;
int freightShipNum;
}; };

View File

@ -38,7 +38,7 @@ private:
void renderWeapons(SpaceshipWeaponCmpt* weapon1, SpaceshipWeaponCmpt* weapon2); void renderWeapons(SpaceshipWeaponCmpt* weapon1, SpaceshipWeaponCmpt* weapon2);
void initEnemies(); void initEnemies();
void attachController(); 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 initPlayer();
void calcGroupHps(); void calcGroupHps();
void drawGroupHp(); void drawGroupHp();

View File

@ -14,12 +14,13 @@ private:
void physicalStep(Entity* entity, float dt, MoveCmpt&, MotionCmpt&); void physicalStep(Entity* entity, float dt, MoveCmpt&, MotionCmpt&);
}; };
class MissileUpdateSystem: public UpdateSystem { class BulletUpdateSystem: public UpdateSystem {
public: public:
void Update(float dt) override; void Update(float dt) override;
private: private:
void updateMissile(float dt, BulletCmpt&, MoveCmpt&, MotionCmpt&); void updateMissile(float dt, BulletCmpt&, MoveCmpt&, MotionCmpt&);
void updateBulletLife(float dt, BulletCmpt&);
}; };
class ColliRectCorrectSystem: public UpdateSystem { class ColliRectCorrectSystem: public UpdateSystem {

View File

@ -27,13 +27,12 @@ void FreightShipController::Update(float dt) {
if (IsLeftPressing()) { if (IsLeftPressing()) {
auto weapon = entity_->Use<FreightShipCmpt>()->weapon; auto weapon = entity_->Use<FreightShipCmpt>()->weapon;
if (weapon) { if (weapon) {
// FIXME duplicated codes in here and fightship_controller.cpp
if (weapon->type == SpaceshipWeaponCmpt::Orientation) { if (weapon->type == SpaceshipWeaponCmpt::Orientation) {
Shoot(*weapon, Shoot(*weapon,
Rotate(Point{0, -1}, entity_->Get<FightShipCmpt>()->degree)); Rotate(Point{0, -1}, entity_->Get<FightShipCmpt>()->degree));
} else { } else {
Shoot(*weapon, Shoot(*weapon,
GetMousePosition() - GameWindowSize / 2); GetMousePositionMapped() - GameWindowSize / 2);
} }
} }
} }

View File

View File

@ -5,15 +5,15 @@
#include "game/stages/space.hpp" #include "game/stages/space.hpp"
void SelectScence::OnInit() { void SelectScence::OnInit() {
// TODO move it to welcome stage Renderer::SetClearColor(Color{0.1, 0.1, 0.1, 1});
LoadResources();
switchBtn_.reset(new Texture("assets/switch_btn.png")); switchBtn_.reset(new Texture("assets/switch_btn.png"));
goBtn_.reset(new Texture("assets/go_btn.png")); goBtn_.reset(new Texture("assets/go_btn.png"));
Renderer::SetCamera(camera_); Renderer::SetCamera(camera_);
InitInfo.planeType = 1; InitInfo.planeType = 1;
InitInfo.planeNum = 5; InitInfo.fightShipNum = 3;
InitInfo.freightShipNum = 2;
InitInfo.groupNum = 2; InitInfo.groupNum = 2;
} }
@ -83,7 +83,11 @@ void SelectScence::renderSelectShip() {
void SelectScence::renderProperties() { void SelectScence::renderProperties() {
auto& font = engine.GetInnerBmpFont(); 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), font.Render("HP: " + std::to_string(FreightShipLife),
20, 20,
Point{80, 400}, Point{80, 400},
@ -108,7 +112,11 @@ void SelectScence::renderProperties() {
20, 20,
Point{80, 500}, Point{80, 500},
Color{0, 0.7, 0.7, 1}); 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), font.Render("HP: " + std::to_string(FightShipLife),
20, 20,
Point{80, 400}, Point{80, 400},
@ -158,22 +166,41 @@ void SelectScence::renderGroupNumPanel() {
void SelectScence::renderPlaneNumPanel() { void SelectScence::renderPlaneNumPanel() {
auto& font = engine.GetInnerBmpFont(); auto& font = engine.GetInnerBmpFont();
font.Render("PLANE NUMBER:",
font.Render("FIGHTSHIPS:",
20, 20,
Point{600, 400}, Point{600, 400},
Color{0.3, 0.6, 0.8, 1}); Color{0.3, 0.6, 0.8, 1});
if (Button(switchBtn_.get(), Point{870, 410}, Size{switchBtn_->GetSize().w, 20})) { if (Button(switchBtn_.get(), Point{870, 410}, Size{switchBtn_->GetSize().w, 20})) {
InitInfo.planeNum --; InitInfo.fightShipNum --;
if (InitInfo.planeNum <= 0) if (InitInfo.fightShipNum <= 0)
InitInfo.planeNum = 100; 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)) { if (Button(switchBtn_.get(), Point{960, 410}, Size{switchBtn_->GetSize().w, 20}, true)) {
InitInfo.planeNum ++; InitInfo.fightShipNum ++;
if (InitInfo.planeNum > 100) if (InitInfo.fightShipNum> 100)
InitInfo.planeNum = 1; 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() { void SelectScence::renderGoBtn() {

View File

@ -1,4 +1,6 @@
#include "game/stages/space.hpp" #include "game/stages/space.hpp"
#include "game/gui.hpp"
#include "game/stages/select.hpp"
void SpaceScence::OnInit() { void SpaceScence::OnInit() {
Renderer::SetClearColor(Color{0, 0, 0, 255}); Renderer::SetClearColor(Color{0, 0, 0, 255});
@ -15,8 +17,7 @@ void SpaceScence::OnInit() {
SystemMgr.Clear(); SystemMgr.Clear();
SystemMgr.AddUpdateSystem(new AIUpdateSystem); SystemMgr.AddUpdateSystem(new AIUpdateSystem);
SystemMgr.AddUpdateSystem(new WeaponCooldownSystem); SystemMgr.AddUpdateSystem(new WeaponCooldownSystem);
SystemMgr.AddUpdateSystem(new EnergyProductSystem); SystemMgr.AddUpdateSystem(new BulletUpdateSystem);
SystemMgr.AddUpdateSystem(new MissileUpdateSystem);
SystemMgr.AddUpdateSystem(new PhysicalSystem); SystemMgr.AddUpdateSystem(new PhysicalSystem);
SystemMgr.AddUpdateSystem(new ColliRectCorrectSystem); SystemMgr.AddUpdateSystem(new ColliRectCorrectSystem);
SystemMgr.AddUpdateSystem(new CollideSystem); SystemMgr.AddUpdateSystem(new CollideSystem);
@ -57,27 +58,36 @@ void SpaceScence::initPlayer() {
} }
void SpaceScence::initEnemies() { 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) { 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) { } else if (InitInfo.groupNum == 3) {
generateEnemiesAt(Enemy1Group, 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.planeNum); generateEnemiesAt(Enemy2Group, Point{720 * 4, -720 * 4}, InitInfo.fightShipNum, InitInfo.freightShipNum);
} else if (InitInfo.groupNum == 4) { } else if (InitInfo.groupNum == 4) {
generateEnemiesAt(Enemy1Group, Point{0, -720 * 4}, InitInfo.planeNum); generateEnemiesAt(Enemy1Group, Point{0, -720 * 4}, InitInfo.fightShipNum, InitInfo.freightShipNum);
generateEnemiesAt(Enemy2Group, Point{720 * 4, 0}, InitInfo.planeNum); generateEnemiesAt(Enemy2Group, Point{720 * 4, 0}, InitInfo.fightShipNum, InitInfo.freightShipNum);
generateEnemiesAt(Enemy3Group, Point{720 * 4, -720 * 4}, InitInfo.planeNum); generateEnemiesAt(Enemy3Group, Point{720 * 4, -720 * 4}, InitInfo.fightShipNum, InitInfo.freightShipNum);
} else { } else {
Log("group num invalid"); Log("group num invalid");
} }
} }
void SpaceScence::generateEnemiesAt(int group, const Point& p, int num) { void SpaceScence::generateEnemiesAt(int group, const Point& p, int fightShipNum, int freightShipNum) {
for (int i = 0; i < num; i++) { for (int i = 0; i < freightShipNum; i++) {
Entity* enemy = CreateFreightShip(group); Entity* enemy = CreateFreightShip(group);
enemy->Add<AICmpt>(FreightShipAI); enemy->Add<AICmpt>(FreightShipAI);
// Entity* enemy = CreateFightShip(group); enemy->Use<MoveCmpt>()->position += p + Point{Random<float>(-400, 400), Random<float>(-100, 100)};
// enemy->Add<AICmpt>(FightShipAI); Entities.Add(enemy);
Groups[group].Add(enemy);
}
for (int i = 0; i < fightShipNum; i++) {
Entity* enemy = CreateFightShip(group);
enemy->Add<AICmpt>(FightShipAI);
enemy->Use<MoveCmpt>()->position += p + Point{Random<float>(-400, 400), Random<float>(-100, 100)}; enemy->Use<MoveCmpt>()->position += p + Point{Random<float>(-400, 400), Random<float>(-100, 100)};
Entities.Add(enemy); Entities.Add(enemy);
Groups[group].Add(enemy); Groups[group].Add(enemy);
@ -85,9 +95,15 @@ void SpaceScence::generateEnemiesAt(int group, const Point& p, int num) {
} }
void SpaceScence::OnUpdate(float dt) { void SpaceScence::OnUpdate(float dt) {
if (PlayerSpaceship && PlayerSpaceship->IsAlive()) {
controller_->Update(dt); controller_->Update(dt);
}
SystemMgr.Update(dt); SystemMgr.Update(dt);
if (PlayerSpaceship && !PlayerSpaceship->IsAlive()) {
PlayerSpaceship = nullptr;
}
if (lookAtEntity_ && lookAtEntity_->IsAlive()) { if (lookAtEntity_ && lookAtEntity_->IsAlive()) {
gameCamera_.MoveTo(lookAtEntity_->Get<MoveCmpt>()->position); gameCamera_.MoveTo(lookAtEntity_->Get<MoveCmpt>()->position);
} else { } else {
@ -105,6 +121,17 @@ void SpaceScence::OnUpdate(float dt) {
attachController(); 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() { void SpaceScence::attachController() {
@ -122,6 +149,20 @@ void SpaceScence::OnRender() {
Renderer::SetCamera(guiCamera_); Renderer::SetCamera(guiCamera_);
renderGUI(); 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() { void SpaceScence::renderBackground() {
@ -206,13 +247,11 @@ void SpaceScence::renderMiniMap() {
for (auto& entity: Entities) { for (auto& entity: Entities) {
if (entity != PlayerSpaceship) { if (entity != PlayerSpaceship) {
const auto& pos = entity->Get<MoveCmpt>()->position; const auto& pos = entity->Get<MoveCmpt>()->position;
Point entityOnMapPos = (pos - PlayerSpaceship->Get<MoveCmpt>()->position) * Size{mapRect.w, mapRect.h} / GameWindowSize + Point entityOnMapPos = (pos - PlayerSpaceship->Get<MoveCmpt>()->position) * Size{mapRect.w, mapRect.h} / (GameWindowSize * 8) +
Point{mapRect.x, mapRect.y} + Size{mapRect.w, mapRect.h} / 2; Point{mapRect.x, mapRect.y} + Size{mapRect.w, mapRect.h} / 2;
if (IsPointInRect(entityOnMapPos, mapRect)) { if (IsPointInRect(entityOnMapPos, mapRect)) {
if (entity->Has<FreightShipCmpt>()) { if (entity->Has<GroupCmpt>()) {
Renderer::SetDrawColor(Color{255, 255, 255, 255}); Renderer::SetDrawColor(GroupSpecColor[entity->Get<GroupCmpt>()->groupIdx]);
} else {
Renderer::SetDrawColor(Color{0, 0, 255, 255});
} }
Renderer::FillRect(Rect{entityOnMapPos.x - 1, entityOnMapPos.y - 1, 2, 2}); Renderer::FillRect(Rect{entityOnMapPos.x - 1, entityOnMapPos.y - 1, 2, 2});
} }

View File

@ -2,8 +2,11 @@
#include "game/gui.hpp" #include "game/gui.hpp"
#include "game/constants.hpp" #include "game/constants.hpp"
#include "game/stages/select.hpp" #include "game/stages/select.hpp"
#include "game/global.hpp"
void WelcomeScence::OnInit() { void WelcomeScence::OnInit() {
Renderer::SetClearColor(Color{0.1, 0.1, 0.1, 1});
startImage_.reset(new Texture("assets/start_btn.png")); startImage_.reset(new Texture("assets/start_btn.png"));
exitImage_.reset(new Texture("assets/exit_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); auto cursor = glfwCreateCursor(&image, image.width / 2, image.height / 2);
glfwSetCursor(engine.GetWindow(), cursor); glfwSetCursor(engine.GetWindow(), cursor);
stbi_image_free(image.pixels); stbi_image_free(image.pixels);
LoadResources();
} }
void WelcomeScence::OnRender() { void WelcomeScence::OnRender() {

View File

@ -36,7 +36,7 @@ void PhysicalSystem::physicalStep(Entity* entity,
motionCmpt.acceleration = Point{0, 0}; motionCmpt.acceleration = Point{0, 0};
} }
void MissileUpdateSystem::Update(float dt) { void BulletUpdateSystem::Update(float dt) {
for (auto& bullet : Bullets) { for (auto& bullet : Bullets) {
if (bullet->Get<BulletCmpt>()->type == BulletCmpt::Missile) { if (bullet->Get<BulletCmpt>()->type == BulletCmpt::Missile) {
updateMissile(dt, updateMissile(dt,
@ -44,10 +44,11 @@ void MissileUpdateSystem::Update(float dt) {
*bullet->Use<MoveCmpt>(), *bullet->Use<MoveCmpt>(),
*bullet->Use<MotionCmpt>()); *bullet->Use<MotionCmpt>());
} }
updateBulletLife(dt, *bullet->Use<BulletCmpt>());
} }
} }
void MissileUpdateSystem::updateMissile(float dt, void BulletUpdateSystem::updateMissile(float dt,
BulletCmpt& bullet, BulletCmpt& bullet,
MoveCmpt& move, MoveCmpt& move,
MotionCmpt& motion) { 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) { void ColliRectCorrectSystem::Update(float dt) {
for (auto& entity: Entities) { for (auto& entity: Entities) {
if (entity->Has<CollisionCmpt, MoveCmpt>()) { if (entity->Has<CollisionCmpt, MoveCmpt>()) {
@ -124,8 +129,7 @@ void CleanupSystem::Update(float dt) {
Bullets.RemoveAll([](const EntityPtr& entity){ Bullets.RemoveAll([](const EntityPtr& entity){
return !entity->Get<BulletCmpt>()->alive || return !entity->Get<BulletCmpt>()->alive ||
!IsPointInRect(MapGlobal2PlayerCoord(entity->Get<MoveCmpt>()->position), entity->Get<BulletCmpt>()->liveTime >= BulletDieTime;
BulletRefreshArea);
}, destroyFunc); }, destroyFunc);
Entities.RemoveAll([&](const EntityPtr& entity){ Entities.RemoveAll([&](const EntityPtr& entity){