add cursor; finished select scence

This commit is contained in:
VisualGMQ 2022-02-15 22:50:31 +08:00
parent fd0bcce5c7
commit 559cfda2da
38 changed files with 717 additions and 78 deletions

BIN
assets/cursor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

BIN
assets/go_btn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

BIN
assets/switch_btn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 920 B

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -6,3 +6,11 @@
void Shoot(SpaceshipWeaponCmpt& weapon, const Point& dir);
void Shoot(SpaceshipWeaponCmpt& weapon, const Point& dir, Entity* target);
void MoveLeft(MotionCmpt& motion);
void MoveRight(MotionCmpt& motion);
void MoveUp(MotionCmpt& motion);
void MoveDown(MotionCmpt& motion);
void SpeedUp(MotionCmpt& motion, FightShipCmpt& ship);
void SpeedDown(MotionCmpt& motion, FightShipCmpt& ship);
void TurnLeft(FightShipCmpt& motion);
void TurnRight(FightShipCmpt& motion);

9
include/game/ai.hpp Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include "tinyengine/tinyengine.hpp"
#include "game/component.hpp"
#include "game/global.hpp"
#include "game/action.hpp"
void FreightShipAI(Entity* self);
void FightShipAI(Entity* self);

View File

@ -181,3 +181,55 @@ public:
};
};
class PlanetCmpt: public Component {
public:
void Init(const Point& position, const Size& size) {
positionInSpace = position;
generateMap(size);
}
Point positionInSpace;
Unique<Mat<Entity*>> map;
private:
void generateMap(const Size& size);
};
class EnergyProductCmpt: public Component {
public:
void Init(int amount, float duration) {
this->productAmount = amount;
this->duration = duration;
this->cooldown = duration;
this->amount = 0;
}
bool IsCoolDowning() { return cooldown > 0; }
void Release() {}
float duration;
float cooldown;
int productAmount;
int amount;
};
class GroupCmpt: public Component {
public:
void Init(int group) {
groupIdx = group;
}
void Release() {}
int groupIdx;
};
class AICmpt: public Component {
public:
using AIFunc = std::function<void(Entity*)>;
void Init(AIFunc func) {
this->func = func;
}
void Release() {}
AIFunc func;
};

View File

@ -2,16 +2,35 @@
#include "tinyengine/libmath.hpp"
constexpr float FightShipMaxSpeed = 400;
constexpr int FightShipLife = 10;
constexpr float FightShipRotationDegree = 6;
constexpr float FightShipAccelration = 200;
constexpr float FreightShipMaxSpeed = 100;
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 FreightShipLife = 15;
constexpr float FreightShipAccelerate = 100;
constexpr float LazerDamage = 3.4;
constexpr float LazerShooterSpeed = 800;
constexpr float LazerShooterMaxSpeed = 2000;
constexpr float LazerShooterCooldown = 0.15;
constexpr float MissileRotateDegree = 150;
constexpr float CoreMaxHp = 100;
constexpr int CoreEnergyProductDuration = 2;
constexpr int CoreEnergyProductAmount = 1;
constexpr Size GameWindowSize = {1024, 720};
constexpr Rect BulletRefreshArea{-100, -100, 1124, 820};
constexpr Rect SpaceshipRefreshArea{-1024 * 3, -720 * 3, 1024 * 7, 720 * 7};
constexpr int BlockSize = 16;
constexpr int PlayerGroup = 0;
constexpr int Enemy1Group = 1;
constexpr int Enemy2Group = 2;
constexpr int Enemy3Group = 3;
constexpr float EntityRenderSize = 20;
constexpr float EntityCollisionSize = 16;

View File

@ -4,7 +4,7 @@
#include "game/component.hpp"
#include "game/global.hpp"
Entity* CreateFreightShip();
Entity* CreateFightShip();
Entity* CreateBullet(int damage, Entity* owner, float maxSpeed);
Entity* CreateMissile(int damage, Entity* owner, float maxSpeed, Entity* target);
Entity* CreateFreightShip(int group);
Entity* CreateFightShip(int group);
Entity* CreateBullet(int group, int damage, Entity* owner, float maxSpeed);
Entity* CreateMissile(int group, int damage, Entity* owner, float maxSpeed, Entity* target);

View File

@ -2,6 +2,7 @@
#include "tinyengine/tinyengine.hpp"
#include "game/quick_list.hpp"
#include "game/init_info.hpp"
extern Context ECSContext;
extern SystemManager SystemMgr;
@ -13,6 +14,10 @@ extern QuickList<Entity*> Entities;
extern Entity* PlayerSpaceship;
extern std::array<QuickList<Entity*>, 4> Groups;
extern GameInitInfo InitInfo;
void LoadResources();
Point MapGlobal2PlayerCoord(const Point& pos);
Point MapPlayerCoord2Global(const Point& pos);

View File

@ -2,4 +2,4 @@
#include "tinyengine/tinyengine.hpp"
bool Button(Texture* texture, const Point& pos, const Size& size);
bool Button(Texture* texture, const Point& pos, const Size& size, bool hflip = false);

View File

