mirror of
https://github.com/Nimac0/SDL_Minigame
synced 2026-01-12 07:53:43 +00:00
unmanaged scenes first impl
This commit is contained in:
parent
7c50c8d1fb
commit
0bfe720a4a
@ -24,8 +24,8 @@ public:
|
|||||||
AssetManager(Manager* manager);
|
AssetManager(Manager* manager);
|
||||||
~AssetManager();
|
~AssetManager();
|
||||||
|
|
||||||
void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner);
|
Entity* createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner);
|
||||||
void createPowerup(Vector2D pos, std::function<void (Entity*)> pickupFunc, Textures texture);
|
Entity* createPowerup(Vector2D pos, std::function<void (Entity*)> pickupFunc, Textures texture);
|
||||||
|
|
||||||
Vector2D calculateSpawnPosition();
|
Vector2D calculateSpawnPosition();
|
||||||
PowerupType calculateType();
|
PowerupType calculateType();
|
||||||
|
|||||||
@ -24,6 +24,7 @@ public:
|
|||||||
void init() override;
|
void init() override;
|
||||||
void update(uint_fast16_t diffTime) override;
|
void update(uint_fast16_t diffTime) override;
|
||||||
void removeCollision();
|
void removeCollision();
|
||||||
|
void addCollision();
|
||||||
|
|
||||||
void handleCollision(Vector2D& characterPos, SDL_Rect& characterCollider, SDL_Rect& componentCollider);
|
void handleCollision(Vector2D& characterPos, SDL_Rect& characterCollider, SDL_Rect& componentCollider);
|
||||||
};
|
};
|
||||||
138
include/Entity.h
138
include/Entity.h
@ -5,6 +5,8 @@
|
|||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "VEGO.h"
|
||||||
|
|
||||||
#include "ColliderComponent.h"
|
#include "ColliderComponent.h"
|
||||||
#include "ECS.h"
|
#include "ECS.h"
|
||||||
#include "Constants.h"
|
#include "Constants.h"
|
||||||
@ -35,85 +37,83 @@ class Entity
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Used for rendering order (last is highest) or retrieving entities of group
|
* \brief Used for rendering order (last is highest) or retrieving entities of group
|
||||||
* \todo Label used in singular entity shouldn't use plural
|
* \todo Label used in singular entity shouldn't use plural
|
||||||
* \todo HEARTS are rendered above POWERUPS, missleading order
|
* \todo HEARTS are rendered above POWERUPS, missleading order
|
||||||
* \todo PROJECTILE are rendered above POWERUPS, missleading order
|
* \todo PROJECTILE are rendered above POWERUPS, missleading order
|
||||||
* \todo Generalize HEARTS as UI or similar
|
* \todo Generalize HEARTS as UI or similar
|
||||||
*/
|
*/
|
||||||
enum class GroupLabel
|
enum class GroupLabel
|
||||||
{
|
{
|
||||||
MAPTILES, //!< Entity using TileComponent
|
MAPTILES, //!< Entity using TileComponent
|
||||||
PLAYERS, //!< Primary entity in player controll
|
PLAYERS, //!< Primary entity in player controll
|
||||||
ENEMIES, //!< \deprecated All players now grouped as Entity::PLAYERS
|
ENEMIES, //!< \deprecated All players now grouped as Entity::PLAYERS
|
||||||
COLLIDERS, //!< Fixed collider entity, e.g. a wall
|
COLLIDERS, //!< Fixed collider entity, e.g. a wall
|
||||||
PROJECTILE, //!< \todo Document
|
PROJECTILE, //!< \todo Document
|
||||||
HEARTS, //!< \todo Document
|
HEARTS, //!< \todo Document
|
||||||
POWERUPS //!< \todo Document
|
POWERUPS //!< \todo Document
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \todo Document
|
* \todo Document
|
||||||
*/
|
*/
|
||||||
explicit Entity(Manager& mManager) :
|
explicit Entity(Manager& mManager) :
|
||||||
manager(mManager) { };
|
manager(mManager) { };
|
||||||
|
|
||||||
void update(uint_fast16_t diffTime) const; //!< Call each frame to update all components
|
void update(uint_fast16_t diffTime) const; //!< Call each frame to update all components
|
||||||
|
|
||||||
bool isActive() const { return this->active; } //!< \sa destroy()
|
bool isActive() const { return this->active; } //!< \sa destroy()
|
||||||
//! Mark for destruction for Manager::refresh() and disables collision
|
//! Mark for destruction for Manager::refresh() and disables collision
|
||||||
//! \sa ColliderComponent
|
//! \sa ColliderComponent
|
||||||
void destroy() {
|
void destroy();
|
||||||
this->active = false;
|
//! Reactivate an entity and reenables collision
|
||||||
if (this->hasComponent<ColliderComponent>()) {
|
//! \sa ColliderComponent
|
||||||
this->getComponent<ColliderComponent>().removeCollision();
|
void reactivate();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasGroup(Group mGroup); //!< \sa GroupLabel
|
bool hasGroup(Group mGroup); //!< \sa GroupLabel
|
||||||
void addGroup(Group mGroup); //!< \sa GroupLabel
|
void addGroup(Group mGroup); //!< \sa GroupLabel
|
||||||
void delGroup(Group mGroup); //!< \sa GroupLabel
|
void delGroup(Group mGroup); //!< \sa GroupLabel
|
||||||
//! \returns bitset with true on position GroupLabel if the entity belongs to group
|
//! \returns bitset with true on position GroupLabel if the entity belongs to group
|
||||||
//! \sa GroupLabel
|
//! \sa GroupLabel
|
||||||
std::bitset<MAX_GROUPS> getGroupBitSet();
|
std::bitset<MAX_GROUPS> getGroupBitSet();
|
||||||
|
|
||||||
//! \sa Manager
|
//! \sa Manager
|
||||||
Manager& getManager() { return manager; };
|
Manager& getManager() { return manager; };
|
||||||
|
|
||||||
template <typename T> bool hasComponent() const //! \sa Component
|
template <typename T> bool hasComponent() const //! \sa Component
|
||||||
{
|
{
|
||||||
return componentBitSet[getComponentTypeID<T>()];
|
return componentBitSet[getComponentTypeID<T>()];
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Adds specified type as component and calls Component::init()
|
//! \brief Adds specified type as component and calls Component::init()
|
||||||
//! \param mArgs Constructor arguments of component
|
//! \param mArgs Constructor arguments of component
|
||||||
template <typename T, typename...TArgs> T& addComponent(TArgs&&...mArgs)
|
template <typename T, typename...TArgs> T& addComponent(TArgs&&...mArgs)
|
||||||
{
|
{
|
||||||
T* c(new T(std::forward<TArgs>(mArgs)...));
|
T* c(new T(std::forward<TArgs>(mArgs)...));
|
||||||
c->entity = this;
|
c->entity = this;
|
||||||
std::unique_ptr<Component> uPtr{ c };
|
std::unique_ptr<Component> uPtr{ c };
|
||||||
this->components.emplace_back(std::move(uPtr));
|
this->components.emplace_back(std::move(uPtr));
|
||||||
|
|
||||||
componentArray[getComponentTypeID<T>()] = c;
|
componentArray[getComponentTypeID<T>()] = c;
|
||||||
componentBitSet[getComponentTypeID<T>()] = true;
|
componentBitSet[getComponentTypeID<T>()] = true;
|
||||||
|
|
||||||
c->init();
|
c->init();
|
||||||
return *c;
|
return *c;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> T& getComponent() const //! \returns Component of type T
|
template <typename T> T& getComponent() const //! \returns Component of type T
|
||||||
{
|
{
|
||||||
auto ptr(componentArray[getComponentTypeID<T>()]);
|
auto ptr(componentArray[getComponentTypeID<T>()]);
|
||||||
return *static_cast<T*>(ptr);
|
return *static_cast<T*>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Manager& manager;
|
Manager& manager;
|
||||||
bool active = true;
|
bool active = true;
|
||||||
std::vector<std::unique_ptr<Component>> components;
|
std::vector<std::unique_ptr<Component>> components;
|
||||||
|
|
||||||
ComponentArray componentArray = {};
|
ComponentArray componentArray = {};
|
||||||
ComponentBitSet componentBitSet;
|
ComponentBitSet componentBitSet;
|
||||||
GroupBitSet groupBitSet;
|
GroupBitSet groupBitSet;
|
||||||
};
|
};
|
||||||
@ -7,9 +7,10 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Constants.h"
|
#include "Constants.h"
|
||||||
#include "Entity.h"
|
|
||||||
|
|
||||||
class GameInternal;
|
class GameInternal;
|
||||||
|
class Entity;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* \brief Is responsible for managing all entities
|
* \brief Is responsible for managing all entities
|
||||||
@ -22,24 +23,30 @@ class GameInternal;
|
|||||||
class Manager
|
class Manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Manager(GameInternal* game) : game(game) {};
|
Manager(GameInternal* game) : game(game) {};
|
||||||
|
|
||||||
void update(uint_fast16_t diffTime); //!< \sa Entity::update()
|
|
||||||
//! Disables all functionality of entities marked for destruction
|
|
||||||
//! \sa Entity::destroy()
|
|
||||||
void refresh();
|
|
||||||
|
|
||||||
void addToGroup(Entity* mEntity, Group mGroup); //!< \todo `friend` to Entity
|
void update(uint_fast16_t diffTime); //!< \sa Entity::update()
|
||||||
std::vector<Entity*>& getGroup(Group mGroup); //!< \returns std::vector containing all entities in group Entity::GroupLabel
|
//! Disables all functionality of entities marked for destruction
|
||||||
|
//! \sa Entity::destroy()
|
||||||
|
void refresh();
|
||||||
|
|
||||||
std::vector<Entity*> getAll(); //!< \returns std::vector containing all entities
|
void addToGroup(Entity* mEntity, Group mGroup); //!< \todo `friend` to Entity
|
||||||
|
std::vector<Entity*>& getGroup(Group mGroup); //!< \returns std::vector containing all entities in group Entity::GroupLabel
|
||||||
|
|
||||||
Entity& addEntity(); //!< Creates and returns a new, empty entity
|
std::vector<Entity*> getAll(); //!< \returns std::vector containing all entities
|
||||||
|
|
||||||
GameInternal* getGame() { return this->game; };
|
Entity& addEntity(); //!< Creates and returns a new, empty entity
|
||||||
|
|
||||||
|
GameInternal* getGame() { return this->game; };
|
||||||
|
|
||||||
|
std::shared_ptr<Entity> getShared(Entity* entity);
|
||||||
|
std::weak_ptr<Entity> getWeak(Entity* entity);
|
||||||
|
|
||||||
|
// this function is ugly af and should not be merged
|
||||||
|
void addExistingEntity(std::shared_ptr<Entity> entity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GameInternal* game;
|
GameInternal* game;
|
||||||
std::vector<std::unique_ptr<Entity>> entities;
|
std::vector<std::shared_ptr<Entity>> entities;
|
||||||
std::array<std::vector<Entity*>, MAX_GROUPS> entitiesByGroup;
|
std::array<std::vector<Entity*>, MAX_GROUPS> entitiesByGroup;
|
||||||
};
|
};
|
||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Entity.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -22,6 +23,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
Map(const char* path);
|
Map(const char* path);
|
||||||
void generateTiles(); //!< Generates the map based on the loaded definition
|
void generateTiles(); //!< Generates the map based on the loaded definition
|
||||||
|
void removeTiles(); //!< Removes all tiles previously generated
|
||||||
private:
|
private:
|
||||||
// struct required for initialisation
|
// struct required for initialisation
|
||||||
struct MapData {
|
struct MapData {
|
||||||
@ -42,10 +44,13 @@ private:
|
|||||||
|
|
||||||
tmx::Map map;
|
tmx::Map map;
|
||||||
Map::MapData mapData;
|
Map::MapData mapData;
|
||||||
std::vector<std::function<void()>> tileConstructors;
|
std::vector<std::function<Entity*()>> tileConstructors;
|
||||||
|
|
||||||
|
std::vector<Entity*> tiles;
|
||||||
|
|
||||||
void loadTileLayer(const tmx::TileLayer& layer);
|
void loadTileLayer(const tmx::TileLayer& layer);
|
||||||
static void addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool hasCollision);
|
// created tile is returned so it can be removed later
|
||||||
|
static Entity* addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool hasCollision);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static std::optional<T> getLayerProperty(const std::vector<tmx::Property>& properties, std::string propertyName) { return std::nullopt; };
|
static std::optional<T> getLayerProperty(const std::vector<tmx::Property>& properties, std::string propertyName) { return std::nullopt; };
|
||||||
|
|||||||
63
include/Scene.h
Normal file
63
include/Scene.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "Map.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Scene {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Adds an Entity limited to the scene
|
||||||
|
* @details Adds an Entity, that is limited to the scene only. The entity will be destroyed with the seen, and should not be accessed afterward. For Entities that need to be reset to a specific position when loading a scene, use addInitFunc. Entities will respawn with the same parameters each time the scene is initialized.
|
||||||
|
* @param[in] entityDefinition Function to define the entity. The function will only be called when the scene will be initialized
|
||||||
|
*/
|
||||||
|
void addEntity(std::function<Entity*()> entityDefinition);
|
||||||
|
/**
|
||||||
|
* @brief Adds an Entity limited to this cycle of the scene
|
||||||
|
* @details Adds an Entity, that is limited to the scene only. The entity will be destroyed with the seen, and should not be accessed afterward. For Entities that need to be reset to a specific position when loading a scene, use addInitFunc. Entities will only spawn once.
|
||||||
|
* @param[in] entityDefinition Function to define the entity. The function will only be called when the scene will be initialized
|
||||||
|
*/
|
||||||
|
void addTemporaryEntity(std::function<Entity*()> entityDefinition);
|
||||||
|
/**
|
||||||
|
* @brief Adds a function to be executed on init of the scene.
|
||||||
|
*
|
||||||
|
* @param[in] initFunc The initialize function
|
||||||
|
*/
|
||||||
|
void addInitFunc(std::function<void()> initFunc);
|
||||||
|
/**
|
||||||
|
* @brief Adds a function to be executed on update of the scene.
|
||||||
|
*
|
||||||
|
* @param[in] updateFunc The update function
|
||||||
|
*/
|
||||||
|
void addUpdateFunc(std::function<void(uint_fast16_t diffTime)> updateFunc);
|
||||||
|
/**
|
||||||
|
* @brief Adds a function to be executed on reset of the scene.
|
||||||
|
*
|
||||||
|
* @param[in] resetFunc The reset function
|
||||||
|
*/
|
||||||
|
void addResetFunc(std::function<void()> resetFunc);
|
||||||
|
|
||||||
|
void addMap(Map* map);
|
||||||
|
void addMap(const char* path);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void update(uint_fast16_t diffTime);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
bool isActive() { return this->active; };
|
||||||
|
private:
|
||||||
|
std::vector<std::shared_ptr<Entity>> entities;
|
||||||
|
std::vector<std::weak_ptr<Entity>> tempEntities;
|
||||||
|
std::vector<std::function<Entity*()>> entityFuncs;
|
||||||
|
std::vector<std::function<Entity*()>> tempEntityFuncs;
|
||||||
|
std::vector<std::function<void()>> initFuncs;
|
||||||
|
std::vector<std::function<void(uint_fast16_t diffTime)>> updateFuncs;
|
||||||
|
std::vector<std::function<void()>> resetFuncs;
|
||||||
|
|
||||||
|
std::unique_ptr<Map> map_unique; // only used if map is constructed by scene
|
||||||
|
Map* map = nullptr;
|
||||||
|
|
||||||
|
bool active = false;
|
||||||
|
};
|
||||||
@ -1,9 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include "GameInternal.h"
|
#include "GameInternal.h"
|
||||||
|
|
||||||
namespace vego {
|
namespace vego {
|
||||||
extern GameInternal* game;
|
extern GameInternal* game;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline GameInternal& VEGO_Game() {
|
inline GameInternal& VEGO_Game() {
|
||||||
return *vego::game;
|
return *vego::game;
|
||||||
};
|
};
|
||||||
@ -41,7 +41,7 @@ Mix_Music* AssetManager::getMusic(std::string id)
|
|||||||
return music.at(id);
|
return music.at(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner) {
|
Entity* AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, float speed, Textures textureEnum, Entity* owner) {
|
||||||
|
|
||||||
auto& projectile(man->addEntity());
|
auto& projectile(man->addEntity());
|
||||||
projectile.addComponent<TransformComponent>(pos.x, pos.y, 32, 32, scale); //32x32 is standard size for objects
|
projectile.addComponent<TransformComponent>(pos.x, pos.y, 32, 32, scale); //32x32 is standard size for objects
|
||||||
@ -49,9 +49,11 @@ void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale,
|
|||||||
projectile.addComponent<ProjectileComponent>(range, speed, velocity, owner);
|
projectile.addComponent<ProjectileComponent>(range, speed, velocity, owner);
|
||||||
projectile.addComponent<ColliderComponent>("projectile", 0.6f);
|
projectile.addComponent<ColliderComponent>("projectile", 0.6f);
|
||||||
projectile.addGroup((size_t)Entity::GroupLabel::PROJECTILE);
|
projectile.addGroup((size_t)Entity::GroupLabel::PROJECTILE);
|
||||||
|
|
||||||
|
return &projectile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::createPowerup(Vector2D pos, std::function<void (Entity*)> pickupFunc, Textures texture) {
|
Entity* AssetManager::createPowerup(Vector2D pos, std::function<void (Entity*)> pickupFunc, Textures texture) {
|
||||||
|
|
||||||
auto& powerups(man->addEntity());
|
auto& powerups(man->addEntity());
|
||||||
powerups.addComponent<TransformComponent>(pos.x, pos.y, 32, 32, 1); //32x32 is standard size for objects
|
powerups.addComponent<TransformComponent>(pos.x, pos.y, 32, 32, 1); //32x32 is standard size for objects
|
||||||
@ -66,6 +68,8 @@ void AssetManager::createPowerup(Vector2D pos, std::function<void (Entity*)> pic
|
|||||||
powerups.addComponent<ColliderComponent>("powerup", 0.6f);
|
powerups.addComponent<ColliderComponent>("powerup", 0.6f);
|
||||||
powerups.addComponent<PowerupComponent>(pickupFunc);
|
powerups.addComponent<PowerupComponent>(pickupFunc);
|
||||||
powerups.addGroup((size_t)Entity::GroupLabel::POWERUPS);
|
powerups.addGroup((size_t)Entity::GroupLabel::POWERUPS);
|
||||||
|
|
||||||
|
return &powerups;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D AssetManager::calculateSpawnPosition()
|
Vector2D AssetManager::calculateSpawnPosition()
|
||||||
|
|||||||
@ -49,6 +49,11 @@ void ColliderComponent::removeCollision()
|
|||||||
this->hasCollision = false;
|
this->hasCollision = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ColliderComponent::addCollision()
|
||||||
|
{
|
||||||
|
this->hasCollision = true;
|
||||||
|
}
|
||||||
|
|
||||||
void ColliderComponent::handleCollision(Vector2D& entityPos, SDL_Rect& entityCollider, SDL_Rect& componentCollider)
|
void ColliderComponent::handleCollision(Vector2D& entityPos, SDL_Rect& entityCollider, SDL_Rect& componentCollider)
|
||||||
{
|
{
|
||||||
// collision to right of character
|
// collision to right of character
|
||||||
|
|||||||
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#include "Manager.h"
|
#include "Manager.h"
|
||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
|
|
||||||
|
#include "VEGO.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
void Entity::update(uint_fast16_t diffTime) const
|
void Entity::update(uint_fast16_t diffTime) const
|
||||||
@ -29,3 +32,23 @@ std::bitset<MAX_GROUPS> Entity::getGroupBitSet()
|
|||||||
{
|
{
|
||||||
return groupBitSet;
|
return groupBitSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Entity::destroy() {
|
||||||
|
this->active = false;
|
||||||
|
if (this->hasComponent<ColliderComponent>()) {
|
||||||
|
this->getComponent<ColliderComponent>().removeCollision();
|
||||||
|
}
|
||||||
|
if (this->hasComponent<SpriteComponent>()) {
|
||||||
|
VEGO_Game().renderManager.remove(&this->getComponent<SpriteComponent>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::reactivate() {
|
||||||
|
this->active = true;
|
||||||
|
if (this->hasComponent<ColliderComponent>()) {
|
||||||
|
this->getComponent<ColliderComponent>().addCollision();
|
||||||
|
}
|
||||||
|
if (this->hasComponent<SpriteComponent>()) {
|
||||||
|
VEGO_Game().renderManager.add(&this->getComponent<SpriteComponent>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
#include "Manager.h"
|
#include "Manager.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
#include <numeric>
|
||||||
|
#include <ranges>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Constants.h"
|
#include "Constants.h"
|
||||||
@ -8,53 +12,78 @@
|
|||||||
|
|
||||||
void Manager::refresh()
|
void Manager::refresh()
|
||||||
{
|
{
|
||||||
for (auto i(0u); i < MAX_GROUPS; i++)
|
for (auto i(0u); i < MAX_GROUPS; i++)
|
||||||
{
|
{
|
||||||
auto& v(entitiesByGroup[i]);
|
auto& v(entitiesByGroup[i]);
|
||||||
v.erase(
|
v.erase(
|
||||||
std::remove_if(std::begin(v), std::end(v),
|
std::remove_if(std::begin(v), std::end(v),
|
||||||
[i](Entity* mEntity)
|
[i](Entity* mEntity)
|
||||||
{
|
{
|
||||||
return !mEntity->isActive() || !mEntity->hasGroup(i);
|
return !mEntity->isActive() || !mEntity->hasGroup(i);
|
||||||
}), std::end(v));
|
}), std::end(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
entities.erase(std::remove_if(std::begin(entities), std::end(entities),
|
entities.erase(std::remove_if(std::begin(entities), std::end(entities),
|
||||||
[](const std::unique_ptr<Entity>& mEntity)
|
[](const std::shared_ptr<Entity>& mEntity)
|
||||||
{
|
{
|
||||||
return !mEntity->isActive();
|
return !mEntity->isActive();
|
||||||
}),
|
}),
|
||||||
std::end(entities));
|
std::end(entities));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::update(uint_fast16_t diffTime)
|
void Manager::update(uint_fast16_t diffTime)
|
||||||
{
|
{
|
||||||
for (auto& e : entities) e->update(diffTime);
|
for (auto& e : entities) e->update(diffTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::addToGroup(Entity* mEntity, Group mGroup)
|
void Manager::addToGroup(Entity* mEntity, Group mGroup)
|
||||||
{
|
{
|
||||||
entitiesByGroup.at(mGroup).emplace_back(mEntity);
|
entitiesByGroup.at(mGroup).emplace_back(mEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Entity*>& Manager::getGroup(Group mGroup)
|
std::vector<Entity*>& Manager::getGroup(Group mGroup)
|
||||||
{
|
{
|
||||||
return entitiesByGroup.at(mGroup);
|
return entitiesByGroup.at(mGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Entity*> Manager::getAll()
|
std::vector<Entity*> Manager::getAll()
|
||||||
{
|
{
|
||||||
std::vector<Entity*> entity_vec;
|
std::vector<Entity*> entity_vec;
|
||||||
for (auto& entity_ptr : entities) {
|
for (auto& entity_ptr : entities) {
|
||||||
entity_vec.emplace_back(entity_ptr.get());
|
entity_vec.emplace_back(entity_ptr.get());
|
||||||
}
|
}
|
||||||
return entity_vec;
|
return entity_vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity& Manager::addEntity()
|
Entity& Manager::addEntity()
|
||||||
{
|
{
|
||||||
Entity* e = new Entity(*this);
|
Entity* e = new Entity(*this);
|
||||||
std::unique_ptr<Entity> uPtr{ e };
|
entities.emplace_back(e);
|
||||||
entities.emplace_back(std::move(uPtr));
|
return *e;
|
||||||
return *e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::addExistingEntity(std::shared_ptr<Entity> entity)
|
||||||
|
{
|
||||||
|
entities.emplace_back(entity);
|
||||||
|
std::ranges::for_each(std::views::iota(0ul, MAX_GROUPS), [&entity, this](auto i) {
|
||||||
|
if (entity->hasGroup(i)) {
|
||||||
|
this->entitiesByGroup.at(i).emplace_back(entity.get());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Entity> Manager::getShared(Entity* entity)
|
||||||
|
{
|
||||||
|
auto entityPtr = std::find_if(std::begin(entities), std::end(entities), [&entity](const auto& entityPtr) {
|
||||||
|
return entity == entityPtr.get();
|
||||||
|
});
|
||||||
|
return std::shared_ptr<Entity>(*entityPtr); // careful, error if find_if returns end
|
||||||
|
}
|
||||||
|
|
||||||
|
std::weak_ptr<Entity> Manager::getWeak(Entity* entity)
|
||||||
|
{
|
||||||
|
auto entityPtr = std::find_if(std::begin(entities), std::end(entities), [&entity](const auto& entityPtr) {
|
||||||
|
return entity == entityPtr.get();
|
||||||
|
});
|
||||||
|
return *entityPtr; // careful, error if find_if returns end
|
||||||
|
}
|
||||||
20
src/Map.cpp
20
src/Map.cpp
@ -20,6 +20,7 @@
|
|||||||
#include <tmxlite/Types.hpp>
|
#include <tmxlite/Types.hpp>
|
||||||
|
|
||||||
#include "ColliderComponent.h"
|
#include "ColliderComponent.h"
|
||||||
|
#include "Entity.h"
|
||||||
#include "GameInternal.h"
|
#include "GameInternal.h"
|
||||||
#include "SpriteComponent.h"
|
#include "SpriteComponent.h"
|
||||||
#include "TextureManager.h"
|
#include "TextureManager.h"
|
||||||
@ -148,9 +149,9 @@ void Map::loadTileLayer(const tmx::TileLayer& layer)
|
|||||||
const float tilePosY = (static_cast<float>(y) * this->mapData.mapTileSize->y);
|
const float tilePosY = (static_cast<float>(y) * this->mapData.mapTileSize->y);
|
||||||
|
|
||||||
// return tile data as a function to spawn said tile
|
// return tile data as a function to spawn said tile
|
||||||
return std::function<void()>(
|
return std::function<Entity*()>(
|
||||||
[tilePosX, tilePosY, capture0 = *this->mapData.mapTileSize, u, v, zIndex, capture1 = data.texturePath, collision] {
|
[tilePosX, tilePosY, capture0 = *this->mapData.mapTileSize, u, v, zIndex, capture1 = data.texturePath, collision] {
|
||||||
Map::addTile(tilePosX, tilePosY, capture0, u, v, zIndex, capture1, collision);
|
return Map::addTile(tilePosX, tilePosY, capture0, u, v, zIndex, capture1, collision);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -162,7 +163,7 @@ void Map::loadTileLayer(const tmx::TileLayer& layer)
|
|||||||
this->tileConstructors.insert(this->tileConstructors.end(), tileConstructorRange.begin(), tileConstructorRange.end());
|
this->tileConstructors.insert(this->tileConstructors.end(), tileConstructorRange.begin(), tileConstructorRange.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool hasCollision)
|
Entity* Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool hasCollision)
|
||||||
{
|
{
|
||||||
auto& tile(VEGO_Game().manager.addEntity());
|
auto& tile(VEGO_Game().manager.addEntity());
|
||||||
|
|
||||||
@ -175,11 +176,20 @@ void Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int
|
|||||||
tile.addComponent<ColliderComponent>("hello I am a collider of a tile!");
|
tile.addComponent<ColliderComponent>("hello I am a collider of a tile!");
|
||||||
tile.addGroup((size_t)Entity::GroupLabel::MAPTILES);
|
tile.addGroup((size_t)Entity::GroupLabel::MAPTILES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return &tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::generateTiles()
|
void Map::generateTiles()
|
||||||
{
|
{
|
||||||
std::ranges::for_each(this->tileConstructors, [](auto& function) {
|
this->tiles = std::views::transform(this->tileConstructors, [](auto& function) {
|
||||||
function();
|
return function();
|
||||||
|
}) | std::ranges::to<std::vector<Entity*>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::removeTiles()
|
||||||
|
{
|
||||||
|
std::ranges::for_each(this->tiles, [](const auto& tile) {
|
||||||
|
tile->destroy();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
102
src/Scene.cpp
Normal file
102
src/Scene.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include "Scene.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "Map.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
#include <ranges>
|
||||||
|
#include <vector>
|
||||||
|
#include <VEGO.h>
|
||||||
|
|
||||||
|
void Scene::addEntity(std::function<Entity*()> entityDefinition)
|
||||||
|
{
|
||||||
|
this->entityFuncs.push_back(entityDefinition);
|
||||||
|
|
||||||
|
if (this->active) {
|
||||||
|
this->entities.emplace_back(VEGO_Game().manager.getWeak(entityDefinition()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::addTemporaryEntity(std::function<Entity*()> entityDefinition)
|
||||||
|
{
|
||||||
|
if (this->active) {
|
||||||
|
this->tempEntities.push_back(VEGO_Game().manager.getWeak(entityDefinition()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->tempEntityFuncs.push_back(entityDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::addInitFunc(std::function<void()> initFunc)
|
||||||
|
{
|
||||||
|
this->initFuncs.push_back(initFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::addUpdateFunc(std::function<void(uint_fast16_t diffTime)> updateFunc)
|
||||||
|
{
|
||||||
|
this->updateFuncs.push_back(updateFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::addResetFunc(std::function<void()> resetFunc)
|
||||||
|
{
|
||||||
|
this->resetFuncs.push_back(resetFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::init()
|
||||||
|
{
|
||||||
|
this->map->generateTiles();
|
||||||
|
|
||||||
|
std::ranges::for_each(this->initFuncs, [](const auto& func) {
|
||||||
|
func();
|
||||||
|
});
|
||||||
|
std::ranges::for_each(this->entities, [](auto entity) {
|
||||||
|
entity->reactivate();
|
||||||
|
VEGO_Game().manager.addExistingEntity(entity);
|
||||||
|
});
|
||||||
|
std::ranges::for_each(this->entityFuncs, [this](const auto& func) {
|
||||||
|
this->entities.emplace_back(VEGO_Game().manager.getShared(func()));
|
||||||
|
});
|
||||||
|
std::ranges::for_each(this->tempEntityFuncs, [this](const auto& func) {
|
||||||
|
this->tempEntities.emplace_back(VEGO_Game().manager.getWeak(func()));
|
||||||
|
});
|
||||||
|
|
||||||
|
this->active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::update(uint_fast16_t diffTime)
|
||||||
|
{
|
||||||
|
std::ranges::for_each(this->updateFuncs, [diffTime](const auto& func) {
|
||||||
|
func(diffTime);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::reset()
|
||||||
|
{
|
||||||
|
this->active = false;
|
||||||
|
|
||||||
|
std::ranges::for_each(this->entities, [](const auto& entity) {
|
||||||
|
entity->destroy();
|
||||||
|
});
|
||||||
|
std::ranges::for_each(this->tempEntities, [](const auto& entity) {
|
||||||
|
if (!entity.expired())
|
||||||
|
entity.lock()->destroy();
|
||||||
|
});
|
||||||
|
this->tempEntities.clear();
|
||||||
|
std::ranges::for_each(this->resetFuncs, [](const auto& func) {
|
||||||
|
func();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this->map) {
|
||||||
|
this->map->removeTiles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::addMap(Map* map)
|
||||||
|
{
|
||||||
|
this->map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::addMap(const char* path)
|
||||||
|
{
|
||||||
|
this->map_unique = std::unique_ptr<Map>(new Map(path));
|
||||||
|
this->addMap(this->map_unique.get());
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user