0
0
mirror of https://github.com/Nimac0/SDL_Minigame synced 2026-01-12 21:23:41 +00:00

refactored labels to be within Entity class

This commit is contained in:
Benedikt Galbavy 2024-02-02 22:17:21 +01:00
parent 3e9d81b2a5
commit d10afe1e07
15 changed files with 68 additions and 65 deletions

View File

@ -23,7 +23,7 @@ public:
AssetManager(Manager* manager); AssetManager(Manager* manager);
~AssetManager(); ~AssetManager();
void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, const char* texturePath, TeamLabel teamLabel); void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, const char* texturePath, Entity::TeamLabel teamLabel);
void createPowerup(Vector2D pos, PowerupType type); void createPowerup(Vector2D pos, PowerupType type);
Vector2D calculateSpawnPosition(); Vector2D calculateSpawnPosition();

View File

@ -43,16 +43,16 @@ public:
// temporary function, remove once game.cpp cleaned up // temporary function, remove once game.cpp cleaned up
std::vector<ColliderComponent*> getColliders( std::vector<ColliderComponent*> getColliders(
std::initializer_list<GroupLabel> const& groupLabels, std::initializer_list<Entity::GroupLabel> const& groupLabels,
std::initializer_list<TeamLabel> const& teamLabels = {}, std::initializer_list<Entity::TeamLabel> const& teamLabels = {},
bool negateTeam = false); bool negateTeam = false);
template<typename T> template<typename T>
T getAnyIntersection( T getAnyIntersection(
Entity* entity, Entity* entity,
Vector2D posMod = {}, Vector2D posMod = {},
std::initializer_list<GroupLabel> const& groupLabels = {}, std::initializer_list<Entity::GroupLabel> const& groupLabels = {},
std::initializer_list<TeamLabel> const& teamLabels = {}, std::initializer_list<Entity::TeamLabel> const& teamLabels = {},
bool negateTeam = false); bool negateTeam = false);
void update(); void update();

View File

