mirror of
https://github.com/Nimac0/SDL_Minigame
synced 2026-01-12 21:23:41 +00:00
Rewrite player collisions
This commit is contained in:
parent
fa480f916f
commit
8ff81ace72
44
include/CollisionHandler.h
Normal file
44
include/CollisionHandler.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "SpriteComponent.h"
|
||||||
|
#include "Vector2D.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class ColliderComponent;
|
||||||
|
class Manager;
|
||||||
|
class Entity;
|
||||||
|
|
||||||
|
constexpr uint8_t DIRECTION_C = 4;
|
||||||
|
|
||||||
|
enum class direction
|
||||||
|
{
|
||||||
|
LEFT = 0,
|
||||||
|
RIGHT,
|
||||||
|
UP,
|
||||||
|
DOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
using IntersectionBitSet = std::bitset<DIRECTION_C>;
|
||||||
|
|
||||||
|
class CollisionHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Manager& manager;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CollisionHandler(Manager& mManager) :
|
||||||
|
manager(mManager) { };
|
||||||
|
~CollisionHandler();
|
||||||
|
|
||||||
|
|
||||||
|
static IntersectionBitSet getIntersection(Entity* entityA, Entity* entityB); // intersections relative to entityA
|
||||||
|
static IntersectionBitSet getIntersection(Entity* entityA, Entity* entityB, Vector2D posModA, Vector2D posModB);
|
||||||
|
static IntersectionBitSet getIntersectionWithBounds(Entity* entity);// will fail if speed high enough to switch from no collision to full overlap in one tick
|
||||||
|
static IntersectionBitSet getIntersectionWithBounds(Entity* entity, Vector2D posMod);
|
||||||
|
|
||||||
|
std::vector<ColliderComponent*> getColliders(GroupLabel groupLabel); // temporary function, remove once game.cpp cleaned up
|
||||||
|
|
||||||
|
void update();
|
||||||
|
};
|
||||||
@ -2,16 +2,6 @@
|
|||||||
|
|
||||||
class Entity;
|
class Entity;
|
||||||
|
|
||||||
enum class GroupLabel
|
|
||||||
{
|
|
||||||
MAP,
|
|
||||||
PLAYERS,
|
|
||||||
ENEMIES,
|
|
||||||
COLLIDERS,
|
|
||||||
PROJECTILE,
|
|
||||||
HEARTS
|
|
||||||
};
|
|
||||||
|
|
||||||
class Component
|
class Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -3,9 +3,11 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
using Group = std::size_t;
|
using Group = std::size_t;
|
||||||
|
using Team = std::size_t;
|
||||||
|
|
||||||
constexpr std::size_t MAX_COMPONENTS = 32;
|
constexpr std::size_t MAX_COMPONENTS = 32;
|
||||||
constexpr std::size_t MAX_GROUPS = 32;
|
constexpr std::size_t MAX_GROUPS = 32;
|
||||||
|
constexpr std::size_t MAX_TEAMS = 8; //
|
||||||
|
|
||||||
constexpr int SCREEN_SIZE_HEIGHT = 640;
|
constexpr int SCREEN_SIZE_HEIGHT = 640;
|
||||||
constexpr int SCREEN_SIZE_WIDTH = 800;
|
constexpr int SCREEN_SIZE_WIDTH = 800;
|
||||||
|
|||||||
@ -15,10 +15,28 @@ 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
|
||||||
|
{
|
||||||
|
MAPTILES,
|
||||||
|
PLAYERS,
|
||||||
|
ENEMIES,
|
||||||
|
COLLIDERS,
|
||||||
|
PROJECTILE,
|
||||||
|
HEARTS
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class TeamLabel
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
BLUE,
|
||||||
|
RED
|
||||||
|
};
|
||||||
|
|
||||||
class Entity
|
class Entity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Entity(Manager& mManager) : manager(mManager) { }
|
explicit Entity(Manager& mManager) :
|
||||||
|
manager(mManager) { };
|
||||||
|
|
||||||
void update() const;
|
void update() const;
|
||||||
void draw() const;
|
void draw() const;
|
||||||
@ -30,6 +48,11 @@ public:
|
|||||||
void addGroup(Group mGroup);
|
void addGroup(Group mGroup);
|
||||||
void delGroup(Group mGroup);
|
void delGroup(Group mGroup);
|
||||||
|
|
||||||
|
void setTeam(TeamLabel teamLabel);
|
||||||
|
TeamLabel getTeam();
|
||||||
|
|
||||||
|
Manager& getManager() { return manager; };
|
||||||
|
|
||||||
template <typename T> bool hasComponent() const
|
template <typename T> bool hasComponent() const
|
||||||
{
|
{
|
||||||
return componentBitSet[getComponentTypeID<T>()];
|
return componentBitSet[getComponentTypeID<T>()];
|
||||||
@ -63,4 +86,5 @@ private:
|
|||||||
ComponentArray componentArray = {};
|
ComponentArray componentArray = {};
|
||||||
ComponentBitSet componentBitSet;
|
ComponentBitSet componentBitSet;
|
||||||
GroupBitSet groupBitSet;
|
GroupBitSet groupBitSet;
|
||||||
|
TeamLabel teamLabel;
|
||||||
};
|
};
|
||||||
@ -5,7 +5,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class AssetManager;
|
class AssetManager;
|
||||||
class ColliderComponent;
|
class CollisionHandler;
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
@ -24,7 +24,7 @@ public:
|
|||||||
static void addTile(int id, int x, int y);
|
static void addTile(int id, int x, int y);
|
||||||
static SDL_Renderer* renderer;
|
static SDL_Renderer* renderer;
|
||||||
static SDL_Event event;
|
static SDL_Event event;
|
||||||
static std::vector<ColliderComponent*> colliders;
|
static CollisionHandler* collisionHandler;
|
||||||
static AssetManager* assets;
|
static AssetManager* assets;
|
||||||
|
|
||||||
bool getWinner();
|
bool getWinner();
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Constants.h"
|
#include "Constants.h"
|
||||||
|
#include "Entity.h"
|
||||||
class Entity;
|
|
||||||
|
|
||||||
class Manager
|
class Manager
|
||||||
{
|
{
|
||||||
@ -18,9 +17,13 @@ public:
|
|||||||
void addToGroup(Entity* mEntity, Group mGroup);
|
void addToGroup(Entity* mEntity, Group mGroup);
|
||||||
std::vector<Entity*>& getGroup(Group mGroup);
|
std::vector<Entity*>& getGroup(Group mGroup);
|
||||||
|
|
||||||
|
void addToTeam(Entity* mEntity, Team mTeam);
|
||||||
|
std::vector<Entity*>& getTeam(Team mTeam);
|
||||||
|
|
||||||
Entity& addEntity();
|
Entity& addEntity();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<Entity>> entities;
|
std::vector<std::unique_ptr<Entity>> entities;
|
||||||
std::array<std::vector<Entity*>, MAX_GROUPS> groupedEntities;
|
std::array<std::vector<Entity*>, MAX_GROUPS> entitiesByGroup;
|
||||||
|
std::array<std::vector<Entity*>, MAX_TEAMS> entitiesByTeam;
|
||||||
};
|
};
|
||||||
9
include/PlayerComponent.h
Normal file
9
include/PlayerComponent.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Component.h"
|
||||||
|
|
||||||
|
class PlayerComponent : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
private:
|
||||||
|
};
|
||||||
@ -13,6 +13,7 @@ public:
|
|||||||
friend Vector2D& operator-(Vector2D& vector1, const Vector2D& vector2);
|
friend Vector2D& operator-(Vector2D& vector1, const Vector2D& vector2);
|
||||||
friend Vector2D& operator*(Vector2D& vector1, const Vector2D& vector2);
|
friend Vector2D& operator*(Vector2D& vector1, const Vector2D& vector2);
|
||||||
friend Vector2D& operator/(Vector2D& vector1, const Vector2D& vector2);
|
friend Vector2D& operator/(Vector2D& vector1, const Vector2D& vector2);
|
||||||
|
friend Vector2D& operator+=(Vector2D& vector1, const Vector2D& vector2);
|
||||||
|
|
||||||
Vector2D& operator*(const int& i);
|
Vector2D& operator*(const int& i);
|
||||||
Vector2D& zero();
|
Vector2D& zero();
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "ColliderComponent.h"
|
#include "ColliderComponent.h"
|
||||||
|
|
||||||
|
#include "CollisionHandler.h"
|
||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "TransformComponent.h"
|
#include "TransformComponent.h"
|
||||||
@ -26,13 +27,13 @@ void ColliderComponent::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
transform = &entity->getComponent<TransformComponent>();
|
transform = &entity->getComponent<TransformComponent>();
|
||||||
Game::colliders.push_back(this);
|
//Game::collisionHandler->add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColliderComponent::update()
|
void ColliderComponent::update()
|
||||||
{
|
{
|
||||||
collider.x = transform->position.x;
|
collider.x = transform->position.x - (transform->width - transform->width * transform->scale * this->hitboxScale) / 2;
|
||||||
collider.y = transform->position.y;
|
collider.y = transform->position.y - (transform->width - transform->width * transform->scale * this->hitboxScale) / 2;
|
||||||
|
|
||||||
|
|
||||||
collider.w = (transform->width * transform->scale) * this->hitboxScale;
|
collider.w = (transform->width * transform->scale) * this->hitboxScale;
|
||||||
|
|||||||
94
src/CollisionHandler.cpp
Normal file
94
src/CollisionHandler.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "CollisionHandler.h"
|
||||||
|
|
||||||
|
#include "ColliderComponent.h"
|
||||||
|
#include "Constants.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "Manager.h"
|
||||||
|
#include "Vector2D.h"
|
||||||
|
|
||||||
|
#include <SDL_rect.h>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
IntersectionBitSet CollisionHandler::getIntersection(Entity* entityA, Entity* entityB)
|
||||||
|
{
|
||||||
|
return getIntersection(entityA, entityB, Vector2D(0,0), Vector2D(0,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
IntersectionBitSet CollisionHandler::getIntersection(Entity* entityA, Entity* entityB, Vector2D posModA, Vector2D posModB)
|
||||||
|
{
|
||||||
|
if (!entityA->hasComponent<ColliderComponent>() ||
|
||||||
|
!entityB->hasComponent<ColliderComponent>())
|
||||||
|
return std::bitset<DIRECTION_C>();
|
||||||
|
|
||||||
|
SDL_Rect* colliderA = &entityA->getComponent<ColliderComponent>().collider;
|
||||||
|
SDL_Rect* colliderB = &entityB->getComponent<ColliderComponent>().collider;
|
||||||
|
|
||||||
|
if (!SDL_HasIntersection(
|
||||||
|
colliderA,
|
||||||
|
colliderB))
|
||||||
|
return std::bitset<DIRECTION_C>();
|
||||||
|
|
||||||
|
std::bitset<DIRECTION_C> intersections;
|
||||||
|
|
||||||
|
// checks all 4 directions to allow checking full overlap
|
||||||
|
if (colliderA->x + posModA.x < colliderB->x + colliderB->w + posModB.x)
|
||||||
|
intersections.set((size_t) direction::LEFT) = 1;
|
||||||
|
|
||||||
|
if (colliderA->x + colliderA->w + posModA.x > colliderB->x + posModB.x)
|
||||||
|
intersections.set((size_t) direction::RIGHT) = 1;
|
||||||
|
|
||||||
|
if (colliderA->y + posModA.y < colliderB->y + colliderB->h + posModB.y)
|
||||||
|
intersections.set((size_t) direction::UP) = 1;
|
||||||
|
|
||||||
|
if (colliderA->y + colliderA->h + posModA.y > colliderB->y + posModB.y)
|
||||||
|
intersections.set((size_t) direction::DOWN) = 1;
|
||||||
|
|
||||||
|
return intersections;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntersectionBitSet CollisionHandler::getIntersectionWithBounds(Entity* entity)
|
||||||
|
{
|
||||||
|
return getIntersectionWithBounds(entity, Vector2D(0,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
IntersectionBitSet CollisionHandler::getIntersectionWithBounds(Entity* entity, Vector2D posMod)
|
||||||
|
{
|
||||||
|
if (!entity->hasComponent<ColliderComponent>())
|
||||||
|
return std::bitset<DIRECTION_C>();
|
||||||
|
|
||||||
|
SDL_Rect* collider = &entity->getComponent<ColliderComponent>().collider;
|
||||||
|
|
||||||
|
std::bitset<DIRECTION_C> intersections;
|
||||||
|
|
||||||
|
// all 4 directions and both sides to allow checking for fully out of bounds
|
||||||
|
if (collider->x + posMod.x < 0 ||
|
||||||
|
collider->x + posMod.x > SCREEN_SIZE_WIDTH)
|
||||||
|
intersections.set((size_t) direction::LEFT);
|
||||||
|
|
||||||
|
if (collider->x + collider->w + posMod.x < 0 ||
|
||||||
|
collider->x + collider->w + posMod.x > SCREEN_SIZE_WIDTH)
|
||||||
|
intersections.set((size_t) direction::RIGHT);
|
||||||
|
|
||||||
|
if (collider->y + posMod.y < 0 ||
|
||||||
|
collider->y + posMod.y > SCREEN_SIZE_HEIGHT)
|
||||||
|
intersections.set((size_t) direction::UP);
|
||||||
|
|
||||||
|
if (collider->y + collider->h + posMod.y < 0 ||
|
||||||
|
collider->y + collider->h + posMod.y > SCREEN_SIZE_HEIGHT)
|
||||||
|
intersections.set((size_t) direction::DOWN);
|
||||||
|
|
||||||
|
return intersections;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ColliderComponent*> CollisionHandler::getColliders(GroupLabel groupLabel)
|
||||||
|
{
|
||||||
|
std::vector<ColliderComponent*> colliders;
|
||||||
|
|
||||||
|
for (auto& entity : manager.getGroup((size_t) groupLabel)) {
|
||||||
|
if (!entity->hasComponent<ColliderComponent>())
|
||||||
|
continue;
|
||||||
|
colliders.emplace_back(&entity->getComponent<ColliderComponent>());
|
||||||
|
}
|
||||||
|
|
||||||
|
return colliders;
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Manager.h"
|
#include "Manager.h"
|
||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
void Entity::update() const
|
void Entity::update() const
|
||||||
{
|
{
|
||||||
@ -28,3 +29,14 @@ void Entity::delGroup(Group mGroup)
|
|||||||
{
|
{
|
||||||
groupBitSet[mGroup] = false;
|
groupBitSet[mGroup] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Entity::setTeam(TeamLabel teamLabel)
|
||||||
|
{
|
||||||
|
teamLabel = teamLabel;
|
||||||
|
manager.addToTeam(this, (size_t) teamLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
TeamLabel Entity::getTeam()
|
||||||
|
{
|
||||||
|
return teamLabel;
|
||||||
|
}
|
||||||
|
|||||||
83
src/Game.cpp
83
src/Game.cpp
@ -1,8 +1,10 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
|
|
||||||
|
#include "CollisionHandler.h"
|
||||||
#include "Components.h"
|
#include "Components.h"
|
||||||
|
|
||||||
#include "AssetManager.h"
|
#include "AssetManager.h"
|
||||||
|
#include "Entity.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
#include "TextureManager.h"
|
#include "TextureManager.h"
|
||||||
|
|
||||||
@ -11,14 +13,15 @@ Manager manager;
|
|||||||
|
|
||||||
AssetManager* Game::assets = new AssetManager(&manager);
|
AssetManager* Game::assets = new AssetManager(&manager);
|
||||||
|
|
||||||
|
CollisionHandler* Game::collisionHandler = new CollisionHandler(manager);
|
||||||
|
|
||||||
SDL_Renderer* Game::renderer = nullptr;
|
SDL_Renderer* Game::renderer = nullptr;
|
||||||
|
|
||||||
SDL_Event Game::event;
|
SDL_Event Game::event;
|
||||||
|
|
||||||
std::vector<ColliderComponent*> Game::colliders;
|
auto& player1(manager.addEntity());
|
||||||
|
auto& player2(manager.addEntity());
|
||||||
|
|
||||||
auto& player(manager.addEntity());
|
|
||||||
auto& enemy(manager.addEntity());
|
|
||||||
auto& wall(manager.addEntity());
|
auto& wall(manager.addEntity());
|
||||||
//auto& projectile (manager.addEntity());
|
//auto& projectile (manager.addEntity());
|
||||||
|
|
||||||
@ -110,25 +113,27 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo
|
|||||||
|
|
||||||
//ecs implementation
|
//ecs implementation
|
||||||
|
|
||||||
player.addComponent<TransformComponent>(80,80,2); //posx, posy, scale
|
player1.addComponent<TransformComponent>(80,80,2); //posx, posy, scale
|
||||||
player.addComponent<SpriteComponent>("assets/chicken_knight_spritesheet.png", true); //adds sprite (32x32px), path needed
|
player1.addComponent<SpriteComponent>("assets/chicken_knight_spritesheet.png", true); //adds sprite (32x32px), path needed
|
||||||
player.addComponent<KeyboardController>(SDL_SCANCODE_W, SDL_SCANCODE_S, SDL_SCANCODE_A, SDL_SCANCODE_D, SDL_SCANCODE_E, Vector2D(1, 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(1, 0));//custom keycontrols can be added
|
||||||
player.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)
|
||||||
player.addComponent<HealthComponent>(5, &manager, true);
|
player1.addComponent<HealthComponent>(5, &manager, true);
|
||||||
player.addGroup((size_t)GroupLabel::PLAYERS); //tell programm what group it belongs to for rendering order
|
player1.addGroup((size_t) GroupLabel::PLAYERS); //tell programm what group it belongs to for rendering order
|
||||||
|
player1.setTeam(TeamLabel::BLUE);
|
||||||
|
|
||||||
enemy.addComponent<TransformComponent>(600, 500, 2);
|
player2.addComponent<TransformComponent>(600, 500, 2);
|
||||||
enemy.addComponent<SpriteComponent>("assets/chicken_spritesheet.png", true);
|
player2.addComponent<SpriteComponent>("assets/chicken_spritesheet.png", true);
|
||||||
enemy.addComponent<KeyboardController>(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_RCTRL, Vector2D(-1, 0));
|
player2.addComponent<KeyboardController>(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_RCTRL, Vector2D(-1, 0));
|
||||||
enemy.addComponent<ColliderComponent>("enemy", 0.8f);
|
player2.addComponent<ColliderComponent>("enemy", 0.8f);
|
||||||
enemy.addComponent<HealthComponent>(5, &manager, false);
|
player2.addComponent<HealthComponent>(5, &manager, false);
|
||||||
enemy.addGroup((size_t)GroupLabel::ENEMIES);
|
player2.addGroup((size_t) GroupLabel::PLAYERS);
|
||||||
|
player2.setTeam(TeamLabel::RED);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& tiles(manager.getGroup((size_t)GroupLabel::MAP));
|
auto& tiles(manager.getGroup((size_t)GroupLabel::MAPTILES));
|
||||||
auto& players(manager.getGroup((size_t)GroupLabel::PLAYERS));
|
auto& players(manager.getGroup((size_t)GroupLabel::PLAYERS));
|
||||||
auto& enemies(manager.getGroup((size_t)GroupLabel::ENEMIES));
|
auto& enemies(manager.getGroup((size_t)GroupLabel::PLAYERS));
|
||||||
auto& projectiles(manager.getGroup((size_t)GroupLabel::PROJECTILE));
|
auto& projectiles(manager.getGroup((size_t)GroupLabel::PROJECTILE));
|
||||||
auto& hearts(manager.getGroup((size_t)GroupLabel::HEARTS));
|
auto& hearts(manager.getGroup((size_t)GroupLabel::HEARTS));
|
||||||
|
|
||||||
@ -148,64 +153,70 @@ void Game::handleEvents()
|
|||||||
|
|
||||||
void Game::update()
|
void Game::update()
|
||||||
{
|
{
|
||||||
Vector2D playerPos = player.getComponent<TransformComponent>().position;
|
Vector2D playerPos = player1.getComponent<TransformComponent>().position;
|
||||||
Vector2D enemyPos = enemy.getComponent<TransformComponent>().position;
|
Vector2D enemyPos = player2.getComponent<TransformComponent>().position;
|
||||||
|
|
||||||
manager.refresh();
|
manager.refresh();
|
||||||
manager.update();
|
manager.update();
|
||||||
|
|
||||||
for (auto cc : colliders)
|
|
||||||
|
|
||||||
|
/*for (auto cc : Game::collisionHandler->getColliders(GroupLabel::COLLIDERS))
|
||||||
{
|
{
|
||||||
if (SDL_HasIntersection(&player.getComponent<ColliderComponent>().collider, &cc->collider) && strcmp(cc->tag, "player") && cc->hasCollision)
|
if (cc->hasCollision &&
|
||||||
|
strcmp(cc->tag, "player") &&
|
||||||
|
SDL_HasIntersection(&player1.getComponent<ColliderComponent>().collider, &cc->collider))
|
||||||
{
|
{
|
||||||
player.getComponent<TransformComponent>().position = playerPos;
|
player1.getComponent<TransformComponent>().position = playerPos;
|
||||||
}
|
}
|
||||||
if (SDL_HasIntersection(&enemy.getComponent<ColliderComponent>().collider, &cc->collider) && strcmp(cc->tag, "enemy") && cc->hasCollision)
|
if (cc->hasCollision &&
|
||||||
|
strcmp(cc->tag, "enemy") &&
|
||||||
|
SDL_HasIntersection(&player2.getComponent<ColliderComponent>().collider, &cc->collider))
|
||||||
{
|
{
|
||||||
enemy.getComponent<TransformComponent>().position = enemyPos;
|
player2.getComponent<TransformComponent>().position = enemyPos;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
//checking if projectiles hit player1 or player2
|
//checking if projectiles hit player1 or player2
|
||||||
for (auto& p : projectiles) {
|
for (auto& p : projectiles) {
|
||||||
if(SDL_HasIntersection(&enemy.getComponent<ColliderComponent>().collider, &p->getComponent<ColliderComponent>().collider)
|
if(SDL_HasIntersection(&player2.getComponent<ColliderComponent>().collider, &p->getComponent<ColliderComponent>().collider)
|
||||||
&& (p->getComponent<ColliderComponent>().hasCollision) && !p->getComponent<ProjectileComponent>().getSource()) {
|
&& (p->getComponent<ColliderComponent>().hasCollision) && !p->getComponent<ProjectileComponent>().getSource()) {
|
||||||
//std::cout << "Enemy hit!";
|
//std::cout << "Enemy hit!";
|
||||||
p->getComponent<ColliderComponent>().removeCollision();
|
p->getComponent<ColliderComponent>().removeCollision();
|
||||||
p->destroy();
|
p->destroy();
|
||||||
|
|
||||||
enemy.getComponent<HealthComponent>().getDamage();
|
player2.getComponent<HealthComponent>().getDamage();
|
||||||
|
|
||||||
//display updated health | pretty scuffed but works ig
|
//display updated health | pretty scuffed but works ig
|
||||||
for(auto h : hearts)
|
for(auto h : hearts)
|
||||||
h->destroy();
|
h->destroy();
|
||||||
|
|
||||||
player.getComponent<HealthComponent>().createAllHearts();
|
player1.getComponent<HealthComponent>().createAllHearts();
|
||||||
enemy.getComponent<HealthComponent>().createAllHearts();
|
player2.getComponent<HealthComponent>().createAllHearts();
|
||||||
|
|
||||||
if(enemy.getComponent<HealthComponent>().getHealth() < 1) {
|
if(player2.getComponent<HealthComponent>().getHealth() < 1) {
|
||||||
std::cout << "Player1 wins!" << std::endl;
|
std::cout << "Player1 wins!" << std::endl;
|
||||||
winner = true;
|
winner = true;
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SDL_HasIntersection(&player.getComponent<ColliderComponent>().collider, &p->getComponent<ColliderComponent>().collider)
|
if(SDL_HasIntersection(&player1.getComponent<ColliderComponent>().collider, &p->getComponent<ColliderComponent>().collider)
|
||||||
&& (p->getComponent<ColliderComponent>().hasCollision) && p->getComponent<ProjectileComponent>().getSource()) {
|
&& (p->getComponent<ColliderComponent>().hasCollision) && p->getComponent<ProjectileComponent>().getSource()) {
|
||||||
//std::cout << "Player hit!";
|
//std::cout << "Player hit!";
|
||||||
p->getComponent<ColliderComponent>().removeCollision();
|
p->getComponent<ColliderComponent>().removeCollision();
|
||||||
p->destroy();
|
p->destroy();
|
||||||
|
|
||||||
player.getComponent<HealthComponent>().getDamage();
|
player1.getComponent<HealthComponent>().getDamage();
|
||||||
|
|
||||||
//display updated health
|
//display updated health
|
||||||
for(auto h : hearts)
|
for(auto h : hearts)
|
||||||
h->destroy();
|
h->destroy();
|
||||||
|
|
||||||
player.getComponent<HealthComponent>().createAllHearts();
|
player1.getComponent<HealthComponent>().createAllHearts();
|
||||||
enemy.getComponent<HealthComponent>().createAllHearts();
|
player2.getComponent<HealthComponent>().createAllHearts();
|
||||||
|
|
||||||
if(player.getComponent<HealthComponent>().getHealth() < 1) {
|
if(player1.getComponent<HealthComponent>().getHealth() < 1) {
|
||||||
std::cout << "Player2 wins!" << std::endl;
|
std::cout << "Player2 wins!" << std::endl;
|
||||||
winner = false;
|
winner = false;
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
@ -251,7 +262,7 @@ void Game::addTile(int 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::MAP);
|
tile.addGroup((size_t)GroupLabel::MAPTILES);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Game::running() const
|
bool Game::running() const
|
||||||
|
|||||||
@ -2,12 +2,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Entity.h"
|
#include "Constants.h"
|
||||||
|
|
||||||
void Manager::update()
|
|
||||||
{
|
|
||||||
for (auto& e : entities) e->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::draw()
|
void Manager::draw()
|
||||||
{
|
{
|
||||||
@ -18,7 +13,7 @@ void Manager::refresh()
|
|||||||
{
|
{
|
||||||
for (auto i(0u); i < MAX_GROUPS; i++)
|
for (auto i(0u); i < MAX_GROUPS; i++)
|
||||||
{
|
{
|
||||||
auto& v(groupedEntities[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)
|
||||||
@ -27,6 +22,17 @@ void Manager::refresh()
|
|||||||
}), std::end(v));
|
}), std::end(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto i(0u); i < MAX_TEAMS; i++)
|
||||||
|
{
|
||||||
|
auto& v(entitiesByTeam[i]);
|
||||||
|
v.erase(
|
||||||
|
std::remove_if(std::begin(v), std::end(v),
|
||||||
|
[i](Entity* mEntity)
|
||||||
|
{
|
||||||
|
return !mEntity->isActive() || (size_t)(mEntity->getTeam()) != i;
|
||||||
|
}), 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::unique_ptr<Entity>& mEntity)
|
||||||
{
|
{
|
||||||
@ -35,14 +41,29 @@ void Manager::refresh()
|
|||||||
std::end(entities));
|
std::end(entities));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::update()
|
||||||
|
{
|
||||||
|
for (auto& e : entities) e->update();
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::addToGroup(Entity* mEntity, Group mGroup)
|
void Manager::addToGroup(Entity* mEntity, Group mGroup)
|
||||||
{
|
{
|
||||||
groupedEntities[mGroup].emplace_back(mEntity);
|
entitiesByGroup[mGroup].emplace_back(mEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Entity*>& Manager::getGroup(Group mGroup)
|
std::vector<Entity*>& Manager::getGroup(Group mGroup)
|
||||||
{
|
{
|
||||||
return groupedEntities[mGroup];
|
return entitiesByGroup[mGroup];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::addToTeam(Entity* mEntity, Team mTeam)
|
||||||
|
{
|
||||||
|
entitiesByTeam[mTeam].emplace_back(mEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Entity*>& Manager::getTeam(Team mTeam)
|
||||||
|
{
|
||||||
|
return entitiesByTeam[mTeam];
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity& Manager::addEntity()
|
Entity& Manager::addEntity()
|
||||||
|
|||||||
1
src/PlayerComponent.cpp
Normal file
1
src/PlayerComponent.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "PlayerComponent.h"
|
||||||
@ -1,5 +1,12 @@
|
|||||||
#include "TransformComponent.h"
|
#include "TransformComponent.h"
|
||||||
|
|
||||||
|
#include "CollisionHandler.h"
|
||||||
|
#include "ColliderComponent.h"
|
||||||
#include "Constants.h"
|
#include "Constants.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Vector2D.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
TransformComponent::TransformComponent()
|
TransformComponent::TransformComponent()
|
||||||
{
|
{
|
||||||
@ -44,12 +51,39 @@ void TransformComponent::update()
|
|||||||
// if(velocity.x != 0 && velocity.y != 0)
|
// if(velocity.x != 0 && velocity.y != 0)
|
||||||
|
|
||||||
float multiplier = velocity.x != 0 && velocity.y != 0 ? 0.707 : 1; //normalizes vector
|
float multiplier = velocity.x != 0 && velocity.y != 0 ? 0.707 : 1; //normalizes vector
|
||||||
Vector2D newPos(
|
Vector2D positionChange(
|
||||||
position.x + velocity.x * speed * multiplier,
|
velocity.x * speed * multiplier,
|
||||||
position.y + velocity.y * speed * multiplier
|
velocity.y * speed * multiplier
|
||||||
);
|
);
|
||||||
if (newPos.x < 0 || newPos.x + (this->width * this->scale) > SCREEN_SIZE_WIDTH || newPos.y < 0 || newPos.y + (this->height * this->scale) > SCREEN_SIZE_HEIGHT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
position = newPos;
|
IntersectionBitSet intersectionsX = CollisionHandler::getIntersectionWithBounds(entity, positionChange);
|
||||||
|
for (auto& collider : Game::collisionHandler->getColliders(GroupLabel::MAPTILES)) {
|
||||||
|
intersectionsX |= CollisionHandler::getIntersection(entity, collider->entity, Vector2D(positionChange.x, 0), Vector2D(0, 0));
|
||||||
}
|
}
|
||||||
|
for (auto& collider : Game::collisionHandler->getColliders(GroupLabel::COLLIDERS)) {
|
||||||
|
intersectionsX |= CollisionHandler::getIntersection(entity, collider->entity, Vector2D(positionChange.x, 0), Vector2D(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
IntersectionBitSet intersectionsY = CollisionHandler::getIntersectionWithBounds(entity, positionChange);
|
||||||
|
for (auto& collider : Game::collisionHandler->getColliders(GroupLabel::MAPTILES)) {
|
||||||
|
intersectionsY |= CollisionHandler::getIntersection(entity, collider->entity, Vector2D(0, positionChange.y), Vector2D(0, 0));
|
||||||
|
}
|
||||||
|
for (auto& collider : Game::collisionHandler->getColliders(GroupLabel::COLLIDERS)) {
|
||||||
|
intersectionsY |= CollisionHandler::getIntersection(entity, collider->entity, Vector2D(0, positionChange.y), Vector2D(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intersectionsX.test((size_t) direction::LEFT) && positionChange.x < 0)
|
||||||
|
positionChange.x = 0;
|
||||||
|
|
||||||
|
if (intersectionsX.test((size_t) direction::RIGHT) && positionChange.x > 0)
|
||||||
|
positionChange.x = 0;
|
||||||
|
|
||||||
|
if (intersectionsY.test((size_t) direction::UP) && positionChange.y < 0)
|
||||||
|
positionChange.y = 0;
|
||||||
|
|
||||||
|
if (intersectionsY.test((size_t) direction::DOWN) && positionChange.y > 0)
|
||||||
|
positionChange.y = 0;
|
||||||
|
|
||||||
|
position += positionChange;
|
||||||
|
|
||||||
|
};
|
||||||
@ -36,6 +36,12 @@ Vector2D& operator/(Vector2D& vector1, const Vector2D& vector2)
|
|||||||
vector1.y /= vector2.y;
|
vector1.y /= vector2.y;
|
||||||
return vector1;
|
return vector1;
|
||||||
}
|
}
|
||||||
|
Vector2D& operator+=(Vector2D& vector1, const Vector2D& vector2)
|
||||||
|
{
|
||||||
|
vector1.x += vector2.x;
|
||||||
|
vector1.y += vector2.y;
|
||||||
|
return vector1;
|
||||||
|
}
|
||||||
Vector2D& Vector2D::operator*(const int& i)
|
Vector2D& Vector2D::operator*(const int& i)
|
||||||
{
|
{
|
||||||
this->x *= i;
|
this->x *= i;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user