finished basic spaceship, it can move and shoot
This commit is contained in:
parent
d1fbdb1898
commit
71096200f6
|
@ -25,8 +25,7 @@ add_subdirectory(libs/glfw)
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
${ENGINE_NAME}
|
${ENGINE_NAME}
|
||||||
PRIVATE include/tinyengine
|
PUBLIC include libs/glad/include libs/stb_image libs/miniaudio # /usr/local/Cellar/glm/0.9.9.8/include
|
||||||
PUBLIC libs/glad/include libs/stb_image libs/miniaudio # /usr/local/Cellar/glm/0.9.9.8/include
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
|
@ -54,13 +53,9 @@ target_compile_options(
|
||||||
################
|
################
|
||||||
aux_source_directory(src/game GAME_SRC)
|
aux_source_directory(src/game GAME_SRC)
|
||||||
aux_source_directory(src/game/stages GAME_SRC)
|
aux_source_directory(src/game/stages GAME_SRC)
|
||||||
|
aux_source_directory(src/game/controllers GAME_SRC)
|
||||||
add_executable(${PROJECT_NAME} ${GAME_SRC})
|
add_executable(${PROJECT_NAME} ${GAME_SRC})
|
||||||
|
|
||||||
target_include_directories(
|
|
||||||
${PROJECT_NAME}
|
|
||||||
PRIVATE include
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
${PROJECT_NAME}
|
${PROJECT_NAME}
|
||||||
PRIVATE ${ENGINE_NAME}
|
PRIVATE ${ENGINE_NAME}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 488 B |
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
#include "game/component.hpp"
|
||||||
|
#include "game/entity.hpp"
|
||||||
|
|
||||||
|
void Shoot(SpaceshipWeaponCmpt& weapon, const Point& dir);
|
|
@ -0,0 +1,125 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
#include "game/constants.hpp"
|
||||||
|
|
||||||
|
class MoveCmpt: public Component {
|
||||||
|
public:
|
||||||
|
void Init(const Point& p) { position = p; }
|
||||||
|
void Release() {}
|
||||||
|
|
||||||
|
Point position;
|
||||||
|
Point oldPosition = {0, 0};
|
||||||
|
};
|
||||||
|
|
||||||
|
class MotionCmpt: public Component {
|
||||||
|
public:
|
||||||
|
void Init(const Point& spd, float maxSpd) {
|
||||||
|
speed = spd;
|
||||||
|
maxSpeed = maxSpd;
|
||||||
|
}
|
||||||
|
void Release() {}
|
||||||
|
|
||||||
|
Point speed;
|
||||||
|
Point acceleration = {0, 0};
|
||||||
|
|
||||||
|
float maxSpeed;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CollisionCmpt: public Component {
|
||||||
|
public:
|
||||||
|
void Init(const Size& size) { rect.w = size.w; rect.h = size.h; }
|
||||||
|
void Release() {}
|
||||||
|
|
||||||
|
Rect rect;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpaceshipWeaponCmpt: public Component {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Orientation = 0x01,
|
||||||
|
FreeRotation = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
void Init(Type type,
|
||||||
|
Entity* owner,
|
||||||
|
int damage,
|
||||||
|
float shootSpeed,
|
||||||
|
float maxSpeed,
|
||||||
|
float duration) {
|
||||||
|
this->type = type;
|
||||||
|
this->owner = owner;
|
||||||
|
this->damage = damage;
|
||||||
|
this->shootSpeed = shootSpeed;
|
||||||
|
this->shootDuration = duration;
|
||||||
|
this->maxSpeed = maxSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Release() {}
|
||||||
|
bool IsCoolDowning() const { return coolDown >= 0; }
|
||||||
|
Entity* ShootBullet(const Point& dir);
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
int damage;
|
||||||
|
float shootSpeed;
|
||||||
|
float shootDuration;
|
||||||
|
float coolDown;
|
||||||
|
float maxSpeed;
|
||||||
|
Entity* owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpaceshipArmorCmpt: public Component {
|
||||||
|
public:
|
||||||
|
void Init(int defence, float duration) {
|
||||||
|
this->defence = defence;
|
||||||
|
this->recoverDuration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
int defence;
|
||||||
|
float recoverDuration;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LifeCmpt: public Component {
|
||||||
|
public:
|
||||||
|
void Init(int hp) { this->hp = hp; }
|
||||||
|
void Release() {}
|
||||||
|
|
||||||
|
int hp;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RenderCmpt: public Component {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
TypeTexture = 1,
|
||||||
|
TypeTile,
|
||||||
|
};
|
||||||
|
|
||||||
|
void Init(Texture* image) {
|
||||||
|
texture = image;
|
||||||
|
type = TypeTexture;
|
||||||
|
}
|
||||||
|
void Init(const Tile& tile) {
|
||||||
|
this->tile = tile;
|
||||||
|
type = TypeTile;
|
||||||
|
}
|
||||||
|
void Release() {}
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
union {
|
||||||
|
Texture* texture;
|
||||||
|
Tile tile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class BulletCmpt: public Component {
|
||||||
|
public:
|
||||||
|
inline void Init(int damage, Entity* owner) {
|
||||||
|
this->owner = owner;
|
||||||
|
this->damage = damage;
|
||||||
|
}
|
||||||
|
inline void Release() override {}
|
||||||
|
|
||||||
|
int damage;
|
||||||
|
Entity* owner;
|
||||||
|
bool alive;
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
constexpr float FreightMaxSpeed = 100;
|
||||||
|
constexpr float LazerDamage = 2;
|
||||||
|
constexpr float LazerShooterSpeed = 1000;
|
||||||
|
constexpr float LazerShooterMaxSpeed = 1000;
|
||||||
|
constexpr float LazerShooterCooldown = 0.3;
|
||||||
|
constexpr int GameWindowWidth = 1024;
|
||||||
|
constexpr int GameWindowHeight = 720;
|
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
public:
|
||||||
|
virtual ~Controller() = default;
|
||||||
|
|
||||||
|
virtual void Update(float dt) = 0;
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "game/controller.hpp"
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
#include "game/entity.hpp"
|
||||||
|
#include "game/component.hpp"
|
||||||
|
#include "game/action.hpp"
|
||||||
|
|
||||||
|
class FreeRotationController: public Controller {
|
||||||
|
public:
|
||||||
|
FreeRotationController(Entity* entity);
|
||||||
|
void Update(float dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Entity* entity_;
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
#include "game/component.hpp"
|
||||||
|
#include "game/global.hpp"
|
||||||
|
|
||||||
|
Entity* CreateFreightShip();
|
||||||
|
Entity* CreateBullet(int damage, Entity* owner, float maxSpeedß);
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
#include "game/quick_list.hpp"
|
||||||
|
|
||||||
|
extern Context ECSContext;
|
||||||
|
extern SystemManager SystemMgr;
|
||||||
|
extern std::unordered_map<std::string, Unique<TileSheet>> TileSheets;
|
||||||
|
extern std::unordered_map<std::string, Unique<Sound>> Sounds;
|
||||||
|
extern std::string TileSheetName;
|
||||||
|
|
||||||
|
extern QuickList<Entity*> Bullets;
|
||||||
|
|
||||||
|
using EntityList = std::vector<Entity*>;
|
||||||
|
|
||||||
|
extern EntityList Entities;
|
||||||
|
|
||||||
|
void LoadResources();
|
|
@ -0,0 +1,45 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class QuickList final {
|
||||||
|
public:
|
||||||
|
void Add(const T& elem) {
|
||||||
|
datas_.push_back(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveAll(std::function<bool(const T&)> func) {
|
||||||
|
int idx = 0;
|
||||||
|
while (idx < datas_.size()) {
|
||||||
|
if (func(datas_[idx]) && datas_.size() > idx) {
|
||||||
|
std::swap(datas_[idx], datas_[datas_.size() - 1]);
|
||||||
|
datas_.pop_back();
|
||||||
|
} else {
|
||||||
|
idx ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Clear() { datas_.clear(); }
|
||||||
|
|
||||||
|
// for debug
|
||||||
|
void PrintAll(std::function<void(const T&)> func = nullptr) {
|
||||||
|
printf("QuickList: ");
|
||||||
|
for (auto& elem : datas_) {
|
||||||
|
if (func == nullptr) {
|
||||||
|
std::cout << elem << ", ";
|
||||||
|
} else {
|
||||||
|
func(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
using const_iterator = typename std::vector<T>::const_iterator;
|
||||||
|
|
||||||
|
const_iterator begin() const { return datas_.begin(); }
|
||||||
|
const_iterator end() const { return datas_.end(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<T> datas_;
|
||||||
|
};
|
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
#include "game/global.hpp"
|
||||||
|
#include "game/entity.hpp"
|
||||||
|
#include "game/system.hpp"
|
||||||
|
#include "game/controllers/spaceship_controller.hpp"
|
||||||
|
|
||||||
|
class SpaceScence: public Scence {
|
||||||
|
public:
|
||||||
|
void OnInit() override;
|
||||||
|
void OnUpdate(float dt) override;
|
||||||
|
void OnRender() override;
|
||||||
|
void OnQuit() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Entity* spaceship_;
|
||||||
|
Unique<FreeRotationController> controller_;
|
||||||
|
};
|
|
@ -0,0 +1,41 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tinyengine/ecs/system.hpp"
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
#include "game/global.hpp"
|
||||||
|
#include "game/component.hpp"
|
||||||
|
#include "game/entity.hpp"
|
||||||
|
|
||||||
|
class PhysicalSystem: public UpdateSystem {
|
||||||
|
public:
|
||||||
|
void Update(float dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void physicalStep(Entity* entity, float dt, MoveCmpt&, MotionCmpt&);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ColliRectCorrectSystem: public UpdateSystem {
|
||||||
|
public:
|
||||||
|
void Update(float dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void correctColliRect(MoveCmpt&, CollisionCmpt&);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CleanupSystem: public UpdateSystem {
|
||||||
|
public:
|
||||||
|
void Update(float dt) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BulletCooldownSystem: public UpdateSystem {
|
||||||
|
public:
|
||||||
|
void Update(float dt) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RenderEntitySystem: public RenderSystem {
|
||||||
|
public:
|
||||||
|
void Render() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void renderEntity(Entity* entity, const RenderCmpt&);
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
_Pragma("once")
|
_Pragma("once")
|
||||||
|
|
||||||
#include "pch.hpp"
|
#include "tinyengine/pch.hpp"
|
||||||
#include "pool.hpp"
|
#include "tinyengine/pool.hpp"
|
||||||
|
|
||||||
using ComponentId = unsigned int;
|
using ComponentId = unsigned int;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
_Pragma("once")
|
_Pragma("once")
|
||||||
|
|
||||||
#include "pool.hpp"
|
#include "tinyengine/pool.hpp"
|
||||||
#include "component.hpp"
|
#include "component.hpp"
|
||||||
|
|
||||||
class Entity;
|
class Entity;
|
||||||
|
|
|
@ -3,3 +3,4 @@ _Pragma("once")
|
||||||
#include "entity.hpp"
|
#include "entity.hpp"
|
||||||
#include "component.hpp"
|
#include "component.hpp"
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
|
#include "system.hpp"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
_Pragma("once")
|
#pragma once
|
||||||
|
|
||||||
#include "pch.hpp"
|
#include "tinyengine/pch.hpp"
|
||||||
#include "pool.hpp"
|
#include "tinyengine/pool.hpp"
|
||||||
#include "component.hpp"
|
#include "component.hpp"
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "entity.hpp"
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
|
||||||
|
class System {
|
||||||
|
public:
|
||||||
|
virtual ~System() = default;
|
||||||
|
|
||||||
|
bool IsWorking() const { return active_; }
|
||||||
|
void StartWork() { active_ = true; }
|
||||||
|
void StopWork() { active_ = false; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool active_ = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UpdateSystem: public System {
|
||||||
|
public:
|
||||||
|
virtual ~UpdateSystem() = default;
|
||||||
|
|
||||||
|
virtual void Update(float dt) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RenderSystem: public System {
|
||||||
|
public:
|
||||||
|
virtual ~RenderSystem() = default;
|
||||||
|
|
||||||
|
virtual void Render() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SystemManager final {
|
||||||
|
public:
|
||||||
|
void AddUpdateSystem(UpdateSystem* system) { updateSystems_.emplace_back(system); }
|
||||||
|
void AddRenderSystem(RenderSystem* system) { renderSystems_.emplace_back(system); }
|
||||||
|
|
||||||
|
void Update(float dt);
|
||||||
|
void Render();
|
||||||
|
|
||||||
|
void Clear() { ClearUpdateSystems(); ClearRenderSystems(); }
|
||||||
|
void ClearUpdateSystems() { updateSystems_.clear(); }
|
||||||
|
void ClearRenderSystems() { renderSystems_.clear(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Ref<UpdateSystem>> updateSystems_;
|
||||||
|
std::vector<Ref<RenderSystem>> renderSystems_;
|
||||||
|
};
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "pch.hpp"
|
#include "pch.hpp"
|
||||||
#include "libmath.hpp"
|
#include "libmath.hpp"
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
|
|
|
@ -2,3 +2,9 @@
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
|
|
||||||
void OnWindowResize(GLFWwindow* window, int width, int height);
|
void OnWindowResize(GLFWwindow* window, int width, int height);
|
||||||
|
|
||||||
|
bool IsKeyPressing(int key);
|
||||||
|
|
||||||
|
bool IsLeftPressing();
|
||||||
|
bool IsRightPressing();
|
||||||
|
Point GetMousePosition();
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
#include "glad/gl.h"
|
#include "glad/gl.h"
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
#include "stb_image.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include "miniaudio.h"
|
#include "miniaudio.h"
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
#ifdef USE_GLM
|
#ifdef USE_GLM
|
||||||
#include "glm/glm.hpp"
|
#include "glm/glm.hpp"
|
||||||
|
|
|
@ -11,3 +11,4 @@
|
||||||
#include "inner_bmpfont.hpp"
|
#include "inner_bmpfont.hpp"
|
||||||
#include "audio.hpp"
|
#include "audio.hpp"
|
||||||
#include "tilesheet.hpp"
|
#include "tilesheet.hpp"
|
||||||
|
#include "ecs/ecs.hpp"
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "game/action.hpp"
|
||||||
|
|
||||||
|
void Shoot(SpaceshipWeaponCmpt& weapon, const Point& dir) {
|
||||||
|
if (weapon.IsCoolDowning()) return;
|
||||||
|
|
||||||
|
Point playerCenterPos = weapon.owner->Get<MoveCmpt>()->position;
|
||||||
|
|
||||||
|
auto bullet = weapon.ShootBullet(Normalize(dir) * weapon.shootSpeed);
|
||||||
|
Bullets.Add(bullet);
|
||||||
|
|
||||||
|
weapon.coolDown = weapon.shootDuration;
|
||||||
|
|
||||||
|
Sounds["shoot"]->Play();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "game/component.hpp"
|
||||||
|
#include "game/entity.hpp"
|
||||||
|
|
||||||
|
Entity* SpaceshipWeaponCmpt::ShootBullet(const Point& dir) {
|
||||||
|
Entity* bullet = CreateBullet(damage, owner, maxSpeed);
|
||||||
|
bullet->Use<MotionCmpt>()->speed = Normalize(dir) * shootSpeed;
|
||||||
|
bullet->Use<MoveCmpt>()->position = owner->Get<MoveCmpt>()->position;
|
||||||
|
return bullet;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include "game/controllers/spaceship_controller.hpp"
|
||||||
|
#include "tinyengine/event.hpp"
|
||||||
|
|
||||||
|
FreeRotationController::FreeRotationController(Entity* entity)
|
||||||
|
: entity_(entity) {}
|
||||||
|
|
||||||
|
void FreeRotationController::Update(float dt) {
|
||||||
|
const float spd = 100;
|
||||||
|
auto motionCmpt = entity_->Use<MotionCmpt>();
|
||||||
|
if (IsKeyPressing(GLFW_KEY_A)) {
|
||||||
|
// motionCmpt->speed += Point{-spd, 0};
|
||||||
|
motionCmpt->acceleration += Point{-spd, 0};
|
||||||
|
// motionCmpt->speed.x = -spd;
|
||||||
|
}
|
||||||
|
if (IsKeyPressing(GLFW_KEY_D)) {
|
||||||
|
// motionCmpt->speed += Point{spd, 0};
|
||||||
|
motionCmpt->acceleration += Point{spd, 0};
|
||||||
|
// motionCmpt->speed.x = spd;
|
||||||
|
}
|
||||||
|
if (IsKeyPressing(GLFW_KEY_S)) {
|
||||||
|
// motionCmpt->speed += Point{0, spd};
|
||||||
|
motionCmpt->acceleration += Point{0, spd};
|
||||||
|
// motionCmpt->speed.y = spd;
|
||||||
|
}
|
||||||
|
if (IsKeyPressing(GLFW_KEY_W)) {
|
||||||
|
// motionCmpt->speed += Point{0, -spd};
|
||||||
|
motionCmpt->acceleration += Point{0, -spd};
|
||||||
|
// motionCmpt->speed.y = -spd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsLeftPressing()) {
|
||||||
|
if (entity_->Has<SpaceshipWeaponCmpt>()) {
|
||||||
|
Shoot(*entity_->Use<SpaceshipWeaponCmpt>(),
|
||||||
|
GetMousePosition() - entity_->Get<MoveCmpt>()->position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "game/entity.hpp"
|
||||||
|
|
||||||
|
Entity* CreateFreightShip() {
|
||||||
|
Entity* entity = ECSContext.CreateEntity();
|
||||||
|
entity->Add<MoveCmpt>(Point{0, 0});
|
||||||
|
entity->Add<MotionCmpt>(Point{0, 0}, FreightMaxSpeed);
|
||||||
|
entity->Add<RenderCmpt>(TileSheets[TileSheetName]->GetTile(0, 0));
|
||||||
|
entity->Add<SpaceshipWeaponCmpt>(SpaceshipWeaponCmpt::Orientation,
|
||||||
|
entity,
|
||||||
|
LazerDamage,
|
||||||
|
LazerShooterSpeed,
|
||||||
|
LazerShooterMaxSpeed,
|
||||||
|
LazerShooterCooldown);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity* CreateBullet(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>(TileSheets[TileSheetName]->GetTile(0, 1));
|
||||||
|
entity->Add<BulletCmpt>(damage, owner);
|
||||||
|
return entity;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "game/global.hpp"
|
||||||
|
|
||||||
|
Context ECSContext;
|
||||||
|
SystemManager SystemMgr;
|
||||||
|
std::unordered_map<std::string, Unique<TileSheet>> TileSheets;
|
||||||
|
std::unordered_map<std::string, Unique<Sound>> Sounds;
|
||||||
|
std::string TileSheetName = "TileSheet";
|
||||||
|
QuickList<Entity*> Bullets;
|
||||||
|
EntityList Entities;
|
||||||
|
|
||||||
|
void loadImages() {
|
||||||
|
TileSheets[TileSheetName] = std::make_unique<TileSheet>("assets/tilesheet.png", 8, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadSounds() {
|
||||||
|
Sounds["shoot"] = std::make_unique<Sound>("assets/shoot.wav");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadResources() {
|
||||||
|
loadImages();
|
||||||
|
loadSounds();
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
#include "game/stages/gamelogo.hpp"
|
#include "game/stages/gamelogo.hpp"
|
||||||
|
#include "game/stages/space.hpp"
|
||||||
|
#include "game/constants.hpp"
|
||||||
|
|
||||||
RUN_WINDOW("Space Sector", 1024, 720, GameLogoScence)
|
RUN_WINDOW("Space Sector", GameWindowWidth, GameWindowHeight, SpaceScence)
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include "game/stages/space.hpp"
|
||||||
|
|
||||||
|
void SpaceScence::OnInit() {
|
||||||
|
Renderer::SetClearColor(Color{0, 0, 0, 255});
|
||||||
|
LoadResources();
|
||||||
|
|
||||||
|
spaceship_ = CreateFreightShip();
|
||||||
|
Entities.push_back(spaceship_);
|
||||||
|
spaceship_->Use<MoveCmpt>()->position = Point{400, 400};
|
||||||
|
|
||||||
|
controller_.reset(new FreeRotationController(spaceship_));
|
||||||
|
|
||||||
|
SystemMgr.Clear();
|
||||||
|
SystemMgr.AddRenderSystem(new RenderEntitySystem);
|
||||||
|
SystemMgr.AddUpdateSystem(new BulletCooldownSystem);
|
||||||
|
SystemMgr.AddUpdateSystem(new PhysicalSystem);
|
||||||
|
SystemMgr.AddUpdateSystem(new ColliRectCorrectSystem);
|
||||||
|
SystemMgr.AddUpdateSystem(new CleanupSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceScence::OnUpdate(float dt) {
|
||||||
|
controller_->Update(dt);
|
||||||
|
SystemMgr.Update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceScence::OnRender() {
|
||||||
|
SystemMgr.Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpaceScence::OnQuit() {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
#include "game/system.hpp"
|
||||||
|
|
||||||
|
void PhysicalSystem::Update(float dt) {
|
||||||
|
for (auto& entity: Entities) {
|
||||||
|
if (entity->Has<MoveCmpt>() && entity->Has<MotionCmpt>()) {
|
||||||
|
// update entities
|
||||||
|
physicalStep(entity, dt,
|
||||||
|
*entity->Use<MoveCmpt>(),
|
||||||
|
*entity->Use<MotionCmpt>());
|
||||||
|
|
||||||
|
// update bullets
|
||||||
|
for (auto& bullet : Bullets) {
|
||||||
|
if (bullet->Has<MoveCmpt>() && bullet->Has<MotionCmpt>()) {
|
||||||
|
physicalStep(bullet, dt,
|
||||||
|
*bullet->Use<MoveCmpt>(),
|
||||||
|
*bullet->Use<MotionCmpt>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicalSystem::physicalStep(Entity* entity,
|
||||||
|
float dt,
|
||||||
|
MoveCmpt& moveCmpt,
|
||||||
|
MotionCmpt& motionCmpt) {
|
||||||
|
moveCmpt.oldPosition = moveCmpt.position;
|
||||||
|
|
||||||
|
motionCmpt.speed += motionCmpt.acceleration * dt;
|
||||||
|
if (Len(motionCmpt.speed) > motionCmpt.maxSpeed) {
|
||||||
|
motionCmpt.speed = Normalize(motionCmpt.speed) * motionCmpt.maxSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveCmpt.position += motionCmpt.speed * dt + 0.5 * motionCmpt.acceleration * dt * dt;
|
||||||
|
|
||||||
|
motionCmpt.acceleration = Point{0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColliRectCorrectSystem::Update(float dt) {
|
||||||
|
for (auto& entity: Entities) {
|
||||||
|
if (entity->Has<CollisionCmpt>() &&
|
||||||
|
entity->Has<MoveCmpt>()) {
|
||||||
|
correctColliRect(*entity->Use<MoveCmpt>(),
|
||||||
|
*entity->Use<CollisionCmpt>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColliRectCorrectSystem::correctColliRect(MoveCmpt& move, CollisionCmpt& collision) {
|
||||||
|
collision.rect.x = move.position.x;
|
||||||
|
collision.rect.y = move.position.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanupSystem::Update(float dt) {
|
||||||
|
using EntityPtr = Entity*;
|
||||||
|
Bullets.RemoveAll([](const EntityPtr& entity){
|
||||||
|
return !IsPointInRect(entity->Get<MoveCmpt>()->position,
|
||||||
|
Rect{0, 0, GameWindowWidth, GameWindowHeight});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BulletCooldownSystem::Update(float dt) {
|
||||||
|
for (auto& entity : Entities) {
|
||||||
|
if (entity->Has<SpaceshipWeaponCmpt>()) {
|
||||||
|
auto weapon = entity->Use<SpaceshipWeaponCmpt>();
|
||||||
|
if (weapon->coolDown >= 0) {
|
||||||
|
weapon->coolDown -= dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderEntitySystem::Render() {
|
||||||
|
for (auto& entity: Entities) {
|
||||||
|
if (entity->Has<RenderCmpt>()) {
|
||||||
|
renderEntity(entity, *entity->Get<RenderCmpt>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& bullet: Bullets) {
|
||||||
|
renderEntity(bullet, *bullet->Get<RenderCmpt>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderEntitySystem::renderEntity(Entity* entity, const RenderCmpt& renderCmpt) {
|
||||||
|
if (entity->Has<MoveCmpt>()) {
|
||||||
|
auto& pos = entity->Get<MoveCmpt>()->position;
|
||||||
|
if (renderCmpt.type == RenderCmpt::TypeTexture) {
|
||||||
|
Renderer::DrawTexture(renderCmpt.texture,
|
||||||
|
nullptr,
|
||||||
|
pos);
|
||||||
|
} else {
|
||||||
|
Renderer::DrawTile(renderCmpt.tile,
|
||||||
|
pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
#include "audio.hpp"
|
#include "tinyengine/audio.hpp"
|
||||||
|
|
||||||
ma_engine AudioEngine;
|
ma_engine AudioEngine;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "camera.hpp"
|
#include "tinyengine/camera.hpp"
|
||||||
|
|
||||||
bool Camera::TryCalcView() {
|
bool Camera::TryCalcView() {
|
||||||
if (dirty_) {
|
if (dirty_) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "ecs/component.hpp"
|
#include "tinyengine/ecs/component.hpp"
|
||||||
#include "ecs/context.hpp"
|
#include "tinyengine/ecs/context.hpp"
|
||||||
|
|
||||||
ComponentId ComponentIdx::count_ = 0;
|
ComponentId ComponentIdx::count_ = 0;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "ecs/context.hpp"
|
#include "tinyengine/ecs/context.hpp"
|
||||||
#include "ecs/entity.hpp"
|
#include "tinyengine/ecs/entity.hpp"
|
||||||
|
|
||||||
Pool<Entity>::ElemContainer& Context::GetEntities() {
|
Pool<Entity>::ElemContainer& Context::GetEntities() {
|
||||||
return entities_.GetElems();
|
return entities_.GetElems();
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include "tinyengine/ecs/system.hpp"
|
||||||
|
|
||||||
|
void SystemManager::Update(float dt) {
|
||||||
|
for (auto& system: updateSystems_) {
|
||||||
|
if (system->IsWorking()) {
|
||||||
|
system->Update(dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemManager::Render() {
|
||||||
|
for (auto& system: renderSystems_) {
|
||||||
|
if (system->IsWorking()) {
|
||||||
|
system->Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
#include "engine.hpp"
|
#include "tinyengine/engine.hpp"
|
||||||
|
|
||||||
void error_callback(int error, const char* description) {
|
void error_callback(int error, const char* description) {
|
||||||
fprintf(stderr, "Error: %s\n", description);
|
fprintf(stderr, "Error: %s\n", description);
|
||||||
|
|
|
@ -1,5 +1,24 @@
|
||||||
#include "event.hpp"
|
#include "tinyengine/event.hpp"
|
||||||
|
#include "tinyengine/engine.hpp"
|
||||||
|
|
||||||
void OnWindowResize(GLFWwindow* window, int width, int height) {
|
void OnWindowResize(GLFWwindow* window, int width, int height) {
|
||||||
Renderer::SetViewport(0, 0, width, height);
|
Renderer::SetViewport(0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsKeyPressing(int key) {
|
||||||
|
return glfwGetKey(engine.GetWindow(), key) == GLFW_PRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLeftPressing() {
|
||||||
|
return glfwGetMouseButton(engine.GetWindow(), GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsRightPressing() {
|
||||||
|
return glfwGetMouseButton(engine.GetWindow(), GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point GetMousePosition() {
|
||||||
|
double x, y;
|
||||||
|
glfwGetCursorPos(engine.GetWindow(), &x, &y);
|
||||||
|
return Point{float(x), float(y)};
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "glhelpfunc.hpp"
|
#include "tinyengine/glhelpfunc.hpp"
|
||||||
|
|
||||||
#define CASE(e) case e: return #e;
|
#define CASE(e) case e: return #e;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "inner_bmpfont.hpp"
|
#include "tinyengine/inner_bmpfont.hpp"
|
||||||
|
|
||||||
InnerBmpFont::InnerBmpFont() {
|
InnerBmpFont::InnerBmpFont() {
|
||||||
saveChar('0',
|
saveChar('0',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "libmath.hpp"
|
#include "tinyengine/libmath.hpp"
|
||||||
|
|
||||||
Point operator+(const Point& p1, const Point& p2) {
|
Point operator+(const Point& p1, const Point& p2) {
|
||||||
return Point{p1.x + p2.x, p1.y + p2.y};
|
return Point{p1.x + p2.x, p1.y + p2.y};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "renderer.hpp"
|
#include "tinyengine/renderer.hpp"
|
||||||
#include "engine.hpp"
|
#include "tinyengine/engine.hpp"
|
||||||
|
|
||||||
Color Renderer::color_ = {255, 255, 255, 255};
|
Color Renderer::color_ = {255, 255, 255, 255};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "shader.hpp"
|
#include "tinyengine/shader.hpp"
|
||||||
|
|
||||||
GLuint createShader(const std::string& code, GLenum type) {
|
GLuint createShader(const std::string& code, GLenum type) {
|
||||||
GLuint shader;
|
GLuint shader;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "texture.hpp"
|
#include "tinyengine/texture.hpp"
|
||||||
|
|
||||||
Texture::Texture(const std::string& filename) {
|
Texture::Texture(const std::string& filename) {
|
||||||
int w, h, channels;
|
int w, h, channels;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "tilesheet.hpp"
|
#include "tinyengine/tilesheet.hpp"
|
||||||
|
|
||||||
TileSheet::TileSheet(const std::string& filename, int x, int y) {
|
TileSheet::TileSheet(const std::string& filename, int x, int y) {
|
||||||
texture_.reset(new Texture(filename));
|
texture_.reset(new Texture(filename));
|
||||||
|
|
|
@ -6,7 +6,8 @@ macro(AddTest TEST_NAME TEST_FILE)
|
||||||
target_include_directories(${TEST_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
target_include_directories(${TEST_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
AddTest(math math.cpp ${ENGINE_NAME})
|
AddTest(math math.cpp ${ENGINE_NAME})
|
||||||
AddTest(renderer renderer.cpp ${ENGINE_NAME})
|
AddTest(renderer renderer.cpp ${ENGINE_NAME})
|
||||||
AddTest(innerBmpFont innerBmpFont.cpp ${ENGINE_NAME})
|
AddTest(innerBmpFont innerBmpFont.cpp ${ENGINE_NAME})
|
||||||
AddTest(audio audio.cpp ${ENGINE_NAME})
|
AddTest(audio audio.cpp ${ENGINE_NAME})
|
||||||
|
AddTest(quicklist quicklist.cpp ${ENGINE_NAME})
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "game/quick_list.hpp"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
QuickList<int> list;
|
||||||
|
list.Add(1);
|
||||||
|
list.Add(3);
|
||||||
|
list.Add(2);
|
||||||
|
list.Add(5);
|
||||||
|
|
||||||
|
list.PrintAll();
|
||||||
|
|
||||||
|
list.RemoveAll([](const int& elem){
|
||||||
|
return elem < 3;
|
||||||
|
});
|
||||||
|
|
||||||
|
list.PrintAll();
|
||||||
|
|
||||||
|
list.RemoveAll([](const int& elem){
|
||||||
|
return elem < 10;
|
||||||
|
});
|
||||||
|
|
||||||
|
list.PrintAll();
|
||||||
|
}
|
||||||
|
|
Reference in New Issue