@ -16,8 +16,13 @@ using ComponentBitSet = std::bitset<MAX_COMPONENTS>;
using GroupBitSet = std::bitset<MAX_GROUPS>; using GroupBitSet = std::bitset<MAX_GROUPS>;
using ComponentArray = std::array<Component*, MAX_COMPONENTS>; using ComponentArray = std::array<Component*, MAX_COMPONENTS>;
enum class GroupLabel class Entity
{ {
public:
/*! TODO */
enum class GroupLabel
{
MAPTILES, MAPTILES,
PLAYERS, PLAYERS,
ENEMIES, ENEMIES,
@ -25,18 +30,15 @@ enum class GroupLabel
PROJECTILE, PROJECTILE,
HEARTS, HEARTS,
POWERUPS POWERUPS
}; };
enum class TeamLabel enum class TeamLabel
{ {
NONE, NONE, //!< No team
BLUE, BLUE, //!< Team blue
RED RED //!< Team red
}; };
class Entity
{
public:
explicit Entity(Manager& mManager) : explicit Entity(Manager& mManager) :
manager(mManager) { }; manager(mManager) { };

View File

@ -6,12 +6,12 @@
#include <vector> #include <vector>
#include "Vector2D.h" #include "Vector2D.h"
#include "Entity.h"
class AssetManager; class AssetManager;
class CollisionHandler; class CollisionHandler;
class TextureManager; class TextureManager;
class SoundManager; class SoundManager;
enum class TeamLabel;
class Game class Game
{ {
@ -37,13 +37,13 @@ public:
static SoundManager* soundManager; static SoundManager* soundManager;
void refreshPlayers(); void refreshPlayers();
TeamLabel getWinner() const; Entity::TeamLabel getWinner() const;
private: private:
void setWinner(TeamLabel winningTeam); void setWinner(Entity::TeamLabel winningTeam);
int counter = 0; int counter = 0;
bool isRunning = false; bool isRunning = false;
SDL_Window* window; SDL_Window* window;
TeamLabel winner; Entity::TeamLabel winner;
}; };

View File

@ -3,8 +3,9 @@
#include <SDL_ttf.h> #include <SDL_ttf.h>
#include <string> #include <string>
#include "Entity.h"
class Game; class Game;
enum class TeamLabel;
class PopupWindow { class PopupWindow {
@ -17,7 +18,7 @@ public:
bool interacted; bool interacted;
void renderWinnerPopup(TeamLabel winner); void renderWinnerPopup(Entity::TeamLabel winner);
private: private:
SDL_Renderer* renderer; SDL_Renderer* renderer;

View File

@ -37,14 +37,14 @@ Mix_Chunk* AssetManager::getSound(std::string id) {
return soundEffects.at(id); return soundEffects.at(id);
} }
void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, const char* texturePath, TeamLabel teamLabel) { void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, const char* texturePath, Entity::TeamLabel teamLabel) {
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
projectile.addComponent<SpriteComponent>(texturePath); projectile.addComponent<SpriteComponent>(texturePath);
projectile.addComponent<ProjectileComponent>(range, speed, velocity); projectile.addComponent<ProjectileComponent>(range, speed, velocity);
projectile.addComponent<ColliderComponent>("projectile", 0.6f); projectile.addComponent<ColliderComponent>("projectile", 0.6f);
projectile.addGroup((size_t)GroupLabel::PROJECTILE); projectile.addGroup((size_t)Entity::GroupLabel::PROJECTILE);
projectile.setTeam(teamLabel); projectile.setTeam(teamLabel);
} }
@ -67,7 +67,7 @@ void AssetManager::createPowerup(Vector2D pos, PowerupType type) {
powerups.addComponent<ColliderComponent>("powerup", 0.6f); powerups.addComponent<ColliderComponent>("powerup", 0.6f);
powerups.addComponent<PowerupComponent>(type); powerups.addComponent<PowerupComponent>(type);
powerups.addGroup((size_t)GroupLabel::POWERUPS); powerups.addGroup((size_t)Entity::GroupLabel::POWERUPS);
} }
Vector2D AssetManager::calculateSpawnPosition() Vector2D AssetManager::calculateSpawnPosition()
@ -81,7 +81,7 @@ Vector2D AssetManager::calculateSpawnPosition()
spawnRect.x = rand() % (SCREEN_SIZE_WIDTH - spawnRect.w); spawnRect.x = rand() % (SCREEN_SIZE_WIDTH - spawnRect.w);
spawnRect.y = rand() % (SCREEN_SIZE_HEIGHT - spawnRect.h); spawnRect.y = rand() % (SCREEN_SIZE_HEIGHT - spawnRect.h);
conflict = false; conflict = false;
for (auto cc : Game::collisionHandler->getColliders({ GroupLabel::MAPTILES })) for (auto cc : Game::collisionHandler->getColliders({ Entity::GroupLabel::MAPTILES }))
{ {
if (SDL_HasIntersection(&spawnRect, &cc->collider) && strcmp(cc->tag, "projectile")) if (SDL_HasIntersection(&spawnRect, &cc->collider) && strcmp(cc->tag, "projectile"))
{ {

View File

@ -86,8 +86,8 @@ IntersectionBitSet CollisionHandler::getIntersectionWithBounds(Entity* entity, V
} }
std::vector<ColliderComponent*> CollisionHandler::getColliders( std::vector<ColliderComponent*> CollisionHandler::getColliders(
std::initializer_list<GroupLabel> const& groupLabels, std::initializer_list<Entity::GroupLabel> const& groupLabels,
std::initializer_list<TeamLabel> const& teamLabels, std::initializer_list<Entity::TeamLabel> const& teamLabels,
bool negateTeam) bool negateTeam)
{ {
std::vector<ColliderComponent*> colliders; std::vector<ColliderComponent*> colliders;
@ -119,8 +119,8 @@ template<>
IntersectionBitSet CollisionHandler::getAnyIntersection<IntersectionBitSet>( IntersectionBitSet CollisionHandler::getAnyIntersection<IntersectionBitSet>(
Entity* entity, Entity* entity,
Vector2D posMod, Vector2D posMod,
std::initializer_list<GroupLabel> const& groupLabels, std::initializer_list<Entity::GroupLabel> const& groupLabels,
std::initializer_list<TeamLabel> const& teamLabels, std::initializer_list<Entity::TeamLabel> const& teamLabels,
bool negateTeam) bool negateTeam)
{ {
IntersectionBitSet intersections; IntersectionBitSet intersections;
@ -134,8 +134,8 @@ template<>
Entity* CollisionHandler::getAnyIntersection<Entity*>( Entity* CollisionHandler::getAnyIntersection<Entity*>(
Entity* entity, Entity* entity,
Vector2D posMod, Vector2D posMod,
std::initializer_list<GroupLabel> const& groupLabels, std::initializer_list<Entity::GroupLabel> const& groupLabels,
std::initializer_list<TeamLabel> const& teamLabels, std::initializer_list<Entity::TeamLabel> const& teamLabels,
bool negateTeam) bool negateTeam)
{ {
for (auto& collider : getColliders(groupLabels, teamLabels)) { for (auto& collider : getColliders(groupLabels, teamLabels)) {

View File

@ -35,13 +35,13 @@ std::bitset<MAX_GROUPS> Entity::getGroupBitSet()
return groupBitSet; return groupBitSet;
} }
void Entity::setTeam(TeamLabel teamLabel) void Entity::setTeam(Entity::TeamLabel teamLabel)
{ {
this->teamLabel = teamLabel; this->teamLabel = teamLabel;
manager.addToTeam(this, (size_t) teamLabel); manager.addToTeam(this, (size_t) teamLabel);
} }
TeamLabel Entity::getTeam() Entity::TeamLabel Entity::getTeam()
{ {
return teamLabel; return teamLabel;
} }

View File

@ -159,24 +159,24 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo
//ecs implementation //ecs implementation
player1.setTeam(TeamLabel::BLUE); player1.setTeam(Entity::TeamLabel::BLUE);
player1.addComponent<TransformComponent>(80,80,2); //posx, posy, scale player1.addComponent<TransformComponent>(80,80,2); //posx, posy, scale
player1.addComponent<SpriteComponent>(player1Sprite, true); //adds sprite (32x32px), path needed player1.addComponent<SpriteComponent>(player1Sprite, true); //adds sprite (32x32px), path needed
player1.addComponent<KeyboardController>(SDL_SCANCODE_W, SDL_SCANCODE_S, SDL_SCANCODE_A, SDL_SCANCODE_D, SDL_SCANCODE_E, Vector2D(2, 0));//custom keycontrols can be added player1.addComponent<KeyboardController>(SDL_SCANCODE_W, SDL_SCANCODE_S, SDL_SCANCODE_A, SDL_SCANCODE_D, SDL_SCANCODE_E, Vector2D(2, 0));//custom keycontrols can be added
player1.addComponent<ColliderComponent>("player", 0.8f); //adds tag (for further use, reference tag) player1.addComponent<ColliderComponent>("player", 0.8f); //adds tag (for further use, reference tag)
player1.addComponent<HealthComponent>(5, Direction::LEFT); player1.addComponent<HealthComponent>(5, Direction::LEFT);
player1.addComponent<StatEffectsComponent>(); player1.addComponent<StatEffectsComponent>();
player1.addGroup((size_t) GroupLabel::PLAYERS); //tell programm what group it belongs to for rendering order player1.addGroup((size_t) Entity::GroupLabel::PLAYERS); //tell programm what group it belongs to for rendering order
player2.setTeam(TeamLabel::RED); player2.setTeam(Entity::TeamLabel::RED);
player2.addComponent<TransformComponent>(600, 500, 2); player2.addComponent<TransformComponent>(600, 500, 2);
player2.addComponent<SpriteComponent>(player2Sprite, true); player2.addComponent<SpriteComponent>(player2Sprite, true);
player2.addComponent<KeyboardController>(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_RCTRL, Vector2D(-2, 0)); player2.addComponent<KeyboardController>(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_RCTRL, Vector2D(-2, 0));
player2.addComponent<ColliderComponent>("enemy", 0.8f); player2.addComponent<ColliderComponent>("enemy", 0.8f);
player2.addComponent<HealthComponent>(5, Direction::RIGHT); player2.addComponent<HealthComponent>(5, Direction::RIGHT);
player2.addComponent<StatEffectsComponent>(); player2.addComponent<StatEffectsComponent>();
player2.addGroup((size_t) GroupLabel::PLAYERS); player2.addGroup((size_t) Entity::GroupLabel::PLAYERS);
} }
void Game::selectCharacters(const char* &playerSprite, const char* &enemySprite) void Game::selectCharacters(const char* &playerSprite, const char* &enemySprite)
@ -275,11 +275,11 @@ void Game::selectCharacters(const char* &playerSprite, const char* &enemySprite)
this->isRunning = true; this->isRunning = true;
} }
auto& tiles(manager.getGroup((size_t)GroupLabel::MAPTILES)); auto& tiles(manager.getGroup((size_t)Entity::GroupLabel::MAPTILES));
auto& players(manager.getGroup((size_t)GroupLabel::PLAYERS)); auto& players(manager.getGroup((size_t)Entity::GroupLabel::PLAYERS));
auto& projectiles(manager.getGroup((size_t)GroupLabel::PROJECTILE)); auto& projectiles(manager.getGroup((size_t)Entity::GroupLabel::PROJECTILE));
auto& hearts(manager.getGroup((size_t)GroupLabel::HEARTS)); auto& hearts(manager.getGroup((size_t)Entity::GroupLabel::HEARTS));
auto& powerups(manager.getGroup((size_t)GroupLabel::POWERUPS)); auto& powerups(manager.getGroup((size_t)Entity::GroupLabel::POWERUPS));
void Game::handleEvents() void Game::handleEvents()
{ {
@ -311,7 +311,7 @@ void Game::update()
} }
// needs to be in game.cpp to have access to internal functions // needs to be in game.cpp to have access to internal functions
for (auto& player : manager.getGroup((size_t) GroupLabel::PLAYERS)) { for (auto& player : manager.getGroup((size_t) Entity::GroupLabel::PLAYERS)) {
if (player->getComponent<HealthComponent>().getHealth() <= 0) { if (player->getComponent<HealthComponent>().getHealth() <= 0) {
this->setWinner(player->getTeam()); this->setWinner(player->getTeam());
} }
@ -353,7 +353,7 @@ void Game::addTile(unsigned long id, int x, int y)
auto& tile(manager.addEntity()); auto& tile(manager.addEntity());
tile.addComponent<TileComponent>(x, y, TILE_SIZE, TILE_SIZE, id); tile.addComponent<TileComponent>(x, y, TILE_SIZE, TILE_SIZE, id);
if (id == 1) tile.addComponent<ColliderComponent>("water"); if (id == 1) tile.addComponent<ColliderComponent>("water");
tile.addGroup((size_t)GroupLabel::MAPTILES); tile.addGroup((size_t)Entity::GroupLabel::MAPTILES);
} }
bool Game::running() const bool Game::running() const
@ -361,13 +361,13 @@ bool Game::running() const
return isRunning; return isRunning;
} }
void Game::setWinner(TeamLabel winningTeam) void Game::setWinner(Entity::TeamLabel winningTeam)
{ {
this->winner = winningTeam; this->winner = winningTeam;
this->isRunning = false; this->isRunning = false;
} }
TeamLabel Game::getWinner() const Entity::TeamLabel Game::getWinner() const
{ {
return this->winner; return this->winner;
} }

View File

@ -26,7 +26,7 @@ void HealthComponent::setHealth(int health)
void HealthComponent::refreshHearts() void HealthComponent::refreshHearts()
{ {
// clear hearts if exist // clear hearts if exist
for (auto& heart : this->entity->getManager().getGroup((size_t) GroupLabel::HEARTS)) { for (auto& heart : this->entity->getManager().getGroup((size_t) Entity::GroupLabel::HEARTS)) {
if (heart->getTeam() == this->entity->getTeam()) { if (heart->getTeam() == this->entity->getTeam()) {
heart->destroy(); heart->destroy();
} }
@ -59,6 +59,6 @@ void HealthComponent::createHeartComponents(int x)
auto& heart(this->entity->getManager().addEntity()); auto& heart(this->entity->getManager().addEntity());
heart.addComponent<TransformComponent>(x,5,2); heart.addComponent<TransformComponent>(x,5,2);
heart.addComponent<SpriteComponent>("assets/heart.png"); heart.addComponent<SpriteComponent>("assets/heart.png");
heart.addGroup((size_t)GroupLabel::HEARTS); heart.addGroup((size_t)Entity::GroupLabel::HEARTS);
heart.setTeam(this->entity->getTeam()); heart.setTeam(this->entity->getTeam());
} }

View File

@ -62,12 +62,12 @@ bool PopupWindow::shouldContinue() const {
return continueGame; return continueGame;
} }
void PopupWindow::renderWinnerPopup(TeamLabel winner) { void PopupWindow::renderWinnerPopup(Entity::TeamLabel winner) {
SDL_RenderClear(this->renderer); SDL_RenderClear(this->renderer);
//Maybe use texture manager (changes need to be made that it does not use game::renderer automatically, but receives one instead) //Maybe use texture manager (changes need to be made that it does not use game::renderer automatically, but receives one instead)
this->texture = winner == TeamLabel::BLUE ? this->texture = winner == Entity::TeamLabel::BLUE ?
IMG_LoadTexture(this->renderer, "assets/Player1Victory.png") : IMG_LoadTexture(this->renderer, "assets/Player1Victory.png") :
IMG_LoadTexture(this->renderer, "assets/Player2Victory.png"); IMG_LoadTexture(this->renderer, "assets/Player2Victory.png");

View File

@ -31,7 +31,7 @@ void PowerupComponent::update()
if ((player = Game::collisionHandler->getAnyIntersection<Entity*>( if ((player = Game::collisionHandler->getAnyIntersection<Entity*>(
entity, entity,
Vector2D(0, 0), Vector2D(0, 0),
{ GroupLabel::PLAYERS }, { Entity::GroupLabel::PLAYERS },
{}, {},
true)) != nullptr) true)) != nullptr)
{ {

View File

@ -34,7 +34,7 @@ void ProjectileComponent::update()
if ((player = Game::collisionHandler->getAnyIntersection<Entity*>( if ((player = Game::collisionHandler->getAnyIntersection<Entity*>(
entity, entity,
Vector2D(0,0), Vector2D(0,0),
{GroupLabel::PLAYERS}, {Entity::GroupLabel::PLAYERS},
{entity->getTeam()}, {entity->getTeam()},
true)) != nullptr) { true)) != nullptr) {
player->getComponent<HealthComponent>().modifyHealth(); player->getComponent<HealthComponent>().modifyHealth();

View File

@ -62,13 +62,13 @@ void TransformComponent::update()
// TODO: move to separate functions // TODO: move to separate functions
if (this->entity->hasGroup((size_t)GroupLabel::PLAYERS)) { if (this->entity->hasGroup((size_t)Entity::GroupLabel::PLAYERS)) {
IntersectionBitSet intersections = IntersectionBitSet intersections =
(CollisionHandler::getIntersectionWithBounds(entity, Vector2D(positionChange.x, 0)) | (CollisionHandler::getIntersectionWithBounds(entity, Vector2D(positionChange.x, 0)) |
(Game::collisionHandler->getAnyIntersection<IntersectionBitSet>(entity, Vector2D(positionChange.x, 0), { GroupLabel::MAPTILES, GroupLabel::COLLIDERS })) & (Game::collisionHandler->getAnyIntersection<IntersectionBitSet>(entity, Vector2D(positionChange.x, 0), { Entity::GroupLabel::MAPTILES, Entity::GroupLabel::COLLIDERS })) &
IntersectionBitSet("0011")) | IntersectionBitSet("0011")) |
(CollisionHandler::getIntersectionWithBounds(entity, Vector2D(0, positionChange.y)) | (CollisionHandler::getIntersectionWithBounds(entity, Vector2D(0, positionChange.y)) |
(Game::collisionHandler->getAnyIntersection<IntersectionBitSet>(entity, Vector2D(0, positionChange.y), { GroupLabel::MAPTILES, GroupLabel::COLLIDERS })) & (Game::collisionHandler->getAnyIntersection<IntersectionBitSet>(entity, Vector2D(0, positionChange.y), { Entity::GroupLabel::MAPTILES, Entity::GroupLabel::COLLIDERS })) &
IntersectionBitSet("1100")); IntersectionBitSet("1100"));
if (intersections.test((size_t)Direction::LEFT) || intersections.test((size_t)Direction::RIGHT)) if (intersections.test((size_t)Direction::LEFT) || intersections.test((size_t)Direction::RIGHT))

View File

@ -35,9 +35,9 @@ int main(int argc, char* argv[])
SDL_Delay(frameDelay - frameTime); SDL_Delay(frameDelay - frameTime);
} }
} }
TeamLabel winner = game->getWinner(); Entity::TeamLabel winner = game->getWinner();
PopupWindow popupWindow("Game over", winner == TeamLabel::BLUE ? PopupWindow popupWindow("Game over", winner == Entity::TeamLabel::BLUE ?
"Player1 won! Press 'C' to continue or 'Q' to quit." : "Player1 won! Press 'C' to continue or 'Q' to quit." :
"Player2 won! Press 'C' to continue or 'Q' to quit."); "Player2 won! Press 'C' to continue or 'Q' to quit.");