@ -0,0 +1,12 @@
#pragma once
enum PlaneType {
FreightShip = 1,
FightShip,
};
struct GameInitInfo {
int planeType;
int groupNum;
int planeNum;
};

View File

@ -5,12 +5,15 @@
template <typename T>
class QuickList final {
public:
using condition_func = std::function<bool(const T&)>;
using destroy_func = std::function<void(const T&)>;
void Add(const T& elem) {
datas_.push_back(elem);
}
void RemoveAll(std::function<bool(const T&)> findFunc,
std::function<void(const T&)> destroyFunc = nullptr) {
void RemoveAll(condition_func findFunc,
destroy_func destroyFunc = nullptr) {
std::size_t idx = 0;
while (idx < datas_.size()) {
if (datas_.size() > idx && findFunc(datas_[idx])) {
@ -24,7 +27,13 @@ public:
}
}
}
void Clear() { datas_.clear(); }
void Clear(condition_func condition = nullptr, destroy_func destroy = nullptr) {
if (destroy && condition) {
RemoveAll(condition, destroy);
}
datas_.clear();
}
// for debug
void PrintAll(std::function<void(const T&)> func = nullptr) {

View File

@ -0,0 +1,23 @@
#pragma once
#include "tinyengine/tinyengine.hpp"
class SelectScence: public Scence {
public:
void OnInit() override;
void OnRender() override;
private:
Unique<Texture> switchBtn_;
Unique<Texture> goBtn_;
Camera camera_;
void renderTitle();
void renderSelectTitle();
void renderConfigTitle();
void renderSelectShip();
void renderProperties();
void renderGoBtn();
void renderGroupNumPanel();
void renderPlaneNumPanel();
};

View File

@ -6,6 +6,7 @@
#include "game/system.hpp"
#include "game/controllers/freightship_controller.hpp"
#include "game/controllers/fightship_controller.hpp"
#include "game/ai.hpp"
class SpaceScence: public Scence {
public:
@ -15,13 +16,15 @@ public:
void OnQuit() override;
private:
Unique<FreightShipController> freightController_;
Unique<FightShipController> fightController_;
void renderBackground();
void renderGUI();
void renderMiniMap();
void renderWeapons(SpaceshipWeaponCmpt* weapon1, SpaceshipWeaponCmpt* weapon2);
Camera guiCamera_;
Camera gameCamera_;
std::vector<Point> stars_;
};

View File

@ -56,3 +56,16 @@ private:
void renderEntity(Entity* entity, const RenderCmpt&, float rotation);
void renderCollideBox(Entity* entity);
};
class EnergyProductSystem: public UpdateSystem {
public:
void Update(float) override;
private:
void coolDown(EnergyProductCmpt& cmpt, float dt);
};
class AIUpdateSystem: public UpdateSystem {
public:
void Update(float) override;
};

View File

@ -11,6 +11,7 @@ public:
void Scale(const Point& scale);
void SetAnchor(const Point& anchor);
bool TryCalcView();
const Point& GetPosition() const { return position_; }
private:
Mat44 viewMat_;

View File

@ -133,3 +133,5 @@ private:
}
}
};
using EntityPtr = Entity*;

View File

@ -5,6 +5,13 @@ void OnWindowResize(GLFWwindow* window, int width, int height);
bool IsKeyPressing(int key);
void InitEvent(const Size& windowInitSize);
bool IsLeftPressing();
bool IsRightPressing();
bool IsLeftPressed();
bool IsRightPressed();
Point GetMousePosition();
void EventUpdate();
void MouseBtnCallback(GLFWwindow* window, int button, int action, int mods);

View File

@ -102,7 +102,36 @@ inline bool IsPointInRect(const Point& p, const Rect& r) {
return r.x <= p.x && r.y <= p.y && r.x + r.w >= p.x && r.y + r.h >= p.y;
}
/* a matrix stored in row major*/
template <typename T>
class Mat {
public:
Mat(const Size& size): size_(size) {
data_.resize(size.w * size.h);
}
T Get(const Point& p) const {
return data_.at(p.x * size_.h + p.y);
}
T& Get(const Point& p) {
return data_.at(p.x * size_.h + p.y);
}
void Set(const Point& p, const T& value) {
data_.at(p.y + p.x * size_.h) = value;
}
bool InMat(const Point& p) const {
return p.x >= 0 && p.y >= 0 && p.x < size_.w && p.y < size_.h;
}
inline void Fill(const T& t) { data_.fill(t); }
const Size& GetSize() const { return size_; }
private:
std::vector<T> data_;
Size size_;
};
/* a matrix stored in col major*/
class Mat44{
public:
static const Mat44 Eye;
@ -172,3 +201,7 @@ inline Mat44 CreateSRT(const Point& pos, const Point& scale, float degree) {
0, 0, 0, 1,
});
}
inline float Distance(const Point& p1, const Point& p2) {
return Len(p1 - p2);
}

View File

