fixed fight ship ai bug; improved freight ship
This commit is contained in:
parent
559cfda2da
commit
945ee99e41
|
@ -0,0 +1,42 @@
|
||||||
|
![welcome](./snapshot/welcome.png)
|
||||||
|
|
||||||
|
开始界面,上方按钮进入游戏,下方按钮退出游戏
|
||||||
|
|
||||||
|
|
||||||
|
![select-ship](./snapshot/select_ship.png)
|
||||||
|
|
||||||
|
选择飞船和配置阵营界面。左边选择你的飞船(目前只有两架),右边可以配置阵营:
|
||||||
|
|
||||||
|
* `Group Number`:要参战的队伍(最少2队,最多4队)
|
||||||
|
* `Plane Number`:每队的飞船数目
|
||||||
|
|
||||||
|
机种:
|
||||||
|
|
||||||
|
* 防御机(圆圆的那个):血量高,但是速度慢,攻击频率慢,且只有炮弹武器,但是可以360度射击。
|
||||||
|
* 战斗机(看上去就像战斗机的那个):血量少,但是速度快,攻击频率高,有炮弹和导弹两种武器,炮弹只可以向飞行方向射击。
|
||||||
|
|
||||||
|
战斗机和防御机的起始数量是随机的(总数为Plane Number)。
|
||||||
|
|
||||||
|
|
||||||
|
![gaming](./snapshot/gaming.png)
|
||||||
|
|
||||||
|
游戏界面。
|
||||||
|
|
||||||
|
* 左下角是雷达图,可以显示一定范围的飞机
|
||||||
|
* 正下方是战队血量,展示了目前在场的战队的所有飞机血量和(红色是我方血量)
|
||||||
|
* 右下角是武器说明,第一栏为主武器(这里是Bullet子弹),第二栏是副武器(这里是Missile导弹),方括号里显示武器弹药数量(没有就是无限弹药)
|
||||||
|
* 右上角是你的飞船血量。
|
||||||
|
|
||||||
|
飞机的操作:
|
||||||
|
|
||||||
|
* 防御机,按下w,a,s,d进行上下左右的移动,按下鼠标左键进行攻击。
|
||||||
|
* 战斗机,按下a,d进行左右转向,w,s进行加速和减速(不能向后倒着飞),鼠标左键使用炮弹,鼠标右键发射导弹(导弹有数量限制)。
|
||||||
|
|
||||||
|
切换飞机:
|
||||||
|
|
||||||
|
当你控制的飞机死亡后,视角会转到我方阵营的另一架飞机上,此时可以选择按空格键操控这辆飞机。
|
||||||
|
|
||||||
|
胜利条件:
|
||||||
|
|
||||||
|
全灭其他所有阵营获得胜利
|
||||||
|
|
12
ReadMe.md
12
ReadMe.md
|
@ -24,3 +24,15 @@ pack.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
最终的结果在`output`文件夹下。
|
最终的结果在`output`文件夹下。
|
||||||
|
|
||||||
|
## 游戏截图
|
||||||
|
|
||||||
|
![welcome](./snapshot/welcome.png)
|
||||||
|
|
||||||
|
![select](./snapshot/select_ship.png)
|
||||||
|
|
||||||
|
![gaming](./snapshot/gaming.png)
|
||||||
|
|
||||||
|
## 游戏操作
|
||||||
|
|
||||||
|
[游戏操作](./HowToPlay.md)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.0 KiB |
|
@ -228,8 +228,10 @@ public:
|
||||||
|
|
||||||
void Init(AIFunc func) {
|
void Init(AIFunc func) {
|
||||||
this->func = func;
|
this->func = func;
|
||||||
|
target = nullptr;
|
||||||
}
|
}
|
||||||
void Release() {}
|
void Release() {}
|
||||||
|
|
||||||
AIFunc func;
|
AIFunc func;
|
||||||
|
Entity* target;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,9 +7,10 @@ constexpr int FightShipLife = 10;
|
||||||
constexpr float FightShipRotationDegree = 6;
|
constexpr float FightShipRotationDegree = 6;
|
||||||
constexpr float FightShipAccelration = 200;
|
constexpr float FightShipAccelration = 200;
|
||||||
|
|
||||||
constexpr float FreightShipMaxSpeed = 100;
|
constexpr float FreightShipMaxSpeed = 200;
|
||||||
constexpr int FreightShipLife = 15;
|
constexpr int FreightShipLife = 20;
|
||||||
constexpr float FreightShipAccelerate = 100;
|
constexpr float FreightShipAccelerate = 100;
|
||||||
|
constexpr float FreightShipLazerDelay = 0.3;
|
||||||
|
|
||||||
constexpr float LazerDamage = 3.4;
|
constexpr float LazerDamage = 3.4;
|
||||||
constexpr float LazerShooterSpeed = 800;
|
constexpr float LazerShooterSpeed = 800;
|
||||||
|
@ -34,3 +35,10 @@ constexpr int Enemy3Group = 3;
|
||||||
|
|
||||||
constexpr float EntityRenderSize = 20;
|
constexpr float EntityRenderSize = 20;
|
||||||
constexpr float EntityCollisionSize = 16;
|
constexpr float EntityCollisionSize = 16;
|
||||||
|
|
||||||
|
constexpr Color GroupSpecColor[4] = {
|
||||||
|
Color{0.8, 0, 0, 1},
|
||||||
|
Color{0, 0.8, 0, 1},
|
||||||
|
Color{0, 0, 0.8, 1},
|
||||||
|
Color{0.8, 0.8, 0, 1}
|
||||||
|
};
|
||||||
|
|
|
@ -12,6 +12,8 @@ public:
|
||||||
datas_.push_back(elem);
|
datas_.push_back(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Empty() const { return datas_.empty(); }
|
||||||
|
|
||||||
void RemoveAll(condition_func findFunc,
|
void RemoveAll(condition_func findFunc,
|
||||||
destroy_func destroyFunc = nullptr) {
|
destroy_func destroyFunc = nullptr) {
|
||||||
std::size_t idx = 0;
|
std::size_t idx = 0;
|
||||||
|
@ -48,6 +50,11 @@ public:
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t Size() const { return datas_.size(); }
|
||||||
|
T& Get(size_t idx) { return datas_[idx]; }
|
||||||
|
|
||||||
|
|
||||||
using const_iterator = typename std::vector<T>::const_iterator;
|
using const_iterator = typename std::vector<T>::const_iterator;
|
||||||
|
|
||||||
const_iterator begin() const { return datas_.begin(); }
|
const_iterator begin() const { return datas_.begin(); }
|
||||||
|
|
|
@ -16,15 +16,23 @@ public:
|
||||||
void OnQuit() override;
|
void OnQuit() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Unique<FightShipController> fightController_;
|
Unique<Controller> controller_;
|
||||||
|
|
||||||
|
Camera guiCamera_;
|
||||||
|
Camera gameCamera_;
|
||||||
|
Entity* lookAtEntity_;
|
||||||
|
|
||||||
|
std::vector<Point> stars_;
|
||||||
|
int groupHps[4] = {0};
|
||||||
|
|
||||||
void renderBackground();
|
void renderBackground();
|
||||||
void renderGUI();
|
void renderGUI();
|
||||||
void renderMiniMap();
|
void renderMiniMap();
|
||||||
void renderWeapons(SpaceshipWeaponCmpt* weapon1, SpaceshipWeaponCmpt* weapon2);
|
void renderWeapons(SpaceshipWeaponCmpt* weapon1, SpaceshipWeaponCmpt* weapon2);
|
||||||
|
void initEnemies();
|
||||||
Camera guiCamera_;
|
void attachController();
|
||||||
Camera gameCamera_;
|
void generateEnemiesAt(int group, const Point& p, int num);
|
||||||
|
void initPlayer();
|
||||||
std::vector<Point> stars_;
|
void calcGroupHps();
|
||||||
|
void drawGroupHp();
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
void Render() override;
|
void Render() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void renderEntity(Entity* entity, const RenderCmpt&, float rotation);
|
void renderEntity(Entity* entity, const RenderCmpt&, float rotation, const Color&);
|
||||||
void renderCollideBox(Entity* entity);
|
void renderCollideBox(Entity* entity);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ bool IsRightPressing();
|
||||||
bool IsLeftPressed();
|
bool IsLeftPressed();
|
||||||
bool IsRightPressed();
|
bool IsRightPressed();
|
||||||
Point GetMousePosition();
|
Point GetMousePosition();
|
||||||
|
Point GetMousePositionMapped();
|
||||||
|
|
||||||
void EventUpdate();
|
void EventUpdate();
|
||||||
|
|
||||||
|
|
|
@ -195,8 +195,8 @@ inline Mat44 CreateSRT(const Point& pos, const Point& scale, float degree) {
|
||||||
float sinTheta = std::sin(theta),
|
float sinTheta = std::sin(theta),
|
||||||
cosTheta = std::cos(theta);
|
cosTheta = std::cos(theta);
|
||||||
return Mat44({
|
return Mat44({
|
||||||
scale.x * cosTheta, scale.y * sinTheta, 0, pos.x,
|
scale.x * cosTheta,-scale.y * sinTheta, 0, pos.x,
|
||||||
-scale.x * sinTheta, scale.y * cosTheta, 0, pos.y,
|
scale.x * sinTheta, scale.y * cosTheta, 0, pos.y,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,15 +31,17 @@ public:
|
||||||
static void FillRect(const Rect& rect);
|
static void FillRect(const Rect& rect);
|
||||||
static void DrawTile(const Tile& tile,
|
static void DrawTile(const Tile& tile,
|
||||||
const Point& pos,
|
const Point& pos,
|
||||||
const Size& size = {0, 0},
|
const Size& = {0, 0},
|
||||||
float degree = 0,
|
float degree = 0,
|
||||||
FlipFlag flip = NoFlip);
|
FlipFlag = NoFlip,
|
||||||
|
const Color& = {1, 1, 1, 1});
|
||||||
static void DrawTexture(const Texture* texture,
|
static void DrawTexture(const Texture* texture,
|
||||||
const Rect* srcrect,
|
const Rect* srcrect,
|
||||||
const Point& pos,
|
const Point& pos,
|
||||||
const Size& size = Size{0, 0},
|
const Size& = Size{0, 0},
|
||||||
float degree = 0,
|
float degree = 0,
|
||||||
FlipFlag flip = NoFlip);
|
FlipFlag = NoFlip,
|
||||||
|
const Color& = {1, 1, 1, 1});
|
||||||
static void DrawTexture(const Texture* texture,
|
static void DrawTexture(const Texture* texture,
|
||||||
const Rect* rect,
|
const Rect* rect,
|
||||||
const Mat44& transform,
|
const Mat44& transform,
|
||||||
|
|
2
pack.sh
2
pack.sh
|
@ -8,3 +8,5 @@ mkdir output
|
||||||
cp ./build/SpaceSector output
|
cp ./build/SpaceSector output
|
||||||
cp -r ./assets output
|
cp -r ./assets output
|
||||||
rm -rf ./output/assets/test
|
rm -rf ./output/assets/test
|
||||||
|
cp ./HowToPlay.md output/
|
||||||
|
cp -r ./snapshot output
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
|
@ -5,8 +5,6 @@ void Shoot(SpaceshipWeaponCmpt& weapon, const Point& dir) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point playerCenterPos = weapon.owner->Get<MoveCmpt>()->position;
|
|
||||||
|
|
||||||
Entity* bullet;
|
Entity* bullet;
|
||||||
bullet = weapon.ShootBullet(dir);
|
bullet = weapon.ShootBullet(dir);
|
||||||
if (bullet) {
|
if (bullet) {
|
||||||
|
@ -26,8 +24,7 @@ void Shoot(SpaceshipWeaponCmpt& weapon, const Point& dir, Entity* target) {
|
||||||
Entity* bullet;
|
Entity* bullet;
|
||||||
bullet = weapon.ShootMissile(dir, target);
|
bullet = weapon.ShootMissile(dir, target);
|
||||||
if (bullet) {
|
if (bullet) {
|
||||||
// FIXME the rotation have some bugs
|
bullet->Use<BulletCmpt>()->rotation = Sign(dir.x) * Degrees(std::acos(-Normalize(dir).y));
|
||||||
bullet->Use<BulletCmpt>()->rotation = Degrees(std::acos(-Normalize(dir).y));
|
|
||||||
Bullets.Add(bullet);
|
Bullets.Add(bullet);
|
||||||
weapon.coolDown = weapon.shootDuration;
|
weapon.coolDown = weapon.shootDuration;
|
||||||
Sounds["shoot"]->Play();
|
Sounds["shoot"]->Play();
|
||||||
|
@ -51,19 +48,19 @@ void MoveDown(MotionCmpt& motion) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpeedUp(MotionCmpt& motion, FightShipCmpt& ship) {
|
void SpeedUp(MotionCmpt& motion, FightShipCmpt& ship) {
|
||||||
motion.acceleration = Rotate(Point{0, FightShipAccelration},
|
motion.acceleration = Rotate(Point{0, -FightShipAccelration},
|
||||||
-ship.degree);
|
ship.degree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpeedDown(MotionCmpt& motion, FightShipCmpt& ship) {
|
void SpeedDown(MotionCmpt& motion, FightShipCmpt& ship) {
|
||||||
motion.acceleration = Rotate(Point{0, -FightShipAccelration},
|
motion.acceleration = Rotate(Point{0, FightShipAccelration},
|
||||||
-ship.degree);
|
ship.degree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TurnLeft(FightShipCmpt& ship) {
|
void TurnLeft(FightShipCmpt& ship) {
|
||||||
ship.degree += FightShipRotationDegree;
|
ship.degree -= FightShipRotationDegree;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TurnRight(FightShipCmpt& ship) {
|
void TurnRight(FightShipCmpt& ship) {
|
||||||
ship.degree -= FightShipRotationDegree;
|
ship.degree += FightShipRotationDegree;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,27 @@
|
||||||
#include "game/ai.hpp"
|
#include "game/ai.hpp"
|
||||||
|
|
||||||
|
Entity* findRandomEntity(Entity* self) {
|
||||||
|
int groupIdx = Random<int>(0, 3);
|
||||||
|
if (groupIdx == self->Get<GroupCmpt>()->groupIdx) {
|
||||||
|
groupIdx ++;
|
||||||
|
if (groupIdx >= 4) {
|
||||||
|
groupIdx = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto& group = Groups[groupIdx];
|
||||||
|
if (group.Empty())
|
||||||
|
return nullptr;
|
||||||
|
return group.Get(Random<int>(1, group.Size()) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
void FreightShipAI(Entity* self) {
|
void FreightShipAI(Entity* self) {
|
||||||
auto pmove = PlayerSpaceship->Get<MoveCmpt>();
|
auto ai = self->Use<AICmpt>();
|
||||||
|
if (!ai->target || !ai->target->IsAlive()) {
|
||||||
|
ai->target = findRandomEntity(self);
|
||||||
|
}
|
||||||
|
if (!ai->target) return;
|
||||||
|
|
||||||
|
auto pmove = ai->target->Get<MoveCmpt>();
|
||||||
auto smove = self->Get<MoveCmpt>();
|
auto smove = self->Get<MoveCmpt>();
|
||||||
auto dir = pmove->position - smove->position;
|
auto dir = pmove->position - smove->position;
|
||||||
if (Len2(dir) > 250000) {
|
if (Len2(dir) > 250000) {
|
||||||
|
@ -22,29 +42,35 @@ void FreightShipAI(Entity* self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FightShipAI(Entity* self) {
|
void FightShipAI(Entity* self) {
|
||||||
auto pmove = PlayerSpaceship->Get<MoveCmpt>();
|
auto ai = self->Use<AICmpt>();
|
||||||
|
if (!ai->target || !ai->target->IsAlive()) {
|
||||||
|
ai->target = findRandomEntity(self);
|
||||||
|
}
|
||||||
|
if (!ai->target) return;
|
||||||
|
|
||||||
|
auto pmove = ai->target->Get<MoveCmpt>();
|
||||||
auto smove = self->Get<MoveCmpt>();
|
auto smove = self->Get<MoveCmpt>();
|
||||||
auto dir = pmove->position - smove->position;
|
auto dir = pmove->position - smove->position;
|
||||||
|
|
||||||
auto motion = self->Use<MotionCmpt>();
|
auto motion = self->Use<MotionCmpt>();
|
||||||
auto ship = self->Use<FightShipCmpt>();
|
auto ship = self->Use<FightShipCmpt>();
|
||||||
|
|
||||||
auto nspd = Normalize(motion->speed),
|
auto ndir = Normalize(dir);
|
||||||
ndir = Normalize(dir);
|
|
||||||
|
|
||||||
SpeedUp(*motion, *ship);
|
SpeedUp(*motion, *ship);
|
||||||
|
|
||||||
auto cross = Cross(nspd, ndir);
|
auto shipDir = Rotate(Point{0, -1}, self->Get<FightShipCmpt>()->degree);
|
||||||
if (cross > std::sin(Radians(80))) {
|
auto cross = Cross(shipDir, ndir);
|
||||||
TurnLeft(*ship);
|
if (cross > 0) {
|
||||||
} else if (cross < std::sin(Radians(10))) {
|
|
||||||
TurnRight(*ship);
|
TurnRight(*ship);
|
||||||
|
} else {
|
||||||
|
TurnLeft(*ship);
|
||||||
|
}
|
||||||
|
if (abs(Cross(Normalize(motion->speed), Normalize(dir))) < std::sin(Radians(10))) {
|
||||||
|
if (ship->weapon2->bulletAmount > 0 && Random(1.0f, 100.0f) < 5) {
|
||||||
|
Shoot(*ship->weapon2, shipDir, ai->target);
|
||||||
|
} else {
|
||||||
|
Shoot(*ship->weapon1, shipDir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// if (Cross(Normalize(motion->speed), Normalize(dir)) < std::sin(Radians(10))) {
|
|
||||||
// if (ship->weapon2->bulletAmount > 0 && Random(1.0f, 100.0f) < 5) {
|
|
||||||
// Shoot(*ship->weapon2, dir, PlayerSpaceship);
|
|
||||||
// } else {
|
|
||||||
// Shoot(*ship->weapon1, dir);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,5 +23,6 @@ Entity* SpaceshipWeaponCmpt::ShootMissile(const Point& dir, Entity* target) {
|
||||||
}
|
}
|
||||||
bullet->Use<MotionCmpt>()->speed = Normalize(dir) * shootSpeed;
|
bullet->Use<MotionCmpt>()->speed = Normalize(dir) * shootSpeed;
|
||||||
bullet->Use<MoveCmpt>()->position = owner->Get<MoveCmpt>()->position;
|
bullet->Use<MoveCmpt>()->position = owner->Get<MoveCmpt>()->position;
|
||||||
|
Sounds["missile"]->Play();
|
||||||
return bullet;
|
return bullet;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@ FightShipController::FightShipController(Entity* entity)
|
||||||
: entity_(entity) {}
|
: entity_(entity) {}
|
||||||
|
|
||||||
void FightShipController::Update(float dt) {
|
void FightShipController::Update(float dt) {
|
||||||
|
if (!entity_ || !entity_->IsAlive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const float spd = 100;
|
const float spd = 100;
|
||||||
auto motionCmpt = entity_->Use<MotionCmpt>();
|
auto motionCmpt = entity_->Use<MotionCmpt>();
|
||||||
auto ship = entity_->Use<FightShipCmpt>();
|
auto ship = entity_->Use<FightShipCmpt>();
|
||||||
|
@ -15,14 +19,14 @@ void FightShipController::Update(float dt) {
|
||||||
TurnRight(*ship);
|
TurnRight(*ship);
|
||||||
}
|
}
|
||||||
if (IsKeyPressing(GLFW_KEY_S)) {
|
if (IsKeyPressing(GLFW_KEY_S)) {
|
||||||
SpeedUp(*motionCmpt, *ship);
|
SpeedDown(*motionCmpt, *ship);
|
||||||
}
|
}
|
||||||
if (IsKeyPressing(GLFW_KEY_W)) {
|
if (IsKeyPressing(GLFW_KEY_W)) {
|
||||||
SpeedDown(*motionCmpt, *ship);
|
SpeedUp(*motionCmpt, *ship);
|
||||||
}
|
}
|
||||||
|
|
||||||
motionCmpt->speed = Rotate(Point{0, -1} * Len(motionCmpt->speed),
|
motionCmpt->speed = Rotate(Point{0, -1} * Len(motionCmpt->speed),
|
||||||
-ship->degree);
|
ship->degree);
|
||||||
|
|
||||||
auto moveCmpt = entity_->Get<MoveCmpt>();
|
auto moveCmpt = entity_->Get<MoveCmpt>();
|
||||||
|
|
||||||
|
@ -46,9 +50,9 @@ void FightShipController::weaponShoot(SpaceshipWeaponCmpt* weapon, const MoveCmp
|
||||||
if (!weapon) return;
|
if (!weapon) return;
|
||||||
Point dir;
|
Point dir;
|
||||||
if (weapon->type == SpaceshipWeaponCmpt::Orientation) {
|
if (weapon->type == SpaceshipWeaponCmpt::Orientation) {
|
||||||
dir = Rotate(Point{0, -1}, -entity_->Get<FightShipCmpt>()->degree);
|
dir = Rotate(Point{0, -1}, entity_->Get<FightShipCmpt>()->degree);
|
||||||
} else {
|
} else {
|
||||||
dir = GetMousePosition() - entity_->Get<MoveCmpt>()->position;
|
dir = GetMousePosition() - GameWindowSize / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weapon->bulletType == BulletCmpt::Bullet) {
|
if (weapon->bulletType == BulletCmpt::Bullet) {
|
||||||
|
@ -57,7 +61,7 @@ void FightShipController::weaponShoot(SpaceshipWeaponCmpt* weapon, const MoveCmp
|
||||||
Entity* target = nullptr;
|
Entity* target = nullptr;
|
||||||
for (auto& entity : Entities) {
|
for (auto& entity : Entities) {
|
||||||
if (entity != entity_ &&
|
if (entity != entity_ &&
|
||||||
IsPointInRect(MapPlayerCoord2Global(GetMousePosition()), entity->Get<CollisionCmpt>()->rect)) {
|
IsPointInRect(MapPlayerCoord2Global(GetMousePositionMapped()), entity->Get<CollisionCmpt>()->rect)) {
|
||||||
target = entity;
|
target = entity;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@ FreightShipController::FreightShipController(Entity* entity)
|
||||||
: entity_(entity) {}
|
: entity_(entity) {}
|
||||||
|
|
||||||
void FreightShipController::Update(float dt) {
|
void FreightShipController::Update(float dt) {
|
||||||
|
if (!entity_ || !entity_->IsAlive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const float spd = 100;
|
const float spd = 100;
|
||||||
auto motionCmpt = entity_->Use<MotionCmpt>();
|
auto motionCmpt = entity_->Use<MotionCmpt>();
|
||||||
if (IsKeyPressing(GLFW_KEY_A)) {
|
if (IsKeyPressing(GLFW_KEY_A)) {
|
||||||
|
@ -29,7 +33,7 @@ void FreightShipController::Update(float dt) {
|
||||||
Rotate(Point{0, -1}, entity_->Get<FightShipCmpt>()->degree));
|
Rotate(Point{0, -1}, entity_->Get<FightShipCmpt>()->degree));
|
||||||
} else {
|
} else {
|
||||||
Shoot(*weapon,
|
Shoot(*weapon,
|
||||||
GetMousePosition() - entity_->Get<MoveCmpt>()->position);
|
GetMousePosition() - GameWindowSize / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ Entity* CreateFreightShip(int group) {
|
||||||
LazerDamage,
|
LazerDamage,
|
||||||
LazerShooterSpeed,
|
LazerShooterSpeed,
|
||||||
LazerShooterMaxSpeed,
|
LazerShooterMaxSpeed,
|
||||||
LazerShooterCooldown + 1);
|
LazerShooterCooldown + FreightShipLazerDelay);
|
||||||
entity->Add<CollisionCmpt>(Size{EntityCollisionSize, EntityCollisionSize});
|
entity->Add<CollisionCmpt>(Size{EntityCollisionSize, EntityCollisionSize});
|
||||||
entity->Add<LifeCmpt>(FreightShipLife);
|
entity->Add<LifeCmpt>(FreightShipLife);
|
||||||
entity->Add<FreightShipCmpt>(weapon);
|
entity->Add<FreightShipCmpt>(weapon);
|
||||||
|
@ -56,7 +56,7 @@ Entity* CreateBullet(int group, int damage, Entity* owner, float maxSpeed) {
|
||||||
Entity* entity = ECSContext.CreateEntity();
|
Entity* entity = ECSContext.CreateEntity();
|
||||||
entity->Add<MoveCmpt>(Point{0, 0});
|
entity->Add<MoveCmpt>(Point{0, 0});
|
||||||
entity->Add<MotionCmpt>(Point{0, 0}, maxSpeed);
|
entity->Add<MotionCmpt>(Point{0, 0}, maxSpeed);
|
||||||
entity->Add<RenderCmpt>(GameTileSheet->GetTile(0, 1));
|
entity->Add<RenderCmpt>(GameTileSheet->GetTile(4, 0));
|
||||||
entity->Add<BulletCmpt>(BulletCmpt::Bullet, damage, owner);
|
entity->Add<BulletCmpt>(BulletCmpt::Bullet, damage, owner);
|
||||||
entity->Add<CollisionCmpt>(Size{8, 8});
|
entity->Add<CollisionCmpt>(Size{8, 8});
|
||||||
entity->Add<GroupCmpt>(group);
|
entity->Add<GroupCmpt>(group);
|
||||||
|
@ -67,7 +67,7 @@ Entity* CreateMissile(int group, int damage, Entity* owner, float maxSpeed, Enti
|
||||||
Entity* entity = ECSContext.CreateEntity();
|
Entity* entity = ECSContext.CreateEntity();
|
||||||
entity->Add<MoveCmpt>(Point{0, 0});
|
entity->Add<MoveCmpt>(Point{0, 0});
|
||||||
entity->Add<MotionCmpt>(Point{0, 0}, maxSpeed);
|
entity->Add<MotionCmpt>(Point{0, 0}, maxSpeed);
|
||||||
entity->Add<RenderCmpt>(GameTileSheet->GetTile(2, 1));
|
entity->Add<RenderCmpt>(GameTileSheet->GetTile(6, 0));
|
||||||
entity->Add<BulletCmpt>(BulletCmpt::Missile, damage, owner, target);
|
entity->Add<BulletCmpt>(BulletCmpt::Missile, damage, owner, target);
|
||||||
entity->Add<CollisionCmpt>(Size{10, 10});
|
entity->Add<CollisionCmpt>(Size{10, 10});
|
||||||
entity->Add<GroupCmpt>(group);
|
entity->Add<GroupCmpt>(group);
|
||||||
|
|
|
@ -15,11 +15,14 @@ GameInitInfo InitInfo;
|
||||||
std::array<QuickList<Entity*>, 4> Groups;
|
std::array<QuickList<Entity*>, 4> Groups;
|
||||||
|
|
||||||
void loadImages() {
|
void loadImages() {
|
||||||
GameTileSheet.reset(new TileSheet("assets/tilesheet.png", 8, 8));
|
GameTileSheet.reset(new TileSheet("assets/tilesheet.png", 7, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadSounds() {
|
void loadSounds() {
|
||||||
Sounds["shoot"] = std::make_unique<Sound>("assets/shoot.wav");
|
Sounds["shoot"] = std::make_unique<Sound>("assets/shoot.wav");
|
||||||
|
Sounds["hurt"] = std::make_unique<Sound>("assets/hurt.wav");
|
||||||
|
Sounds["explosion"] = std::make_unique<Sound>("assets/explose.wav");
|
||||||
|
Sounds["missile"] = std::make_unique<Sound>("assets/missile.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadResources() {
|
void LoadResources() {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
bool Button(Texture* texture, const Point& pos, const Size& size, bool hflip) {
|
bool Button(Texture* texture, const Point& pos, const Size& size, bool hflip) {
|
||||||
Renderer::DrawTexture(texture, nullptr, pos, size, 0, hflip ? Renderer::FlipFlag::Horizontal : Renderer::FlipFlag::NoFlip);
|
Renderer::DrawTexture(texture, nullptr, pos, size, 0, hflip ? Renderer::FlipFlag::Horizontal : Renderer::FlipFlag::NoFlip);
|
||||||
Rect rect = Rect{pos.x - size.w / 2, pos.y - size.h / 2, size.w, size.h};
|
Rect rect = Rect{pos.x - size.w / 2, pos.y - size.h / 2, size.w, size.h};
|
||||||
if (IsPointInRect(GetMousePosition(), rect)) {
|
if (IsPointInRect(GetMousePositionMapped(), rect)) {
|
||||||
Renderer::SetDrawColor(Color{1, 1, 1, 0.2});
|
Renderer::SetDrawColor(Color{1, 1, 1, 0.2});
|
||||||
Renderer::FillRect(rect);
|
Renderer::FillRect(rect);
|
||||||
return IsLeftPressed();
|
return IsLeftPressed();
|
||||||
|
|
|
@ -6,42 +6,11 @@ void SpaceScence::OnInit() {
|
||||||
Entities.Clear();
|
Entities.Clear();
|
||||||
Bullets.Clear();
|
Bullets.Clear();
|
||||||
|
|
||||||
PlayerSpaceship = CreateFightShip(PlayerGroup);
|
initEnemies();
|
||||||
Entities.Add(PlayerSpaceship);
|
initPlayer();
|
||||||
PlayerSpaceship->Use<MoveCmpt>()->position = Point{400, 400};
|
calcGroupHps();
|
||||||
|
|
||||||
Entity* enemy = CreateFreightShip(Enemy1Group);
|
|
||||||
enemy->Add<AICmpt>(FreightShipAI);
|
|
||||||
enemy->Use<MoveCmpt>()->position = Point{100, 100};
|
|
||||||
Entities.Add(enemy);
|
|
||||||
|
|
||||||
enemy = CreateFreightShip(Enemy1Group);
|
|
||||||
enemy->Add<AICmpt>(FreightShipAI);
|
|
||||||
enemy->Use<MoveCmpt>()->position = Point{200, 100};
|
|
||||||
Entities.Add(enemy);
|
|
||||||
|
|
||||||
enemy = CreateFreightShip(Enemy1Group);
|
|
||||||
enemy->Add<AICmpt>(FreightShipAI);
|
|
||||||
enemy->Use<MoveCmpt>()->position = Point{100, 200};
|
|
||||||
Entities.Add(enemy);
|
|
||||||
|
|
||||||
// Entity* enemy = CreateFightShip(Enemy1Group);
|
|
||||||
// enemy->Add<AICmpt>(FightShipAI);
|
|
||||||
// enemy->Use<MoveCmpt>()->position = Point{100, 100};
|
|
||||||
// Entities.Add(enemy);
|
|
||||||
|
|
||||||
// enemy = CreateFightShip(Enemy1Group);
|
|
||||||
// enemy->Add<AICmpt>(FightShipAI);
|
|
||||||
// enemy->Use<MoveCmpt>()->position = Point{200, 100};
|
|
||||||
// Entities.Add(enemy);
|
|
||||||
|
|
||||||
// enemy = CreateFightShip(Enemy1Group);
|
|
||||||
// enemy->Add<AICmpt>(FightShipAI);
|
|
||||||
// enemy->Use<MoveCmpt>()->position = Point{100, 200};
|
|
||||||
// Entities.Add(enemy);
|
|
||||||
|
|
||||||
fightController_.reset(new FightShipController(PlayerSpaceship));
|
|
||||||
|
|
||||||
|
lookAtEntity_ = PlayerSpaceship;
|
||||||
gameCamera_.SetAnchor(GameWindowSize / 2);
|
gameCamera_.SetAnchor(GameWindowSize / 2);
|
||||||
|
|
||||||
SystemMgr.Clear();
|
SystemMgr.Clear();
|
||||||
|
@ -62,10 +31,89 @@ void SpaceScence::OnInit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpaceScence::calcGroupHps() {
|
||||||
|
for (int i = 0; i < InitInfo.groupNum; i++) {
|
||||||
|
for (auto& entity : Groups[i]) {
|
||||||
|
if (entity->Has<LifeCmpt>()) {
|
||||||
|
groupHps[i] += entity->Get<LifeCmpt>()->hp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceScence::initPlayer() {
|
||||||
|
if (PlayerSpaceship && PlayerSpaceship->IsAlive()) {
|
||||||
|
ECSContext.DestroyEntity(PlayerSpaceship);
|
||||||
|
}
|
||||||
|
if (InitInfo.planeType == FightShip) {
|
||||||
|
PlayerSpaceship = CreateFightShip(PlayerGroup);
|
||||||
|
controller_.reset(new FightShipController(PlayerSpaceship));
|
||||||
|
} else if (InitInfo.planeType == FreightShip) {
|
||||||
|
PlayerSpaceship = CreateFreightShip(PlayerGroup);
|
||||||
|
controller_.reset(new FreightShipController(PlayerSpaceship));
|
||||||
|
}
|
||||||
|
Entities.Add(PlayerSpaceship);
|
||||||
|
Groups[PlayerGroup].Add(PlayerSpaceship);
|
||||||
|
PlayerSpaceship->Use<MoveCmpt>()->position = Point{0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceScence::initEnemies() {
|
||||||
|
generateEnemiesAt(PlayerGroup, Point{0, 0}, InitInfo.planeNum - 1);
|
||||||
|
if (InitInfo.groupNum == 2) {
|
||||||
|
generateEnemiesAt(Enemy1Group, Point{0, -720 * 4}, InitInfo.planeNum);
|
||||||
|
} else if (InitInfo.groupNum == 3) {
|
||||||
|
generateEnemiesAt(Enemy1Group, Point{-720 * 4, -720 * 4}, InitInfo.planeNum);
|
||||||
|
generateEnemiesAt(Enemy2Group, Point{720 * 4, -720 * 4}, InitInfo.planeNum);
|
||||||
|
} 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);
|
||||||
|
} else {
|
||||||
|
Log("group num invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceScence::generateEnemiesAt(int group, const Point& p, int num) {
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
Entity* enemy = CreateFreightShip(group);
|
||||||
|
enemy->Add<AICmpt>(FreightShipAI);
|
||||||
|
// Entity* enemy = CreateFightShip(group);
|
||||||
|
// enemy->Add<AICmpt>(FightShipAI);
|
||||||
|
enemy->Use<MoveCmpt>()->position += p + Point{Random<float>(-400, 400), Random<float>(-100, 100)};
|
||||||
|
Entities.Add(enemy);
|
||||||
|
Groups[group].Add(enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SpaceScence::OnUpdate(float dt) {
|
void SpaceScence::OnUpdate(float dt) {
|
||||||
fightController_->Update(dt);
|
controller_->Update(dt);
|
||||||
SystemMgr.Update(dt);
|
SystemMgr.Update(dt);
|
||||||
gameCamera_.MoveTo(PlayerSpaceship->Get<MoveCmpt>()->position);
|
|
||||||
|
if (lookAtEntity_ && lookAtEntity_->IsAlive()) {
|
||||||
|
gameCamera_.MoveTo(lookAtEntity_->Get<MoveCmpt>()->position);
|
||||||
|
} else {
|
||||||
|
if (!Groups[PlayerGroup].Empty()) {
|
||||||
|
lookAtEntity_ = *Groups[PlayerGroup].begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PlayerSpaceship || !PlayerSpaceship->IsAlive()) {
|
||||||
|
if (IsKeyPressing(GLFW_KEY_SPACE)) {
|
||||||
|
PlayerSpaceship = lookAtEntity_;
|
||||||
|
if (PlayerSpaceship->Has<AICmpt>()) {
|
||||||
|
PlayerSpaceship->Remove<AICmpt>();
|
||||||
|
}
|
||||||
|
attachController();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceScence::attachController() {
|
||||||
|
if (PlayerSpaceship->Has<FreightShipCmpt>()) {
|
||||||
|
controller_.reset(new FreightShipController(PlayerSpaceship));
|
||||||
|
} else {
|
||||||
|
controller_.reset(new FightShipController(PlayerSpaceship));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpaceScence::OnRender() {
|
void SpaceScence::OnRender() {
|
||||||
|
@ -100,20 +148,47 @@ void SpaceScence::renderBackground() {
|
||||||
void SpaceScence::renderGUI() {
|
void SpaceScence::renderGUI() {
|
||||||
Renderer::SetCamera(guiCamera_);
|
Renderer::SetCamera(guiCamera_);
|
||||||
|
|
||||||
auto life = PlayerSpaceship->Get<LifeCmpt>()->hp;
|
int life = 0;
|
||||||
|
if (PlayerSpaceship && PlayerSpaceship->IsAlive()) {
|
||||||
|
life = PlayerSpaceship->Get<LifeCmpt>()->hp;
|
||||||
|
}
|
||||||
float xOffset = 16 * life;
|
float xOffset = 16 * life;
|
||||||
for (int i = 0; i < life; i++) {
|
for (int i = 0; i < life; i++) {
|
||||||
Renderer::DrawTile(GameTileSheet->GetTile(1, 1),
|
Renderer::DrawTile(GameTileSheet->GetTile(5, 0),
|
||||||
Point{GameWindowSize.w - xOffset + i * 16, 8});
|
Point{GameWindowSize.w - xOffset + i * 16, 8});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMiniMap();
|
renderMiniMap();
|
||||||
|
if (PlayerSpaceship && PlayerSpaceship->IsAlive()) {
|
||||||
if (PlayerSpaceship->Has<FreightShipCmpt>()) {
|
if (PlayerSpaceship->Has<FreightShipCmpt>()) {
|
||||||
renderWeapons(PlayerSpaceship->Get<FreightShipCmpt>()->weapon, nullptr);
|
renderWeapons(PlayerSpaceship->Get<FreightShipCmpt>()->weapon, nullptr);
|
||||||
} else {
|
} else {
|
||||||
auto fightShip = PlayerSpaceship->Get<FightShipCmpt>();
|
auto fightShip = PlayerSpaceship->Get<FightShipCmpt>();
|
||||||
renderWeapons(fightShip->weapon1, fightShip->weapon2);
|
renderWeapons(fightShip->weapon1, fightShip->weapon2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawGroupHp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceScence::drawGroupHp() {
|
||||||
|
static Color colors[4] = {Color{1, 0, 0, 1},
|
||||||
|
Color{0, 1, 0, 1},
|
||||||
|
Color{0, 0, 1, 1},
|
||||||
|
Color{1, 1, 0, 1}};
|
||||||
|
|
||||||
|
for (int i = 0; i < InitInfo.groupNum; i++) {
|
||||||
|
int hp = 0;
|
||||||
|
for (auto& entity : Groups[i]) {
|
||||||
|
if (entity->Has<LifeCmpt>()) {
|
||||||
|
hp += entity->Get<LifeCmpt>()->hp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Renderer::SetDrawColor(colors[i]);
|
||||||
|
Renderer::FillRect(Rect{150, GameWindowSize.h - 20 * (i + 1), hp / float(groupHps[i]) * 500, 20});
|
||||||
|
Renderer::SetDrawColor(Color{1, 1, 1, 1});
|
||||||
|
Renderer::DrawRect(Rect{150, GameWindowSize.h - 20 * (i + 1), 500, 20});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpaceScence::renderMiniMap() {
|
void SpaceScence::renderMiniMap() {
|
||||||
|
@ -125,6 +200,10 @@ void SpaceScence::renderMiniMap() {
|
||||||
Renderer::SetDrawColor(Color{255, 255, 255, 255});
|
Renderer::SetDrawColor(Color{255, 255, 255, 255});
|
||||||
Renderer::DrawRect(mapRect);
|
Renderer::DrawRect(mapRect);
|
||||||
|
|
||||||
|
if (!PlayerSpaceship || !PlayerSpaceship->IsAlive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -183,16 +262,6 @@ void SpaceScence::renderWeapons(SpaceshipWeaponCmpt* weapon1, SpaceshipWeaponCmp
|
||||||
}
|
}
|
||||||
offset.y += 20;
|
offset.y += 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// font.Render("ENERGY",
|
|
||||||
// 20,
|
|
||||||
// Point{weaponInfoRect.x, weaponInfoRect.y} + offset,
|
|
||||||
// Color{0.9, 0.3, 0.83, 1});
|
|
||||||
// std::string energyAmount = std::to_string(PlayerCore->Get<EnergyProductCmpt>()->amount);
|
|
||||||
// font.Render(energyAmount,
|
|
||||||
// 20,
|
|
||||||
// Point{weaponInfoRect.x + weaponInfoRect.w - 20 - 20 * energyAmount.size(), weaponInfoRect.y} + offset,
|
|
||||||
// Color{0.9, 0.5, 0.8, 1});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpaceScence::OnQuit() {
|
void SpaceScence::OnQuit() {
|
||||||
|
|
|
@ -29,7 +29,7 @@ void WelcomeScence::OnRender() {
|
||||||
Point{(GameWindowSize.w - title.size() * pt) / 2, 200},
|
Point{(GameWindowSize.w - title.size() * pt) / 2, 200},
|
||||||
Color{0.8, 0.8, 1, 1});
|
Color{0.8, 0.8, 1, 1});
|
||||||
|
|
||||||
title = "HTTPS://GITEE.COM/VISUALGMQ/SPACE-SECTOR.GIT";
|
title = "HTTPS://GITEE.COM/VISUALGMQ/SPACE-WAR.GIT";
|
||||||
pt = 10;
|
pt = 10;
|
||||||
font.Render(title, pt,
|
font.Render(title, pt,
|
||||||
Point{(GameWindowSize.w - title.size() * pt) / 2, 710},
|
Point{(GameWindowSize.w - title.size() * pt) / 2, 710},
|
||||||
|
|
|
@ -56,13 +56,13 @@ void MissileUpdateSystem::updateMissile(float dt,
|
||||||
bullet.target = nullptr;
|
bullet.target = nullptr;
|
||||||
} else {
|
} else {
|
||||||
Point v = bullet.target->Get<MoveCmpt>()->position - move.position;
|
Point v = bullet.target->Get<MoveCmpt>()->position - move.position;
|
||||||
float cross = Cross(motion.speed, v);
|
float cross = Cross(Rotate(Point{0, -1}, bullet.rotation), v);
|
||||||
if (cross > 0) {
|
if (cross > 0) {
|
||||||
bullet.rotation -= MissileRotateDegree * dt;
|
|
||||||
} else {
|
|
||||||
bullet.rotation += MissileRotateDegree * dt;
|
bullet.rotation += MissileRotateDegree * dt;
|
||||||
|
} else {
|
||||||
|
bullet.rotation -= MissileRotateDegree * dt;
|
||||||
}
|
}
|
||||||
Point dir = Rotate(Point{0, -1}, -bullet.rotation);
|
Point dir = Rotate(Point{0, -1}, bullet.rotation);
|
||||||
motion.speed = dir * Len(motion.speed);
|
motion.speed = dir * Len(motion.speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ void CollideSystem::Update(float dt) {
|
||||||
entity->Get<CollisionCmpt>()->rect)) {
|
entity->Get<CollisionCmpt>()->rect)) {
|
||||||
if (entity->Has<LifeCmpt>()) {
|
if (entity->Has<LifeCmpt>()) {
|
||||||
entity->Use<LifeCmpt>()->hp -= bullet->Get<BulletCmpt>()->damage;
|
entity->Use<LifeCmpt>()->hp -= bullet->Get<BulletCmpt>()->damage;
|
||||||
|
Sounds["hurt"]->Play();
|
||||||
}
|
}
|
||||||
bullet->Use<BulletCmpt>()->alive = false;
|
bullet->Use<BulletCmpt>()->alive = false;
|
||||||
}
|
}
|
||||||
|
@ -111,20 +112,33 @@ void CleanupSystem::Update(float dt) {
|
||||||
ECSContext.DestroyEntity(entity);
|
ECSContext.DestroyEntity(entity);
|
||||||
};
|
};
|
||||||
|
|
||||||
Bullets.RemoveAll([](const EntityPtr& entity){
|
for (int i = 0; i < InitInfo.groupNum; i++) {
|
||||||
return !entity->Get<BulletCmpt>()->alive ||
|
Groups[i].RemoveAll([](const EntityPtr& entity){
|
||||||
!IsPointInRect(MapGlobal2PlayerCoord(entity->Get<MoveCmpt>()->position),
|
|
||||||
BulletRefreshArea);
|
|
||||||
}, destroyFunc);
|
|
||||||
|
|
||||||
Entities.RemoveAll([](const EntityPtr& entity){
|
|
||||||
if (entity->Has<LifeCmpt>() &&
|
if (entity->Has<LifeCmpt>() &&
|
||||||
entity->Get<LifeCmpt>()->hp <= 0) {
|
entity->Get<LifeCmpt>()->hp <= 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Bullets.RemoveAll([](const EntityPtr& entity){
|
||||||
|
return !entity->Get<BulletCmpt>()->alive ||
|
||||||
|
!IsPointInRect(MapGlobal2PlayerCoord(entity->Get<MoveCmpt>()->position),
|
||||||
|
BulletRefreshArea);
|
||||||
}, destroyFunc);
|
}, destroyFunc);
|
||||||
|
|
||||||
|
Entities.RemoveAll([&](const EntityPtr& entity){
|
||||||
|
if (entity->Has<LifeCmpt>() &&
|
||||||
|
entity->Get<LifeCmpt>()->hp <= 0) {
|
||||||
|
Sounds["explosion"]->Play();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, destroyFunc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeaponCooldownSystem::Update(float dt) {
|
void WeaponCooldownSystem::Update(float dt) {
|
||||||
|
@ -154,8 +168,12 @@ void RenderEntitySystem::Render() {
|
||||||
if (entity->Has<FightShipCmpt>()) {
|
if (entity->Has<FightShipCmpt>()) {
|
||||||
rotation = entity->Get<FightShipCmpt>()->degree;
|
rotation = entity->Get<FightShipCmpt>()->degree;
|
||||||
}
|
}
|
||||||
renderEntity(entity, *entity->Get<RenderCmpt>(), rotation);
|
Color color = {1, 1, 1, 1};
|
||||||
renderCollideBox(entity);
|
if (entity->Has<GroupCmpt>()) {
|
||||||
|
color = GroupSpecColor[entity->Get<GroupCmpt>()->groupIdx];
|
||||||
|
}
|
||||||
|
renderEntity(entity, *entity->Get<RenderCmpt>(), rotation, color);
|
||||||
|
// renderCollideBox(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,8 +182,8 @@ void RenderEntitySystem::Render() {
|
||||||
if (bullet->Get<BulletCmpt>()->type == BulletCmpt::Missile) {
|
if (bullet->Get<BulletCmpt>()->type == BulletCmpt::Missile) {
|
||||||
rotation = bullet->Get<BulletCmpt>()->rotation;
|
rotation = bullet->Get<BulletCmpt>()->rotation;
|
||||||
}
|
}
|
||||||
renderEntity(bullet, *bullet->Get<RenderCmpt>(), rotation);
|
renderEntity(bullet, *bullet->Get<RenderCmpt>(), rotation, Color{1, 1, 1, 1});
|
||||||
renderCollideBox(bullet);
|
// renderCollideBox(bullet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +194,10 @@ void RenderEntitySystem::renderCollideBox(Entity* entity) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderEntitySystem::renderEntity(Entity* entity, const RenderCmpt& renderCmpt, float rotation) {
|
void RenderEntitySystem::renderEntity(Entity* entity,
|
||||||
|
const RenderCmpt& renderCmpt,
|
||||||
|
float rotation,
|
||||||
|
const Color& color) {
|
||||||
if (entity->Has<MoveCmpt>()) {
|
if (entity->Has<MoveCmpt>()) {
|
||||||
auto& pos = entity->Get<MoveCmpt>()->position;
|
auto& pos = entity->Get<MoveCmpt>()->position;
|
||||||
if (renderCmpt.type == RenderCmpt::TypeTexture) {
|
if (renderCmpt.type == RenderCmpt::TypeTexture) {
|
||||||
|
@ -184,12 +205,16 @@ void RenderEntitySystem::renderEntity(Entity* entity, const RenderCmpt& renderCm
|
||||||
nullptr,
|
nullptr,
|
||||||
pos,
|
pos,
|
||||||
Size{EntityRenderSize, EntityRenderSize},
|
Size{EntityRenderSize, EntityRenderSize},
|
||||||
rotation);
|
rotation,
|
||||||
|
Renderer::NoFlip,
|
||||||
|
color);
|
||||||
} else {
|
} else {
|
||||||
Renderer::DrawTile(renderCmpt.tile,
|
Renderer::DrawTile(renderCmpt.tile,
|
||||||
pos,
|
pos,
|
||||||
Size{EntityRenderSize, EntityRenderSize},
|
Size{EntityRenderSize, EntityRenderSize},
|
||||||
rotation);
|
rotation,
|
||||||
|
Renderer::NoFlip,
|
||||||
|
color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,12 @@ bool IsRightPressed() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Point GetMousePosition() {
|
Point GetMousePosition() {
|
||||||
|
double x, y;
|
||||||
|
glfwGetCursorPos(engine.GetWindow(), &x, &y);
|
||||||
|
return Point{float(x), float(y)};
|
||||||
|
}
|
||||||
|
|
||||||
|
Point GetMousePositionMapped() {
|
||||||
double x, y;
|
double x, y;
|
||||||
glfwGetCursorPos(engine.GetWindow(), &x, &y);
|
glfwGetCursorPos(engine.GetWindow(), &x, &y);
|
||||||
return Point{float(x) * WindowInitSize.w / engine.GetWindowSize().w,
|
return Point{float(x) * WindowInitSize.w / engine.GetWindowSize().w,
|
||||||
|
|
|
@ -133,11 +133,12 @@ void Renderer::DrawTile(const Tile& tile,
|
||||||
const Point& pos,
|
const Point& pos,
|
||||||
const Size& size,
|
const Size& size,
|
||||||
float degree,
|
float degree,
|
||||||
Renderer::FlipFlag flip) {
|
Renderer::FlipFlag flip,
|
||||||
|
const Color& color) {
|
||||||
if (size.w == 0 && size.h == 0) {
|
if (size.w == 0 && size.h == 0) {
|
||||||
DrawTexture(tile.texture, &tile.rect, pos, tile.size, degree, flip);
|
DrawTexture(tile.texture, &tile.rect, pos, tile.size, degree, flip, color);
|
||||||
} else {
|
} else {
|
||||||
DrawTexture(tile.texture, &tile.rect, pos, size, degree, flip);
|
DrawTexture(tile.texture, &tile.rect, pos, size, degree, flip, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +147,8 @@ void Renderer::DrawTexture(const Texture* texture,
|
||||||
const Point& pos,
|
const Point& pos,
|
||||||
const Size& size,
|
const Size& size,
|
||||||
float degree,
|
float degree,
|
||||||
FlipFlag flip) {
|
FlipFlag flip,
|
||||||
|
const Color& color) {
|
||||||
if (texture) {
|
if (texture) {
|
||||||
auto scale = size;
|
auto scale = size;
|
||||||
if (size.w == 0 && size.h == 0) {
|
if (size.w == 0 && size.h == 0) {
|
||||||
|
@ -158,7 +160,7 @@ void Renderer::DrawTexture(const Texture* texture,
|
||||||
if (flip & Horizontal) {
|
if (flip & Horizontal) {
|
||||||
scale.w *= -1;
|
scale.w *= -1;
|
||||||
}
|
}
|
||||||
DrawTexture(texture, srcrect, CreateSRT(pos, scale, degree));
|
DrawTexture(texture, srcrect, CreateSRT(pos, scale, degree), color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue