...
 
Commits (6)
......@@ -5,9 +5,10 @@
struct AIPlayer
{
AIPlayer(ecs::Entity target_) : target { target_ }{};
AIPlayer(ecs::Entity target_, size_t idx) : target{ target_ }, hierarchyIdx{ idx }{};
ecs::Entity target;
size_t hierarchyIdx;
};
using AIPlayerComponent = ecs::Component<AIPlayer>;
......
......@@ -18,7 +18,7 @@ using namespace vcl;
/** This function is called before the beginning of the animation loop
It is used to initialize all part-specific data */
void scene_model::setup_data(std::map<std::string,GLuint>& shaders, scene_structure& scene, gui_structure&)
void scene_model::setup_data(std::map<std::string,GLuint>& shaders, scene_structure& scene, gui_structure& gui)
{
srand(static_cast<unsigned> (time(0)));
......@@ -33,6 +33,7 @@ void scene_model::setup_data(std::map<std::string,GLuint>& shaders, scene_struct
pointDrawer.shader = shaders["mesh"];
m_timer.periodic_event_time_step = .3f;
gui.show_frame_camera = false;
}
/** This function is called at each frame of the animation loop.
......@@ -44,6 +45,8 @@ void scene_model::frame_draw(std::map<std::string,GLuint>& shaders, scene_struct
if (m_gameOver)
{
std::cout << "Game Over" << std::endl;
std::cout << "Final score : " << m_score << std::endl;
std::cout << "Maximum wave reached : " << m_waveNumber << std::endl;
glfwSetWindowShouldClose(gui.window, GLFW_TRUE);
return;
}
......@@ -90,10 +93,13 @@ void scene_model::buildEntities(std::map<std::string,GLuint>& shaders)
vec3 playerPosition = m_resources.terrainGeometry.evaluate(0.5, 0.5) + vec3 { 0, 0, 5 };
m_player = builder.buildPlayer(playerPosition, shaders);
vec3 AIPosition = m_resources.terrainGeometry.evaluate(0.4, 0.6) + vec3{ 0, 0, 5 };
vec3 AIPosition = m_resources.terrainGeometry.evaluate(0.8, 0.9) + vec3{ 0, 0, 5 };
builder.buildAICharacter(m_player, AIPosition, shaders);
AIPosition = m_resources.terrainGeometry.evaluate(0.2, 0.3) + vec3{ 0, 0, 5 };
AIPosition = m_resources.terrainGeometry.evaluate(0.2, 0.1) + vec3{ 0, 0, 5 };
builder.buildAICharacter(m_player, AIPosition, shaders);
m_nbAI = 2;
m_waveSize = 2;
m_waveNumber = 1;
m_aimCursor = m_ecs.createEntity();
m_ecs.add<TransformComponent>(m_aimCursor, vec3(0,0,2));
......@@ -110,6 +116,11 @@ void scene_model::set_gui()
ImGui::Spacing();
ImGui::SliderFloat("Time scale", &m_timer.scale, 0.1f, 3.0f);
std::ostringstream stream;
stream << "Score: " << m_score << ", Wave number " << m_waveNumber;
ImGui::Spacing();
ImGui::Text(stream.str().c_str());
}
void scene_model::logicLoop(std::map<std::string,GLuint>& shaders, scene_structure& scene, gui_structure& gui)
......@@ -151,8 +162,14 @@ void scene_model::logicLoop(std::map<std::string,GLuint>& shaders, scene_structu
m_ecs.update<HierarchyPositionUpdater::Transform2Collision>();
m_ecs.update<LockdownSystem>();
m_ecs.update<HealthSystem>(m_ecs);
m_ecs.getSystem<HealthSystem>().destroyDeadCharacter(m_ecs);
m_ecs.getSystem<HealthSystem>().destroyDeadCharacter(m_ecs, m_resources, m_score, m_nbAI);
if (m_nbAI == 0)
{
m_waveSize++;
m_waveNumber++;
createAI(shaders, m_waveSize);
}
}
void scene_model::renderLoop(std::map<std::string,GLuint>& shaders, scene_structure& scene)
......@@ -192,8 +209,8 @@ void scene_model::renderLoop(std::map<std::string,GLuint>& shaders, scene_struct
void scene_model::setupTerrainGeometry()
{
auto xWidth = 60.f;
auto yWidth = 60.f;
auto xWidth = 50.f;
auto yWidth = 50.f;
std::vector<Hole> holes {
Hole { { 0., 0. }, 3, 0.5 }
, Hole { { 0.5, 0.5 }, -1.5, 0.15 }
......@@ -324,6 +341,21 @@ void scene_model::setupCollisionRates()
completeWithSymetricals(m_resources.collisionRates);
}
void scene_model::createAI(std::map<std::string, GLuint>& shaders, const int nbAI)
{
EntityBuilder builder{ m_ecs, m_resources };
std::mt19937 gen(m_rd());
std::uniform_real_distribution<float> dis(0.0f, 1.0f);
for (int i = 0; i < nbAI; i++)
{
vec3 position = m_resources.terrainGeometry.evaluate(dis(gen), dis(gen)) + vec3(0,0,3);
builder.buildAICharacter(m_player, position, shaders);
}
m_nbAI = nbAI;
}
void scene_model::setupCamera(scene_structure& scene)
{
scene.camera.camera_type = camera_control_spherical_coordinates;
......
#pragma once
#include <vector>
#include <sstream>
#include <iostream>
#include <string>
#include <ctime>
......@@ -68,12 +70,18 @@ private:
void setupPlayerAnimation();
void setupCollisionRates();
void setupAI();
void createAI(std::map<std::string, GLuint>& shaders, const int nbAI);
private:
MyEcs m_ecs;
CommonSceneResources m_resources;
std::random_device m_rd;
int m_score;
int m_nbAI;
int m_waveSize;
int m_waveNumber;
bool m_gameOver = false;
Skybox m_skybox;
......
......@@ -45,7 +45,7 @@ struct CommonSceneResources
KeyboardMapping mouseMapping;
CharacterDescription standardCharacter;
Pool<CompletedMeshHierarchy> AIHierarchyPool{ 5 };
Pool<CompletedMeshHierarchy> AIHierarchyPool{ 20 };
};
#endif // !OTHERS_COMMON_SCENE_RESOURCES_HPP_INCLUDED
\ No newline at end of file
......@@ -95,9 +95,10 @@ ecs::Entity EntityBuilder::buildPlayer(vcl::vec3 const& position, std::map<std::
ecs::Entity EntityBuilder::buildAICharacter(ecs::Entity const target, vcl::vec3 const& position, std::map<std::string,GLuint>& shaders)
{
auto& hierarchy = m_resources.AIHierarchyPool.getFreeElement().first;
auto hierarchyPair = m_resources.AIHierarchyPool.getFreeElement();
auto& hierarchy = hierarchyPair.first;
ecs::Entity ai = buildCharacter(m_resources.standardCharacter, hierarchy, position, shaders);
m_ecs.add<CharacterDesignComponent>(ai, 3.0f, 1.0f);
m_ecs.add<AIPlayerComponent>(ai, target);
m_ecs.add<AIPlayerComponent>(ai, target, hierarchyPair.second);
return ai;
}
......@@ -2,7 +2,7 @@
#define OTHERS_POOL_HPP_INCLUDED
#include <vector>
#include <stack>
#include <deque>
#include <algorithm>
template<typename T, typename Container = std::vector<T>>
......@@ -19,7 +19,7 @@ public:
for(size_type i = 0; i < numElems; ++i)
{
m_elements.emplace_back(std::forward<Args>(args)...);
m_freeElems.push(i);
m_freeElems.push_back(i);
}
}
......@@ -39,15 +39,15 @@ public:
std::pair<T&, Handle> getFreeElement()
{
assert(hasFreeElements() && "No free elements left");
auto idx = m_freeElems.top();
m_freeElems.pop();
auto idx = m_freeElems.back();
m_freeElems.pop_back();
return { m_elements[idx], idx };
}
void freeElement(Handle h)
{
assert(!isFree(h) && "Element already free");
m_freeElems.push(h);
m_freeElems.push_back(h);
}
size_t size() { return m_elements.size(); }
......@@ -60,7 +60,7 @@ private:
private:
Container m_elements;
std::stack<size_type> m_freeElems;
std::deque<size_type> m_freeElems;
};
#endif // !OTHERS_POOL_HPP_INCLUDED
\ No newline at end of file
......@@ -8,16 +8,21 @@ void HealthSystem::update(MyEcs& myEcs, RayComponent& ray)
auto& target = myEcs.get<CharacterDesignComponent>(*ray.endEntity);
target.currentHealth -= ray.damage;
ray.damage = 0;
std::cout << "Ray endEntityHealth = " << target.currentHealth << std::endl;
if (target.currentHealth <= 0)
m_deadCharacters.push_back(*ray.endEntity);
}
}
void HealthSystem::destroyDeadCharacter(MyEcs& myEcs)
void HealthSystem::destroyDeadCharacter(MyEcs& myEcs, CommonSceneResources& ressources, int& score, int& nbAI)
{
for (auto entity = m_deadCharacters.begin(); entity != m_deadCharacters.end(); entity++)
{
if (myEcs.has<AIPlayerComponent>(*entity))
{
score++;
nbAI--;
ressources.AIHierarchyPool.freeElement(myEcs.get<AIPlayerComponent>(*entity).hierarchyIdx);
}
myEcs.destroy(*entity);
}
......
......@@ -3,6 +3,7 @@
#include "ECS.hpp"
#include "../components.hpp"
#include "../others/common_scene_resources.hpp"
struct MyEcs;
......@@ -10,7 +11,7 @@ struct HealthSystem
{
public:
void update(MyEcs& myEcs, RayComponent& ray);
void destroyDeadCharacter(MyEcs& myEcs);
void destroyDeadCharacter(MyEcs& myEcs, CommonSceneResources& ressources, int& score, int& nbAI);
using Requirements = ecs::Requirements<ecs::Auto>;
using UpdatePolicy = ecs::OncePerEntity;
......
diff --git a/scenes/3D_graphics/01_modeling/others/entity_builder.cpp b/scenes/3D_graphics/01_modeling/others/entity_builder.cpp
index d4338e3..179ecfb 100644
--- a/scenes/3D_graphics/01_modeling/others/entity_builder.cpp
+++ b/scenes/3D_graphics/01_modeling/others/entity_builder.cpp
@@ -95,7 +95,7 @@ ecs::Entity EntityBuilder::buildPlayer(vcl::vec3 const& position, std::map<std::

ecs::Entity EntityBuilder::buildAICharacter(ecs::Entity const target, vcl::vec3 const& position, std::map<std::string,GLuint>& shaders)
{
- auto& hierarchyPair = m_resources.AIHierarchyPool.getFreeElement();
+ auto hierarchyPair = m_resources.AIHierarchyPool.getFreeElement();
auto& hierarchy = hierarchyPair.first;
ecs::Entity ai = buildCharacter(m_resources.standardCharacter, hierarchy, position, shaders);
m_ecs.add<CharacterDesignComponent>(ai, 3.0f, 1.0f);
diff --git a/scenes/3D_graphics/01_modeling/systems/health_system.hpp b/scenes/3D_graphics/01_modeling/systems/health_system.hpp
index 4a66978..5733e03 100644
--- a/scenes/3D_graphics/01_modeling/systems/health_system.hpp
+++ b/scenes/3D_graphics/01_modeling/systems/health_system.hpp
@@ -11,7 +11,7 @@ struct HealthSystem
{
public:
void update(MyEcs& myEcs, RayComponent& ray);
- void HealthSystem::destroyDeadCharacter(MyEcs& myEcs, CommonSceneResources& ressources, int& score, int& nbAI);
+ void destroyDeadCharacter(MyEcs& myEcs, CommonSceneResources& ressources, int& score, int& nbAI);

using Requirements = ecs::Requirements<ecs::Auto>;
using UpdatePolicy = ecs::OncePerEntity;
diff --git a/simplecspp b/simplecspp
index 96bb59d..561cce1 160000
--- a/simplecspp
+++ b/simplecspp
@@ -1 +1 @@
-Subproject commit 96bb59de97e5fbb60e55411791bdab27e9e0d7c7
+Subproject commit 561cce1422d48bb177f5d1a909f4b1798c1faa93