@ -34,3 +34,36 @@ void Shoot(SpaceshipWeaponCmpt& weapon, const Point& dir, Entity* target) {
}
}
void MoveLeft(MotionCmpt& motion) {
motion.acceleration += Point{-FreightShipAccelerate, 0};
}
void MoveRight(MotionCmpt& motion) {
motion.acceleration += Point{FreightShipAccelerate, 0};
}
void MoveUp(MotionCmpt& motion) {
motion.acceleration += Point{0, -FreightShipAccelerate};
}
void MoveDown(MotionCmpt& motion) {
motion.acceleration += Point{0, FreightShipAccelerate};
}
void SpeedUp(MotionCmpt& motion, FightShipCmpt& ship) {
motion.acceleration = Rotate(Point{0, FightShipAccelration},
-ship.degree);
}
void SpeedDown(MotionCmpt& motion, FightShipCmpt& ship) {
motion.acceleration = Rotate(Point{0, -FightShipAccelration},
-ship.degree);
}
void TurnLeft(FightShipCmpt& ship) {
ship.degree += FightShipRotationDegree;
}
void TurnRight(FightShipCmpt& ship) {
ship.degree -= FightShipRotationDegree;
}

50
src/game/ai.cpp Normal file
View File

@ -0,0 +1,50 @@
#include "game/ai.hpp"
void FreightShipAI(Entity* self) {
auto pmove = PlayerSpaceship->Get<MoveCmpt>();
auto smove = self->Get<MoveCmpt>();
auto dir = pmove->position - smove->position;
if (Len2(dir) > 250000) {
auto motion = self->Use<MotionCmpt>();
if (dir.x < 0) {
MoveLeft(*motion);
} else {
MoveRight(*motion);
}
if (dir.y < 0) {
MoveUp(*motion);
} else {
MoveDown(*motion);
}
} else {
Shoot(*self->Get<FreightShipCmpt>()->weapon, dir);
}
}
void FightShipAI(Entity* self) {
auto pmove = PlayerSpaceship->Get<MoveCmpt>();
auto smove = self->Get<MoveCmpt>();
auto dir = pmove->position - smove->position;
auto motion = self->Use<MotionCmpt>();
auto ship = self->Use<FightShipCmpt>();
auto nspd = Normalize(motion->speed),
ndir = Normalize(dir);
SpeedUp(*motion, *ship);
auto cross = Cross(nspd, ndir);
if (cross > std::sin(Radians(80))) {
TurnLeft(*ship);
} else if (cross < std::sin(Radians(10))) {
TurnRight(*ship);
}
// 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);
// }
// }
}

View File

