diff --git a/include/td/game/Mobs.h b/include/td/game/Mobs.h
index 3a9fe37..3b299a2 100644
--- a/include/td/game/Mobs.h
+++ b/include/td/game/Mobs.h
@@ -6,8 +6,8 @@
#include
#include |
-#include
#include
+#include
namespace td {
namespace game {
@@ -42,8 +42,7 @@ typedef std::uint8_t MobLevel;
typedef std::vector TowerImmunities;
typedef std::vector EffectImmunities;
-class MobStats {
-private:
+struct MobStats {
float m_Damage;
float m_Speed;
Vec2f m_Size;
@@ -51,27 +50,12 @@ private:
std::uint16_t m_ExpCost;
std::uint16_t m_MaxLife;
std::uint16_t m_ExpReward;
-public:
- MobStats(float damage, float speed, Vec2f size, std::uint16_t moneyCost,
- std::uint16_t expCost, std::uint16_t expReward,
- std::uint16_t maxLife) : m_Damage(damage), m_Speed(speed),
- m_Size(size), m_MoneyCost(moneyCost), m_ExpCost(expCost),
- m_MaxLife(maxLife), m_ExpReward(expReward) {
- }
-
- float GetDamage() const { return m_Damage; }
- float GetMovementSpeed() const { return m_Speed; }
- const Vec2f& GetSize() const { return m_Size; }
- std::uint16_t GetMoneyCost() const { return m_MoneyCost; }
- std::uint16_t GetExpCost() const { return m_ExpCost; }
- std::uint16_t GetExpReward() const { return m_ExpReward; }
- std::uint16_t GetMaxLife() const { return m_MaxLife; }
};
struct EffectDuration {
EffectType type;
- float duration; // in seconds
- Tower* tower; // the tower that gived the effect
+ float duration; // in seconds
+ Tower* tower; // the tower that gived the effect
};
const MobStats* GetMobStats(MobType type, std::uint8_t level);
@@ -79,15 +63,16 @@ const TowerImmunities& GetMobTowerImmunities(MobType type, std::uint8_t level);
const EffectImmunities& GetMobEffectImmunities(MobType type, std::uint8_t level);
class Mob : public utils::shape::Rectangle {
-protected:
+ protected:
float m_Health;
-private:
+
+ private:
MobID m_ID;
PlayerID m_Sender;
MobLevel m_Level;
Direction m_Direction;
std::vector m_Effects;
- const Tower* m_LastDamage; // the last tower that damaged the mob
+ const Tower* m_LastDamage; // the last tower that damaged the mob
float m_HitCooldown;
// utils::Timer m_EffectFireTimer;
@@ -97,30 +82,55 @@ private:
TeamCastle* m_CastleTarget;
// utils::CooldownTimer m_AttackTimer;
-public:
- Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level),
- m_HitCooldown(0), m_CastleTarget(nullptr) {
+ public:
+ Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level), m_HitCooldown(0), m_CastleTarget(nullptr) {}
- }
+ virtual ~Mob() {}
virtual MobType GetType() const = 0;
- virtual void Tick(std::uint64_t delta, World* world);
+ virtual void Tick(std::uint64_t delta, World* world) {}
- virtual bool OnDeath(World* world) { return true; }
+ virtual bool OnDeath(World* world) {
+ return true;
+ }
- MobID GetMobID() const { return m_ID; }
- const TowerImmunities& GetTowerImmunities() const { return GetMobTowerImmunities(GetType(), m_Level); }
- const EffectImmunities& GetEffectImmunities() const { return GetMobEffectImmunities(GetType(), m_Level); }
- PlayerID GetSender() const { return m_Sender; }
- MobLevel GetLevel() const { return m_Level; }
- const MobStats* GetStats() const { return GetMobStats(GetType(), m_Level); }
- void SetHealth(float newHealth) { m_Health = newHealth; }
- float GetHealth() const { return m_Health; }
- bool IsDead() const { return m_Health <= 0; }
- bool IsAlive() const { return m_Health > 0; }
- const Tower* GetLastDamageTower() { return m_LastDamage; }
- bool HasReachedEnemyCastle() { return m_CastleTarget != nullptr; }
+ MobID GetMobID() const {
+ return m_ID;
+ }
+ const TowerImmunities& GetTowerImmunities() const {
+ return GetMobTowerImmunities(GetType(), m_Level);
+ }
+ const EffectImmunities& GetEffectImmunities() const {
+ return GetMobEffectImmunities(GetType(), m_Level);
+ }
+ PlayerID GetSender() const {
+ return m_Sender;
+ }
+ MobLevel GetLevel() const {
+ return m_Level;
+ }
+ const MobStats* GetStats() const {
+ return GetMobStats(GetType(), m_Level);
+ }
+ void SetHealth(float newHealth) {
+ m_Health = newHealth;
+ }
+ float GetHealth() const {
+ return m_Health;
+ }
+ bool IsDead() const {
+ return m_Health <= 0;
+ }
+ bool IsAlive() const {
+ return m_Health > 0;
+ }
+ const Tower* GetLastDamageTower() {
+ return m_LastDamage;
+ }
+ bool HasReachedEnemyCastle() {
+ return m_CastleTarget != nullptr;
+ }
void Damage(float dmg, const Tower* damager) {
m_Health = std::max(0.0f, m_Health - dmg);
@@ -129,10 +139,12 @@ public:
}
void Heal(float heal) {
- m_Health = std::min(static_cast(GetStats()->GetMaxLife()), m_Health + heal);
+ m_Health = std::min(static_cast(GetStats()->m_MaxLife), m_Health + heal);
}
- void SetMobReachedCastle(TeamCastle* castle) { m_CastleTarget = castle; } // used when mob is in front of the castle
+ void SetMobReachedCastle(TeamCastle* castle) {
+ m_CastleTarget = castle;
+ } // used when mob is in front of the castle
bool IsImmuneTo(TowerType type);
@@ -140,19 +152,34 @@ public:
void AddEffect(EffectType type, float durationSec, Tower* tower);
bool HasEffect(EffectType type);
- bool HasTakenDamage() { return m_HitCooldown > 0; }
-
- float GetTileX() { return GetCenterX() - static_cast(static_cast(GetCenterX())); } // returns a float between 0 and 1 excluded
- float GetTileY() { return GetCenterY() - static_cast(static_cast(GetCenterY())); } // returns a float between 0 and 1 excluded
-
- Direction GetDirection() const { return m_Direction; }
- void SetDirection(Direction dir) { m_Direction = dir; }
-protected:
- void InitMob() {
- m_Health = static_cast(GetStats()->GetMaxLife());
- SetSize(GetStats()->GetSize().x, GetStats()->GetSize().y);
+ bool HasTakenDamage() {
+ return m_HitCooldown > 0;
}
-private:
+
+ // returns a float between 0 and 1 excluded
+ float GetTileX() {
+ return GetCenterX() - static_cast(static_cast(GetCenterX()));
+ }
+
+ // returns a float between 0 and 1 excluded
+ float GetTileY() {
+ return GetCenterY() - static_cast(static_cast(GetCenterY()));
+ }
+
+ Direction GetDirection() const {
+ return m_Direction;
+ }
+ void SetDirection(Direction dir) {
+ m_Direction = dir;
+ }
+
+ protected:
+ void InitMob() {
+ m_Health = static_cast(GetStats()->m_MaxLife);
+ SetSize(GetStats()->m_Size.x, GetStats()->m_Size.y);
+ }
+
+ private:
void UpdateEffects(std::uint64_t delta, World* world);
void AttackCastle(std::uint64_t delta, World* world);
void Move(std::uint64_t delta, World* world);
@@ -165,85 +192,42 @@ private:
typedef std::shared_ptr MobPtr;
-class Zombie : public Mob {
-public:
- Zombie(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
+template
+class ConcreteMob : public Mob {
+ public:
+ ConcreteMob(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) {
+ InitMob();
+ }
- virtual MobType GetType() const { return MobType::Zombie; }
+ virtual ~ConcreteMob() {}
+
+ virtual void Tick(std::uint64_t delta, World* world) {}
+
+ virtual constexpr MobType GetType() const {
+ return MT;
+ }
};
-class Spider : public Mob {
-public:
- Spider(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
-
- virtual MobType GetType() const { return MobType::Spider; }
-};
-
-class Skeleton : public Mob {
-public:
- Skeleton(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
-
- virtual MobType GetType() const { return MobType::Skeleton; }
-};
-
-class PigMan : public Mob {
-public:
- PigMan(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
-
- virtual MobType GetType() const { return MobType::Pigman; }
-};
-
-class Creeper : public Mob {
-public:
- Creeper(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
-
- virtual MobType GetType() const { return MobType::Creeper; }
-};
-
-class Silverfish : public Mob {
-public:
- Silverfish(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
-
- virtual MobType GetType() const { return MobType::Silverfish; }
-};
-
-class Blaze : public Mob {
-public:
- Blaze(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
-
- virtual MobType GetType() const { return MobType::Blaze; }
-};
-
-class Witch : public Mob {
-public:
- Witch(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
-
- virtual MobType GetType() const { return MobType::Witch; }
-};
-
-class Slime : public Mob {
-public:
- Slime(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
-
- virtual MobType GetType() const { return MobType::Slime; }
-};
-
-class Giant : public Mob {
-public:
- Giant(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
-
- virtual MobType GetType() const { return MobType::Giant; }
-};
+using Zombie = ConcreteMob;
+using Spider = ConcreteMob;
+using Skeleton = ConcreteMob;
+using PigMan = ConcreteMob;
+using Creeper = ConcreteMob;
+using Silverfish = ConcreteMob;
+using Blaze = ConcreteMob;
+using Witch = ConcreteMob;
+using Slime = ConcreteMob;
+using Giant = ConcreteMob;
namespace MobFactory {
MobPtr CreateMob(MobID id, MobType type, std::uint8_t level, PlayerID sender);
std::string GetMobName(MobType type);
-}
+} // namespace MobFactory
class MobListener {
-public:
+ public:
virtual void OnMobSpawn(Mob* mob) {}
virtual void OnMobDie(Mob* mob) {}
@@ -255,6 +239,5 @@ public:
// typedef utils::ObjectNotifier MobNotifier;
-} // namespace game
-} // namespace td
-
+} // namespace game
+} // namespace td
diff --git a/include/td/render/renderer/EntityRenderer.h b/include/td/render/renderer/EntityRenderer.h
new file mode 100644
index 0000000..4f6562c
--- /dev/null
+++ b/include/td/render/renderer/EntityRenderer.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include |
+#include |
+#include |
+
+namespace td {
+namespace render {
+
+class EntityRenderer : public Renderer {
+ private:
+ const game::World& m_World;
+ std::unique_ptr m_EntityVao;
+
+ public:
+ EntityRenderer(Camera& a_Camera, const game::World& a_World);
+ virtual ~EntityRenderer();
+
+ virtual void Render() override;
+};
+
+} // namespace render
+} // namespace td
diff --git a/include/td/render/shader/EntityShader.h b/include/td/render/shader/EntityShader.h
index 765d908..1c7c948 100644
--- a/include/td/render/shader/EntityShader.h
+++ b/include/td/render/shader/EntityShader.h
@@ -1,14 +1,12 @@
#pragma once
-#include |
+#include |
namespace td {
namespace shader {
-class EntityShader : public ShaderProgram {
+class EntityShader : public CameraShaderProgram {
private:
- unsigned int m_LocationProjectionMatrix = 0;
- unsigned int m_LocationViewMatrix = 0;
unsigned int m_LocationPosition = 0;
unsigned int m_LocationColorEffect = 0;
@@ -18,11 +16,7 @@ class EntityShader : public ShaderProgram {
public:
EntityShader();
- void LoadShader();
-
void SetColorEffect(const Vec3f& color);
- void SetProjectionMatrix(const Mat4f& proj) const;
- void SetViewMatrix(const Mat4f& view) const;
void SetModelPos(const Vec3f& pos) const;
};
diff --git a/src/main.cpp b/src/main.cpp
index e17c847..281f48c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -6,7 +6,9 @@
#include |
#include |
+
#include |
+#include |
namespace td {
namespace game {
@@ -202,8 +204,13 @@ int main(int argc, char** argv) {
td::render::Camera cam;
+ auto mob = std::make_shared(0, 0, 0);
+ mob->SetCenter({77, 13});
+ w.GetMobList().push_back(mob);
+
td::render::RenderPipeline renderer;
renderer.AddRenderer(cam, w);
+ renderer.AddRenderer(cam, w);
cam.SetCamPos({77, 25, 13});
cam.UpdatePerspective(display.GetAspectRatio());
diff --git a/src/td/game/Mobs.cpp b/src/td/game/Mobs.cpp
new file mode 100644
index 0000000..1cae4a7
--- /dev/null
+++ b/src/td/game/Mobs.cpp
@@ -0,0 +1,24 @@
+#include
+
+namespace td {
+namespace game {
+
+
+const MobStats* GetMobStats(MobType type, std::uint8_t level) {
+ static MobStats stats;
+ return &stats;
+}
+
+const TowerImmunities& GetMobTowerImmunities(MobType type, std::uint8_t level) {
+ static TowerImmunities ti;
+ return ti;
+}
+
+const EffectImmunities& GetMobEffectImmunities(MobType type, std::uint8_t level) {
+ static EffectImmunities ei;
+ return ei;
+}
+
+
+} // namespace game
+} // namespace td
diff --git a/src/td/render/loader/WorldLoader.cpp b/src/td/render/loader/WorldLoader.cpp
index 9854c4c..cf1beee 100644
--- a/src/td/render/loader/WorldLoader.cpp
+++ b/src/td/render/loader/WorldLoader.cpp
@@ -159,9 +159,9 @@ GL::VertexArray LoadTileSelectModel() {
colorVBO.AddVertexAttribPointer(1, 1, 0);
std::vector indexes(positions.size() / 3, 0);
- for (size_t i = 0; i < indexes.size(); i++) {
- indexes[i] = i + 1;
- }
+ // for (size_t i = 0; i < indexes.size(); i++) {
+ // indexes[i] = i + 1;
+ // }
GL::ElementBuffer indexVBO(indexes);
GL::VertexArray tileSelectVao(std::move(indexVBO));
@@ -211,6 +211,36 @@ RenderData LoadTowerModel(game::TowerPtr tower) {
}
+
+GL::VertexArray LoadMobModel() {
+ std::vector positions = {
+ -0.5, 0, -0.5,
+ -0.5, 0, 0.5,
+ 0.5, 0, -0.5,
+
+ 0.5, 0, -0.5,
+ -0.5, 0, 0.5,
+ 0.5, 0, 0.5
+ };
+
+ std::vector indexes(positions.size() / 3, 0);
+ // for (size_t i = 0; i < indexes.size(); i++) {
+ // indexes[i] = i + 1;
+ // }
+ GL::ElementBuffer indexVBO(indexes);
+
+ GL::VertexBuffer positionVBO(positions, POSITION_VERTEX_SIZE);
+ positionVBO.AddVertexAttribPointer(0, POSITION_VERTEX_SIZE, 0);
+
+ GL::VertexArray mobVao(std::move(indexVBO)); // each pos = 1 color
+ mobVao.Bind();
+ mobVao.BindVertexBuffer(std::move(positionVBO));
+ mobVao.Unbind();
+ return mobVao;
+}
+
+
+
} // namespace WorldLoader
diff --git a/src/td/render/renderer/EntityRenderer.cpp b/src/td/render/renderer/EntityRenderer.cpp
new file mode 100644
index 0000000..1c8dac4
--- /dev/null
+++ b/src/td/render/renderer/EntityRenderer.cpp
@@ -0,0 +1,26 @@
+#include |
+
+#include |
+
+namespace td {
+namespace render {
+
+EntityRenderer::EntityRenderer(Camera& a_Camera, const game::World& a_World) : Renderer(a_Camera), m_World(a_World) {
+ m_EntityVao = std::make_unique(std::move(WorldLoader::LoadMobModel()));
+ m_Shader->Start();
+ m_Shader->SetColorEffect({1, 0, 1});
+}
+
+EntityRenderer::~EntityRenderer() {}
+
+void EntityRenderer::Render() {
+ m_Shader->Start();
+ for (const auto& mob : m_World.GetMobList()) {
+ const auto mobCoords = mob->GetCenter();
+ m_Shader->SetModelPos({mobCoords.GetX(), 1, mobCoords.GetY()});
+ Renderer::Render(*m_EntityVao);
+ }
+}
+
+} // namespace render
+} // namespace td
diff --git a/src/td/render/shader/EntityShader.cpp b/src/td/render/shader/EntityShader.cpp
index 4b4dd06..3080487 100644
--- a/src/td/render/shader/EntityShader.cpp
+++ b/src/td/render/shader/EntityShader.cpp
@@ -53,16 +53,12 @@ static const char vertexSource[] = R"(
#version 330
layout(location = 0) in vec3 position;
-layout(location = 1) in vec2 textureCoords;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform vec3 modelPosition;
-out vec2 pass_textureCoords;
-
void main(void){
- pass_textureCoords = textureCoords;
gl_Position = projectionMatrix * viewMatrix * vec4(position + modelPosition, 1.0);
}
)";
@@ -70,16 +66,13 @@ void main(void){
static const char fragmentSource[] = R"(
#version 330
-in vec2 pass_textureCoords;
-
out vec4 out_color;
uniform vec3 ColorEffect;
-uniform sampler2D textureSampler;
void main(void){
- vec4 color = vec4(ColorEffect, 1.0) * texture(textureSampler, pass_textureCoords);
+ vec4 color = vec4(ColorEffect, 1.0);
if (color.a <= 0.1)
discard;
@@ -90,31 +83,21 @@ void main(void){
)";
#endif
-EntityShader::EntityShader() : ShaderProgram() {}
-
-void EntityShader::LoadShader() {
+EntityShader::EntityShader() : CameraShaderProgram() {
ShaderProgram::LoadProgram(vertexSource, fragmentSource);
}
+
void EntityShader::GetAllUniformLocation() {
+ CameraShaderProgram::GetAllUniformLocation();
m_LocationColorEffect = static_cast(GetUniformLocation("ColorEffect"));
- m_LocationViewMatrix = static_cast(GetUniformLocation("viewMatrix"));
m_LocationPosition = static_cast(GetUniformLocation("modelPosition"));
- m_LocationProjectionMatrix = static_cast(GetUniformLocation("projectionMatrix"));
}
void EntityShader::SetColorEffect(const Vec3f& color) {
LoadVector(m_LocationColorEffect, color);
}
-void EntityShader::SetProjectionMatrix(const Mat4f& proj) const {
- LoadMat4(m_LocationProjectionMatrix, proj);
-}
-
-void EntityShader::SetViewMatrix(const Mat4f& view) const {
- LoadMat4(m_LocationViewMatrix, view);
-}
-
void EntityShader::SetModelPos(const Vec3f& pos) const {
LoadVector(m_LocationPosition, pos);
}
| | | | |