diff --git a/include/AnimationHandler.h b/include/AnimationHandler.h index 6fc8081..069fc2f 100644 --- a/include/AnimationHandler.h +++ b/include/AnimationHandler.h @@ -1,5 +1,5 @@ #pragma once -#include +#include struct Animation { uint8_t index; diff --git a/include/AssetManager.h b/include/AssetManager.h index c6038c0..c0e4db4 100644 --- a/include/AssetManager.h +++ b/include/AssetManager.h @@ -1,14 +1,20 @@ -#include "Entity.h" - +#pragma once #include #include #include -#include "Powerup.h" +#include "Entity.h" class Vector2D; class Manager; +enum class PowerupType +{ + HEART, + WALKINGSPEED, + SHOOTINGSPEED +}; + class AssetManager { public: @@ -19,6 +25,9 @@ public: void createProjectile(Vector2D pos, Vector2D velocity, bool source, int scale, int range, int speed, const char* texturePath, TeamLabel teamLabel); void createPowerup(Vector2D pos, PowerupType type); + Vector2D calculateSpawnPosition(); + PowerupType calculateType(); + //texture management void addTexture(std::string id, const char* path); diff --git a/include/Constants.h b/include/Constants.h index 855b461..e4acb6c 100644 --- a/include/Constants.h +++ b/include/Constants.h @@ -7,6 +7,7 @@ using Team = std::size_t; constexpr std::size_t MAX_COMPONENTS = 32; constexpr std::size_t MAX_GROUPS = 32; +constexpr std::size_t MAX_STATS = 32; constexpr std::size_t MAX_TEAMS = 8; // constexpr int SCREEN_SIZE_HEIGHT = 640; @@ -21,3 +22,7 @@ constexpr int MAP_SIZE_Y = 20; constexpr int SPAWN_ATTEMPTS = 30; +constexpr int BUFF_DURATION = 5000; + +constexpr int BUFF_VALUE = 1; + diff --git a/include/KeyboardController.h b/include/KeyboardController.h index 1466719..eb36173 100644 --- a/include/KeyboardController.h +++ b/include/KeyboardController.h @@ -3,6 +3,7 @@ #include "Component.h" #include "Vector2D.h" +#include "Constants.h" class TransformComponent; class SpriteComponent; @@ -31,6 +32,8 @@ public: void init() override; void update() override; + void modifyAtkSpeed(int8_t modifier); + private: //for creation of projectiles TransformComponent* player; //for starting position of projectile diff --git a/include/Powerup.h b/include/Powerup.h deleted file mode 100644 index eaef7ac..0000000 --- a/include/Powerup.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "Component.h" -#include "Manager.h" -#include "Vector2D.h" -#include - -enum class PowerupType -{ - HEART, - WALKINGSPEED, - SHOOTINGSPEED -}; - -class Powerup -{ -public: - Powerup(){} - ~Powerup(){} - - static Vector2D calculateSpawnPosition(); - static PowerupType calculateType(); - -private: - Manager* manager; -}; \ No newline at end of file diff --git a/include/PowerupComponent.h b/include/PowerupComponent.h new file mode 100644 index 0000000..f83ea29 --- /dev/null +++ b/include/PowerupComponent.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Component.h" +#include "AssetManager.h" + +class PowerupComponent : public Component +{ +public: + PowerupComponent(PowerupType type); + ~PowerupComponent() {}; + + void update() override; + void heartEffect(Entity* player); + void movementSpeedEffect(Entity* player); + void atkSpeedEffect(Entity* player); + +private: + void (PowerupComponent::*pickupFunc)(Entity* player); +}; \ No newline at end of file diff --git a/include/ProjectileComponent.h b/include/ProjectileComponent.h index 8fa949c..2ce171f 100644 --- a/include/ProjectileComponent.h +++ b/include/ProjectileComponent.h @@ -2,6 +2,7 @@ #include "Component.h" #include "Vector2D.h" +#include "Constants.h" class TransformComponent; diff --git a/include/StatEffectsComponent.h b/include/StatEffectsComponent.h new file mode 100644 index 0000000..9dd8c5b --- /dev/null +++ b/include/StatEffectsComponent.h @@ -0,0 +1,27 @@ +#pragma once +#include "Component.h" +#include "Constants.h" +#include +#include + +enum class Stats +{ + MOVEMENT_SPEED, + ATTACK_SPEED +}; + +class StatEffectsComponent : public Component{ +public: + StatEffectsComponent() {}; + ~StatEffectsComponent() {}; + + void init() override; + void update() override; + + void modifyStatDur(Stats stat, uint8_t duration); + + void modifyStatValue(Stats stat, int modifier); + +private: + std::array buffs = { 0 }; +}; \ No newline at end of file diff --git a/include/TextureDict.h b/include/TextureDict.h index 40d146f..e0dabf6 100644 --- a/include/TextureDict.h +++ b/include/TextureDict.h @@ -2,7 +2,7 @@ #include #include -#include "Powerup.h" +#include "AssetManager.h" class TextureDict { diff --git a/include/TransformComponent.h b/include/TransformComponent.h index deed7f9..e41cfaa 100644 --- a/include/TransformComponent.h +++ b/include/TransformComponent.h @@ -2,6 +2,7 @@ #include "Component.h" #include "Vector2D.h" +#include "Constants.h" class TransformComponent : public Component { @@ -23,4 +24,5 @@ public: void init() override; void update() override; + void modifySpeed(int8_t modifier); }; diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 2932b1a..60315ac 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -1,9 +1,19 @@ #include "AssetManager.h" -#include "Entity.h" #include "TextureManager.h" #include "Components.h" +#include "TransformComponent.h" + +#include "CollisionHandler.h" +#include "ColliderComponent.h" +#include "Constants.h" +#include "Entity.h" +#include "Game.h" +#include "Vector2D.h" +#include "PowerupComponent.h" +#include + AssetManager::AssetManager(Manager* manager) : man(manager) {} AssetManager::~AssetManager() {} @@ -45,5 +55,37 @@ void AssetManager::createPowerup(Vector2D pos, PowerupType type) { } powerups.addComponent("powerup", 0.6f); + powerups.addComponent(type); powerups.addGroup((size_t)GroupLabel::POWERUPS); +} + +Vector2D AssetManager::calculateSpawnPosition() +{ + Vector2D spawnPos = Vector2D(-1, -1); + bool conflict = false; + for (int i = 0; i <= SPAWN_ATTEMPTS; i++) + { + SDL_Rect spawnRect; + spawnRect.h = spawnRect.w = 32; + spawnRect.x = rand() % (SCREEN_SIZE_WIDTH - spawnRect.w); + spawnRect.y = rand() % (SCREEN_SIZE_HEIGHT - spawnRect.h); + conflict = false; + for (auto cc : Game::collisionHandler->getColliders({ GroupLabel::MAPTILES })) + { + if (SDL_HasIntersection(&spawnRect, &cc->collider) && strcmp(cc->tag, "projectile")) + { + conflict = true; + break; + } + } + if (conflict) continue; + spawnPos = Vector2D(spawnRect.x, spawnRect.y); + } + return spawnPos; +} + +PowerupType AssetManager::calculateType() +{ + PowerupType type = PowerupType(rand() % 3); + return type; } \ No newline at end of file diff --git a/src/Game.cpp b/src/Game.cpp index 9571df6..c0045c8 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -9,7 +9,7 @@ #include "HealthComponent.h" #include "Map.h" #include "TextureManager.h" -#include "Powerup.h" +#include "StatEffectsComponent.h" Map* map; Manager manager; @@ -122,6 +122,7 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo player1.addComponent(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("player", 0.8f); //adds tag (for further use, reference tag) player1.addComponent(5, Direction::LEFT); + player1.addComponent(); player1.addGroup((size_t) GroupLabel::PLAYERS); //tell programm what group it belongs to for rendering order @@ -131,6 +132,7 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo player2.addComponent(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_RCTRL, Vector2D(-1, 0)); player2.addComponent("enemy", 0.8f); player2.addComponent(5, Direction::RIGHT); + player2.addComponent(); player2.addGroup((size_t) GroupLabel::PLAYERS); } @@ -167,7 +169,7 @@ void Game::update() if (powerupSpawn == 0) { - assets->createPowerup(Powerup::calculateSpawnPosition(), Powerup::calculateType()); + assets->createPowerup(assets->calculateSpawnPosition(), assets->calculateType()); } // needs to be in game.cpp to have access to internal functions diff --git a/src/KeyboardController.cpp b/src/KeyboardController.cpp index 507a44e..66462c2 100644 --- a/src/KeyboardController.cpp +++ b/src/KeyboardController.cpp @@ -71,4 +71,10 @@ void KeyboardController::update() } } +} + +void KeyboardController::modifyAtkSpeed(int8_t modifier) +{ + this->fireCooldown -= modifier * 500; + std::cout << "curr fire cooldown: " << this->fireCooldown << std::endl; } \ No newline at end of file diff --git a/src/Powerup.cpp b/src/Powerup.cpp deleted file mode 100644 index 5dd2d2a..0000000 --- a/src/Powerup.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "Powerup.h" - -#include "CollisionHandler.h" -#include "Entity.h" -#include "TextureDict.h" -#include -#include "Constants.h" -#include "Game.h" -#include "ColliderComponent.h" - -Vector2D Powerup::calculateSpawnPosition() -{ - Vector2D spawnPos = Vector2D(-1,-1); - bool conflict = false; - for (int i = 0; i <= SPAWN_ATTEMPTS; i++) - { - SDL_Rect spawnRect; - spawnRect.h = spawnRect.w = 32; - spawnRect.x = rand() % (SCREEN_SIZE_WIDTH - spawnRect.w); - spawnRect.y = rand() % (SCREEN_SIZE_HEIGHT - spawnRect.h); - conflict = false; - for (auto cc : Game::collisionHandler->getColliders(GroupLabel::MAPTILES)) - { - if (SDL_HasIntersection(&spawnRect, &cc->collider) && strcmp(cc->tag, "projectile")) - { - conflict = true; - break; - } - } - if (conflict) continue; - spawnPos = Vector2D(spawnRect.x, spawnRect.y); - } - return spawnPos; -} - -PowerupType Powerup::calculateType() -{ - PowerupType type = PowerupType(rand() % 3); - return type; -} \ No newline at end of file diff --git a/src/PowerupComponent.cpp b/src/PowerupComponent.cpp new file mode 100644 index 0000000..6a36051 --- /dev/null +++ b/src/PowerupComponent.cpp @@ -0,0 +1,56 @@ +#include "PowerupComponent.h" +#include "Game.h" +#include "CollisionHandler.h" +#include "Entity.h" +#include "HealthComponent.h" +#include "StatEffectsComponent.h" +#include "Constants.h" + +PowerupComponent::PowerupComponent(PowerupType type) +{ + switch (type) + { + case PowerupType::HEART: + this->pickupFunc = (&PowerupComponent::heartEffect); + break; + case PowerupType::WALKINGSPEED: + this->pickupFunc = (&PowerupComponent::movementSpeedEffect); + break; + case PowerupType::SHOOTINGSPEED: + this->pickupFunc = (&PowerupComponent::atkSpeedEffect); + break; + default: + break; + } +} + +void PowerupComponent::update() +{ + Entity* player; + if ((player = Game::collisionHandler->getAnyIntersection( + entity, + Vector2D(0, 0), + { GroupLabel::PLAYERS }, + {}, + true)) != nullptr) + { + std::cout << "collided with powerup" << std::endl; + (this->*pickupFunc)(player); + this->entity->destroy(); + } +} + +void PowerupComponent::heartEffect(Entity* player) +{ + player->getComponent().modifyHealth(1); +} + +void PowerupComponent::movementSpeedEffect(Entity* player) +{ + player->getComponent().modifyStatDur(Stats::MOVEMENT_SPEED, BUFF_DURATION); +} + +void PowerupComponent::atkSpeedEffect(Entity* player) +{ + player->getComponent().modifyStatDur(Stats::ATTACK_SPEED, BUFF_DURATION); +} \ No newline at end of file diff --git a/src/StatEffectsComponent.cpp b/src/StatEffectsComponent.cpp new file mode 100644 index 0000000..b6ba763 --- /dev/null +++ b/src/StatEffectsComponent.cpp @@ -0,0 +1,54 @@ +#include "StatEffectsComponent.h" +#include "Entity.h" +#include "TransformComponent.h" +#include "KeyboardController.h" +#include +#include + +void StatEffectsComponent::init() +{} + +void StatEffectsComponent::update() +{ + /*int i = 0; + std::transform(this->buffs.begin(), this->buffs.end(), this->buffs.begin(), + [this, &i](uint8_t statDuration) { + i++; + uint8_t newDur = statDuration - 1; + if (statDuration > 0 && newDur == 0) { + if (statDuration > 1) + std::cout << (int) statDuration << (int) newDur << std::endl; + this->modifyStatValue((Stats)i, BUFF_VALUE * -1); + } + return newDur; + });*/ + for (int i = 0; i < MAX_STATS; i++) + { + if (this->buffs.at(i) == 0) continue; + if (this->buffs.at(i) - 1 == 0) + { + this->modifyStatValue((Stats)i, BUFF_VALUE * -1); + } + this->buffs.at(i) -= 1; + } +} + +void StatEffectsComponent::modifyStatDur(Stats stat, uint8_t duration) +{ + if(this->buffs.at((uint8_t)stat) == 0) this->modifyStatValue(stat, BUFF_VALUE); + this->buffs.at((uint8_t)stat) += duration; +} + +void StatEffectsComponent::modifyStatValue(Stats stat, int modifier) +{ + switch (stat) + { + case Stats::MOVEMENT_SPEED: + this->entity->getComponent().modifySpeed(modifier); + break; + case Stats::ATTACK_SPEED: + this->entity->getComponent().modifyAtkSpeed(modifier); + break; + default: break; + } +} \ No newline at end of file diff --git a/src/TransformComponent.cpp b/src/TransformComponent.cpp index f6ab5d1..6b2dba4 100644 --- a/src/TransformComponent.cpp +++ b/src/TransformComponent.cpp @@ -60,21 +60,26 @@ void TransformComponent::update() // TODO: move to separate functions - if (this->entity->hasGroup((size_t) GroupLabel::PLAYERS)) { + if (this->entity->hasGroup((size_t)GroupLabel::PLAYERS)) { IntersectionBitSet intersections = (CollisionHandler::getIntersectionWithBounds(entity, Vector2D(positionChange.x, 0)) | - (Game::collisionHandler->getAnyIntersection(entity, Vector2D(positionChange.x, 0), {GroupLabel::MAPTILES, GroupLabel::COLLIDERS})) & + (Game::collisionHandler->getAnyIntersection(entity, Vector2D(positionChange.x, 0), { GroupLabel::MAPTILES, GroupLabel::COLLIDERS })) & IntersectionBitSet("0011")) | (CollisionHandler::getIntersectionWithBounds(entity, Vector2D(0, positionChange.y)) | - (Game::collisionHandler->getAnyIntersection(entity, Vector2D(0, positionChange.y), {GroupLabel::MAPTILES, GroupLabel::COLLIDERS})) & + (Game::collisionHandler->getAnyIntersection(entity, Vector2D(0, positionChange.y), { GroupLabel::MAPTILES, GroupLabel::COLLIDERS })) & IntersectionBitSet("1100")); - if (intersections.test((size_t) direction::LEFT) || intersections.test((size_t) direction::RIGHT)) - positionChange.x = 0; + if (intersections.test((size_t)direction::LEFT) || intersections.test((size_t)direction::RIGHT)) + positionChange.x = 0; - if (intersections.test((size_t) direction::UP) || intersections.test((size_t) direction::DOWN)) + if (intersections.test((size_t)direction::UP) || intersections.test((size_t)direction::DOWN)) positionChange.y = 0; } position += positionChange; -}; \ No newline at end of file +} + +void TransformComponent::modifySpeed(int8_t modifier) +{ + this->speed += modifier * 2; +} \ No newline at end of file