@ -6,7 +6,7 @@ Entity* SpaceshipWeaponCmpt::ShootBullet(const Point& dir) {
if (bulletAmount != InfBullet) {
bulletAmount --;
}
Entity* bullet = CreateBullet(damage, owner, maxSpeed);
Entity* bullet = CreateBullet(owner->Get<GroupCmpt>()->groupIdx, damage, owner, maxSpeed);
bullet->Use<MotionCmpt>()->speed = Normalize(dir) * shootSpeed;
bullet->Use<MoveCmpt>()->position = owner->Get<MoveCmpt>()->position;
return bullet;
@ -17,7 +17,7 @@ Entity* SpaceshipWeaponCmpt::ShootMissile(const Point& dir, Entity* target) {
if (bulletAmount != InfBullet) {
bulletAmount --;
}
Entity* bullet = CreateMissile(damage, owner, maxSpeed, target);
Entity* bullet = CreateMissile(owner->Get<GroupCmpt>()->groupIdx, damage, owner, maxSpeed, target);
if (target) {
bullet->Use<BulletCmpt>()->rotation = Degrees(std::acos(Dot(dir, Normalize(target->Get<MoveCmpt>()->position - owner->Get<MoveCmpt>()->position))));
}

View File

@ -7,33 +7,38 @@ FightShipController::FightShipController(Entity* entity)
void FightShipController::Update(float dt) {
const float spd = 100;
auto motionCmpt = entity_->Use<MotionCmpt>();
float& rotation = entity_->Use<FightShipCmpt>()->degree;
auto ship = entity_->Use<FightShipCmpt>();
if (IsKeyPressing(GLFW_KEY_A)) {
rotation += 2;
TurnLeft(*ship);
}
if (IsKeyPressing(GLFW_KEY_D)) {
rotation -= 2;
TurnRight(*ship);
}
if (IsKeyPressing(GLFW_KEY_S)) {
motionCmpt->acceleration = Rotate(Point{0, spd}, -rotation);
SpeedUp(*motionCmpt, *ship);
}
if (IsKeyPressing(GLFW_KEY_W)) {
motionCmpt->acceleration = Rotate(Point{0, -spd}, -rotation);
SpeedDown(*motionCmpt, *ship);
}
motionCmpt->speed = Rotate(Point{0, -1} * Len(motionCmpt->speed),
-rotation);
-ship->degree);
auto fightShip = entity_->Use<FightShipCmpt>();
auto weapon1 = fightShip->weapon1,
weapon2 = fightShip->weapon2;
auto moveCmpt = entity_->Get<MoveCmpt>();
if (IsLeftPressing()) {
weaponShoot(weapon1, *moveCmpt);
if (entity_->Has<FightShipCmpt>()) {
weaponShoot(entity_->Use<FightShipCmpt>()->weapon1, *moveCmpt);
} else if (entity_->Has<FreightShipCmpt>()) {
weaponShoot(entity_->Use<FreightShipCmpt>()->weapon, *moveCmpt);
}
}
if (IsRightPressing()) {
weaponShoot(weapon2, *moveCmpt);
if (entity_->Has<FightShipCmpt>()) {
weaponShoot(entity_->Use<FightShipCmpt>()->weapon2, *moveCmpt);
} else if (entity_->Has<FreightShipCmpt>()) {
weaponShoot(entity_->Use<FreightShipCmpt>()->weapon, *moveCmpt);
}
}
}

View File

@ -8,16 +8,16 @@ void FreightShipController::Update(float dt) {
const float spd = 100;
auto motionCmpt = entity_->Use<MotionCmpt>();
if (IsKeyPressing(GLFW_KEY_A)) {
motionCmpt->acceleration += Point{-spd, 0};
MoveLeft(*motionCmpt);
}
if (IsKeyPressing(GLFW_KEY_D)) {
motionCmpt->acceleration += Point{spd, 0};
MoveRight(*motionCmpt);
}
if (IsKeyPressing(GLFW_KEY_S)) {
motionCmpt->acceleration += Point{0, spd};
MoveDown(*motionCmpt);
}
if (IsKeyPressing(GLFW_KEY_W)) {
motionCmpt->acceleration += Point{0, -spd};
MoveUp(*motionCmpt);
}
if (IsLeftPressing()) {

View File

@ -1,7 +1,7 @@
#include "game/entity.hpp"
#include "game/constants.hpp"
Entity* CreateFreightShip() {
Entity* CreateFreightShip(int group) {
Entity* entity = ECSContext.CreateEntity();
entity->Add<MoveCmpt>(Point{0, 0});
entity->Add<MotionCmpt>(Point{0, 0}, FreightShipMaxSpeed);
@ -13,14 +13,15 @@ Entity* CreateFreightShip() {
LazerDamage,
LazerShooterSpeed,
LazerShooterMaxSpeed,
LazerShooterCooldown);
entity->Add<CollisionCmpt>(Size{16, 16});
entity->Add<LifeCmpt>(FreightLife);
LazerShooterCooldown + 1);
entity->Add<CollisionCmpt>(Size{EntityCollisionSize, EntityCollisionSize});
entity->Add<LifeCmpt>(FreightShipLife);
entity->Add<FreightShipCmpt>(weapon);
entity->Add<GroupCmpt>(group);
return entity;
}
Entity* CreateFightShip() {
Entity* CreateFightShip(int group) {
Entity* entity = ECSContext.CreateEntity();
entity->Add<MoveCmpt>(Point{0, 0});
entity->Add<MotionCmpt>(Point{0, 0}, FightShipMaxSpeed);
@ -44,28 +45,31 @@ Entity* CreateFightShip() {
LazerShooterCooldown,
10);
entity->Add<CollisionCmpt>(Size{16, 16});
entity->Add<LifeCmpt>(FreightLife);
entity->Add<CollisionCmpt>(Size{EntityCollisionSize, EntityCollisionSize});
entity->Add<LifeCmpt>(FightShipLife);
entity->Add<FightShipCmpt>(weapon1, weapon2);
entity->Add<GroupCmpt>(group);
return entity;
}
Entity* CreateBullet(int damage, Entity* owner, float maxSpeed) {
Entity* CreateBullet(int group, int damage, Entity* owner, float maxSpeed) {
Entity* entity = ECSContext.CreateEntity();
entity->Add<MoveCmpt>(Point{0, 0});
entity->Add<MotionCmpt>(Point{0, 0}, maxSpeed);
entity->Add<RenderCmpt>(GameTileSheet->GetTile(0, 1));
entity->Add<BulletCmpt>(BulletCmpt::Bullet, damage, owner);
entity->Add<CollisionCmpt>(Size{8, 8});
entity->Add<GroupCmpt>(group);
return entity;
}
Entity* CreateMissile(int damage, Entity* owner, float maxSpeed, Entity* target) {
Entity* CreateMissile(int group, int damage, Entity* owner, float maxSpeed, Entity* target) {
Entity* entity = ECSContext.CreateEntity();
entity->Add<MoveCmpt>(Point{0, 0});
entity->Add<MotionCmpt>(Point{0, 0}, maxSpeed);
entity->Add<RenderCmpt>(GameTileSheet->GetTile(2, 1));
entity->Add<BulletCmpt>(BulletCmpt::Missile, damage, owner, target);
entity->Add<CollisionCmpt>(Size{10, 10});
entity->Add<GroupCmpt>(group);
return entity;
}

View File

@ -9,7 +9,10 @@ std::unordered_map<std::string, Unique<Sound>> Sounds;
QuickList<Entity*> Bullets;
QuickList<Entity*> Entities;
Entity* PlayerSpaceship;
Entity* PlayerSpaceship = nullptr;
GameInitInfo InitInfo;
std::array<QuickList<Entity*>, 4> Groups;
void loadImages() {
GameTileSheet.reset(new TileSheet("assets/tilesheet.png", 8, 8));

View File

@ -1,11 +1,13 @@
#include "game/gui.hpp"
#include "tinyengine/event.hpp"
bool Button(Texture* texture, const Point& pos, const Size& size) {
Renderer::DrawTexture(texture, nullptr, pos, size);
if (IsLeftPressing() &&
IsPointInRect(GetMousePosition(), Rect{pos.x - size.w / 2, pos.y - size.h / 2, size.w, size.h})) {
return true;
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);
Rect rect = Rect{pos.x - size.w / 2, pos.y - size.h / 2, size.w, size.h};
if (IsPointInRect(GetMousePosition(), rect)) {
Renderer::SetDrawColor(Color{1, 1, 1, 0.2});
Renderer::FillRect(rect);
return IsLeftPressed();
} else {
return false;
}

0
src/game/init_info.cpp Normal file
View File

View File

@ -1,8 +1,10 @@
#include "game/stages/gamelogo.hpp"
#include "game/stages/space.hpp"
#include "game/stages/welcome.hpp"
#include "game/stages/select.hpp"
#include "game/constants.hpp"
RUN_WINDOW("Space Sector", GameWindowSize.w, GameWindowSize.h, WelcomeScence)
// RUN_WINDOW("Space Sector", GameWindowSize.w, GameWindowSize.h, SpaceScence)
// RUN_WINDOW("Space Sector", GameWindowSize.w, GameWindowSize.h, GameLogoScence)
// RUN_WINDOW("Space War v1.0", GameWindowSize.w, GameWindowSize.h, SelectScence)
// RUN_WINDOW("Space War v1.0", GameWindowSize.w, GameWindowSize.h, SpaceScence)
RUN_WINDOW("Space War v1.0", GameWindowSize.w, GameWindowSize.h, WelcomeScence)
// RUN_WINDOW("Space War v1.0", GameWindowSize.w, GameWindowSize.h, GameLogoScence)

View File

@ -1,5 +1,5 @@
#include "game/stages/gamelogo.hpp"
#include "game/stages/space.hpp"
#include "game/stages/welcome.hpp"
constexpr float TitlePixel = 40.0f;
constexpr float AuthorInfoPixel = 20.0f;
@ -41,6 +41,6 @@ void GameLogoScence::OnRender() {
}
if (duration > 4) {
engine.ChangeScence(new SpaceScence);
engine.ChangeScence(new WelcomeScence);
}
}

187
src/game/stages/select.cpp Normal file
View File

@ -0,0 +1,187 @@
#include "game/stages/select.hpp"
#include "game/constants.hpp"
#include "game/gui.hpp"
#include "game/global.hpp"
#include "game/stages/space.hpp"
void SelectScence::OnInit() {
// TODO move it to welcome stage
LoadResources();
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.groupNum = 2;
}
void SelectScence::OnRender() {
renderTitle();
renderSelectTitle();
renderSelectShip();
renderProperties();
renderConfigTitle();
renderGroupNumPanel();
renderPlaneNumPanel();
renderGoBtn();
}
void SelectScence::renderTitle() {
std::string title = "PREPARATION ROOM";
engine.GetInnerBmpFont().Render(title,
40,
Point{(GameWindowSize.w - title.length() * 40) / 2, 50},
Color{0.5, 0.5, 0, 1});
}
void SelectScence::renderSelectTitle() {
engine.GetInnerBmpFont().Render("SELECT PLANE",
30,
Point{80, 150},
Color{0.2, 0.2, 0.8, 1});
}
void SelectScence::renderConfigTitle() {
engine.GetInnerBmpFont().Render("CONFIG WAR",
30,
Point{600, 150},
Color{0.2, 0.2, 0.8, 1});
}
void SelectScence::renderSelectShip() {
if (Button(switchBtn_.get(), Point{100, 300}, switchBtn_->GetSize() * 2)) {
InitInfo.planeType ++;
if (InitInfo.planeType > 2) {
InitInfo.planeType = 1;
}
}
if (Button(switchBtn_.get(), Point{400, 300}, switchBtn_->GetSize() * 2, true)) {
InitInfo.planeType --;
if (InitInfo.planeType < 1) {
InitInfo.planeType = 2;
}
}
static float rotation = 0;
if (InitInfo.planeType == FreightShip) {
Renderer::DrawTile(GameTileSheet->GetTile(0, 0),
Point{250, 300},
Size{64, 64},
rotation);
} else if (InitInfo.planeType == FightShip) {
Renderer::DrawTile(GameTileSheet->GetTile(1, 0),
Point{250, 300},
Size{64, 64},
rotation);
}
rotation += 2;
}
void SelectScence::renderProperties() {
auto& font = engine.GetInnerBmpFont();
if (InitInfo.planeType == 1) {
font.Render("HP: " + std::to_string(FreightShipLife),
20,
Point{80, 400},
Color{1, 0.1, 0.1, 1});
font.Render("MAX SPEED: " + std::to_string(int(FreightShipMaxSpeed)),
20,
Point{80, 420},
Color{1, 1, 0, 1});
font.Render("MAX ACCELERATION: " + std::to_string(int(FreightShipAccelerate)),
20,
Point{80, 440},
Color{0.7, 0.7, 0, 1});
font.Render("FREE SLOW SHOOT",
20,
Point{80, 460},
Color{0, 0.7, 0.7, 1});
font.Render("FREE MOVE",
20,
Point{80, 480},
Color{0, 0.7, 0.7, 1});
font.Render("ONE WEAPON",
20,
Point{80, 500},
Color{0, 0.7, 0.7, 1});
} else if (InitInfo.planeType == 2) {
font.Render("HP: " + std::to_string(FightShipLife),
20,
Point{80, 400},
Color{1, 0.1, 0.1, 1});
font.Render("MAX SPEED: " + std::to_string(int(FightShipMaxSpeed)),
20,
Point{80, 420},
Color{1, 1, 0, 1});
font.Render("MAX ACCELERATION: " + std::to_string(int(FightShipAccelration)),
20,
Point{80, 440},
Color{0.7, 0.7, 0, 1});
font.Render("DIRECT FAST SHOOT",
20,
Point{80, 460},
Color{0, 0.7, 0.7, 1});
font.Render("DIRECT MOVE",
20,
Point{80, 480},
Color{0, 0.7, 0.7, 1});
font.Render("TWO WEAPON",
20,
Point{80, 500},
Color{0, 0.7, 0.7, 1});
}
}
void SelectScence::renderGroupNumPanel() {
auto& font = engine.GetInnerBmpFont();
font.Render("GROUP NUMBER:",
20,
Point{600, 300},
Color{0.6, 0.3, 0.8, 1});
if (Button(switchBtn_.get(), Point{870, 310}, Size{switchBtn_->GetSize().w, 20})) {
InitInfo.groupNum --;
if (InitInfo.groupNum <= 1)
InitInfo.groupNum = 4;
}
font.Render(std::to_string(InitInfo.groupNum), 20, Point{890, 300}, Color{0.6, 0.3, 0.8, 1});
if (Button(switchBtn_.get(), Point{920, 310}, Size{switchBtn_->GetSize().w, 20}, true)) {
InitInfo.groupNum ++;
if (InitInfo.groupNum > 4)
InitInfo.groupNum = 2;
}
}
void SelectScence::renderPlaneNumPanel() {
auto& font = engine.GetInnerBmpFont();
font.Render("PLANE NUMBER:",
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;
}
font.Render(std::to_string(InitInfo.planeNum), 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;
}
}
void SelectScence::renderGoBtn() {
if (Button(goBtn_.get(),
Point{800, 600},
goBtn_->GetSize() * 4)) {
engine.ChangeScence(new SpaceScence);
} else {
engine.GetInnerBmpFont().Render("GO", 40, Point{760, 570}, Color{1, 0, 1, 1});
}
}

View File

@ -2,40 +2,64 @@
void SpaceScence::OnInit() {
Renderer::SetClearColor(Color{0, 0, 0, 255});
LoadResources();
Entities.Clear();
Bullets.Clear();
PlayerSpaceship = CreateFightShip();
PlayerSpaceship = CreateFightShip(PlayerGroup);
Entities.Add(PlayerSpaceship);
PlayerSpaceship->Use<MoveCmpt>()->position = Point{400, 400};
Entity* enemy = CreateFreightShip();
Entity* enemy = CreateFreightShip(Enemy1Group);
enemy->Add<AICmpt>(FreightShipAI);
enemy->Use<MoveCmpt>()->position = Point{100, 100};
Entities.Add(enemy);
enemy = CreateFreightShip();
enemy = CreateFreightShip(Enemy1Group);
enemy->Add<AICmpt>(FreightShipAI);
enemy->Use<MoveCmpt>()->position = Point{200, 100};
Entities.Add(enemy);
enemy = CreateFreightShip();
enemy = CreateFreightShip(Enemy1Group);
enemy->Add<AICmpt>(FreightShipAI);
enemy->Use<MoveCmpt>()->position = Point{100, 200};
Entities.Add(enemy);
// freightController_.reset(new FreightShipController(spaceship_));
// 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));
gameCamera_.SetAnchor(GameWindowSize / 2);
SystemMgr.Clear();
SystemMgr.AddUpdateSystem(new AIUpdateSystem);
SystemMgr.AddUpdateSystem(new WeaponCooldownSystem);
SystemMgr.AddUpdateSystem(new EnergyProductSystem);
SystemMgr.AddUpdateSystem(new MissileUpdateSystem);
SystemMgr.AddUpdateSystem(new PhysicalSystem);
SystemMgr.AddUpdateSystem(new ColliRectCorrectSystem);
SystemMgr.AddUpdateSystem(new CollideSystem);
SystemMgr.AddUpdateSystem(new CleanupSystem);
SystemMgr.AddRenderSystem(new RenderEntitySystem);
for (int i = 0; i < 100; i++) {
Point p{Random<float>(0, GameWindowSize.w),
Random<float>(0, GameWindowSize.h)};
stars_.push_back(p);
}
}
void SpaceScence::OnUpdate(float dt) {
@ -46,12 +70,33 @@ void SpaceScence::OnUpdate(float dt) {
void SpaceScence::OnRender() {
Renderer::SetCamera(gameCamera_);
renderBackground();
SystemMgr.Render();
Renderer::SetCamera(guiCamera_);
renderGUI();
}
void SpaceScence::renderBackground() {
Renderer::SetDrawColor(Color{1, 1, 1, 1});
Point p;
p.x = std::floor(gameCamera_.GetPosition().x / GameWindowSize.w) * GameWindowSize.w;
p.y = std::floor(gameCamera_.GetPosition().y / GameWindowSize.h) * GameWindowSize.h;
for (auto& star : stars_) {
Point pos{p.x + star.x, p.y + star.y};
if (pos.x < gameCamera_.GetPosition().x) {
pos.x += GameWindowSize.w;
}
if (pos.y < gameCamera_.GetPosition().y) {
pos.y += GameWindowSize.h;
}
Rect drawrect = {pos.x - GameWindowSize.w / 2, pos.y - GameWindowSize.h / 2, 2, 2};
Renderer::FillRect(drawrect);
}
}
void SpaceScence::renderGUI() {
Renderer::SetCamera(guiCamera_);
@ -123,6 +168,7 @@ void SpaceScence::renderWeapons(SpaceshipWeaponCmpt* weapon1, SpaceshipWeaponCmp
}
offset.y += 20;
}
if (weapon2) {
font.Render(weapon2->name,
20,
@ -135,8 +181,18 @@ void SpaceScence::renderWeapons(SpaceshipWeaponCmpt* weapon1, SpaceshipWeaponCmp
Point{weaponInfoRect.x + weaponInfoRect.w - 100, weaponInfoRect.y} + offset,
Color{0, 0.8, 0, 1});
}
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() {

View File

@ -1,16 +1,23 @@
#include "game/stages/welcome.hpp"
#include "game/gui.hpp"
#include "game/stages/space.hpp"
#include "game/constants.hpp"
#include "game/stages/select.hpp"
void WelcomeScence::OnInit() {
startImage_.reset(new Texture("assets/start_btn.png"));
exitImage_.reset(new Texture("assets/exit_btn.png"));
GLFWimage image;
image.pixels = stbi_load("assets/cursor.png", &image.width, &image.height, nullptr, 0);
auto cursor = glfwCreateCursor(&image, image.width / 2, image.height / 2);
glfwSetCursor(engine.GetWindow(), cursor);
stbi_image_free(image.pixels);
}
void WelcomeScence::OnRender() {
Renderer::SetCamera(camera_);
auto& font = engine.GetInnerBmpFont();
std::string title = "SPACE SECTOR";
std::string title = "SPACE WAR";
int pt = 70;
font.Render(title, pt,
Point{(GameWindowSize.w - title.size() * pt) / 2, 100},
@ -22,11 +29,17 @@ void WelcomeScence::OnRender() {
Point{(GameWindowSize.w - title.size() * pt) / 2, 200},
Color{0.8, 0.8, 1, 1});
title = "HTTPS://GITEE.COM/VISUALGMQ/SPACE-SECTOR.GIT";
pt = 10;
font.Render(title, pt,
Point{(GameWindowSize.w - title.size() * pt) / 2, 710},
Color{0.8, 0.8, 1, 1});
if (Button(exitImage_.get(), Point{(GameWindowSize.w) / 2, 550}, Size{100, 100})) {
engine.Exit();
}
if (Button(startImage_.get(), Point{(GameWindowSize.w) / 2, 400}, Size{100, 100})) {
engine.ChangeScence(new SpaceScence);
engine.ChangeScence(new SelectScence);
}
}

View File

@ -7,7 +7,6 @@ void PhysicalSystem::Update(float dt) {
physicalStep(entity, dt,
*entity->Use<MoveCmpt>(),
*entity->Use<MotionCmpt>());
}
}
@ -93,7 +92,8 @@ void CollideSystem::Update(float dt) {
for (auto& bullet : Bullets) {
for (auto& entity: Entities) {
if (entity->Has<CollisionCmpt>() &&
bullet->Get<BulletCmpt>()->owner != entity &&
entity->Has<GroupCmpt>() &&
bullet->Get<GroupCmpt>()->groupIdx != entity->Get<GroupCmpt>()->groupIdx &&
IsRectsIntersect(bullet->Get<CollisionCmpt>()->rect,
entity->Get<CollisionCmpt>()->rect)) {
if (entity->Has<LifeCmpt>()) {
@ -119,10 +119,7 @@ void CleanupSystem::Update(float dt) {
Entities.RemoveAll([](const EntityPtr& entity){
if (entity->Has<LifeCmpt>() &&
entity->Get<LifeCmpt>()->hp <= 0 ||
entity->Has<MoveCmpt>() &&
!IsPointInRect(MapGlobal2PlayerCoord(entity->Get<MoveCmpt>()->position),
SpaceshipRefreshArea)) {
entity->Get<LifeCmpt>()->hp <= 0) {
return true;
} else {
return false;
@ -186,13 +183,41 @@ void RenderEntitySystem::renderEntity(Entity* entity, const RenderCmpt& renderCm
Renderer::DrawTexture(renderCmpt.texture,
nullptr,
pos,
Size{0, 0},
Size{EntityRenderSize, EntityRenderSize},
rotation);
} else {
Renderer::DrawTile(renderCmpt.tile,
pos,
Size{0, 0},
Size{EntityRenderSize, EntityRenderSize},
rotation);
}
}
}
void EnergyProductSystem::Update(float dt) {
for (auto& entity: Entities) {
if (entity->Has<EnergyProductCmpt>()) {
coolDown(*entity->Use<EnergyProductCmpt>(), dt);
}
}
}
void EnergyProductSystem::coolDown(EnergyProductCmpt& cmpt, float dt) {
if (cmpt.IsCoolDowning()) {
cmpt.cooldown -= dt;
} else {
cmpt.cooldown = cmpt.duration;
cmpt.amount += cmpt.productAmount;
}
}
void AIUpdateSystem::Update(float) {
for (auto& entity : Entities) {
if (entity->Has<AICmpt>()) {
auto func = entity->Get<AICmpt>()->func;
if (func) {
func(entity);
}
}
}
}

View File

@ -8,6 +8,7 @@ void Engine::Init(const std::string& title, const Size& size, Scence* scence) {
if (!glfwInit()) {
FATAL_ERROR("glfw init failed");
}
InitEvent(size);
glfwSetErrorCallback(error_callback);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
@ -27,7 +28,8 @@ void Engine::Init(const std::string& title, const Size& size, Scence* scence) {
glfwMakeContextCurrent(window_);
glfwSetFramebufferSizeCallback(engine.GetWindow(), OnWindowResize);
glfwSetFramebufferSizeCallback(window_, OnWindowResize);
glfwSetMouseButtonCallback(window_, MouseBtnCallback);
if (!gladLoadGL(glfwGetProcAddress)) {
glfwTerminate();
@ -75,6 +77,7 @@ void Engine::SwapContext() {
}
void Engine::PollEvent() {
EventUpdate();
glfwPollEvents();
}
@ -87,7 +90,7 @@ void Engine::Shutdown() {
}
void Engine::Update(float deltaTime) {
deltaTime = std::min(deltaTime, 0.3f);
deltaTime = std::min(deltaTime, 0.03f);
if (scence_)
scence_->OnUpdate(deltaTime);
}

View File

@ -1,10 +1,43 @@
#include "tinyengine/event.hpp"
#include "tinyengine/engine.hpp"
struct {
struct MouseState {
bool left = false;
bool right = false;
} MouseState;
};
struct {
MouseState oldState;
MouseState state;
} MouseContext;
void MouseBtnCallback(GLFWwindow* window, int button, int action, int mods) {
if (action == GLFW_PRESS) {
if (button == GLFW_MOUSE_BUTTON_LEFT) {
MouseContext.state.left = true;
}
if (button == GLFW_MOUSE_BUTTON_RIGHT) {
MouseContext.state.right = true;
}
} else if (action == GLFW_RELEASE) {
if (button == GLFW_MOUSE_BUTTON_LEFT) {
MouseContext.state.left = false;
}
if (button == GLFW_MOUSE_BUTTON_RIGHT) {
MouseContext.state.right = false;
}
}
}
void EventUpdate() {
MouseContext.oldState = MouseContext.state;
}
Size WindowInitSize;
void InitEvent(const Size& windowInitSize) {
WindowInitSize = windowInitSize;
}
void OnWindowResize(GLFWwindow* window, int width, int height) {
Renderer::SetViewport(0, 0, width, height);
@ -15,15 +48,24 @@ bool IsKeyPressing(int key) {
}
bool IsLeftPressing() {
return glfwGetMouseButton(engine.GetWindow(), GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS;
return MouseContext.state.left;
}
bool IsRightPressing() {
return glfwGetMouseButton(engine.GetWindow(), GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS;
return MouseContext.state.right;
}
bool IsLeftPressed() {
return MouseContext.state.left && !MouseContext.oldState.left;
}
bool IsRightPressed() {
return MouseContext.state.right && !MouseContext.oldState.right;
}
Point GetMousePosition() {
double x, y;
glfwGetCursorPos(engine.GetWindow(), &x, &y);
return Point{float(x), float(y)};
return Point{float(x) * WindowInitSize.w / engine.GetWindowSize().w,
float(y) * WindowInitSize.h / engine.GetWindowSize().h};
}

View File

@ -363,6 +363,24 @@ InnerBmpFont::InnerBmpFont() {
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0});
saveChar('/',
{0,0,0,0,0,0,0,0,
0,0,0,0,0,1,1,0,
0,0,0,0,1,1,1,0,
0,0,0,1,1,0,0,0,
0,0,0,1,1,0,0,0,
0,1,1,1,0,0,0,0,
0,1,1,0,0,0,0,0,
0,0,0,0,0,0,0,0});
saveChar('.',
{0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,1,1,0,
0,0,0,0,0,1,1,0});
errorChar_ = fontMat({1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,1,