From 98f8cbc2218484ac9c86c9ba27186beac20d3822 Mon Sep 17 00:00:00 2001 From: Markus Date: Sun, 21 Jan 2024 13:28:58 -0600 Subject: [PATCH] worst tutorial, but projectiles added --- CMakeLists.txt | 6 +++- extern/zlib | 2 +- include/AssetManager.h | 28 +++++++++++++++ include/ColliderComponent.h | 11 ++++++ include/Components.h | 1 + include/ECS.h | 5 ++- include/Game.h | 12 +++++++ include/KeyboardController.h | 11 ++++-- include/ProjectileComponent.h | 49 +++++++++++++++++++++++++ include/SpriteComponent.h | 6 +++- src/AssetManager.cpp | 26 ++++++++++++++ src/Game.cpp | 67 ++++++++++++++++++++++++++--------- src/KeyboardController.cpp | 24 ++++++++++++- 13 files changed, 224 insertions(+), 24 deletions(-) create mode 100644 include/AssetManager.h create mode 100644 include/ProjectileComponent.h create mode 100644 src/AssetManager.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e37fb4..02df20d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.15) project(SDL_Minigame) + set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -27,7 +28,10 @@ include_directories( ${PNG_INCLUDE_DIRS}) file(GLOB_RECURSE SOURCES ${PROJECT_SOURCE_DIR}/src/*.cpp) -add_executable(${PROJECT_NAME} ${SOURCES}) +add_executable(${PROJECT_NAME} ${SOURCES} + include/ProjectileComponent.h + include/AssetManager.h + src/AssetManager.cpp) target_link_libraries(${PROJECT_NAME} PRIVATE SDL2::SDL2main diff --git a/extern/zlib b/extern/zlib index 09155ea..95bb91d 160000 --- a/extern/zlib +++ b/extern/zlib @@ -1 +1 @@ -Subproject commit 09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851 +Subproject commit 95bb91dcec40c39693a1ab727e60b9ba076d8383 diff --git a/include/AssetManager.h b/include/AssetManager.h new file mode 100644 index 0000000..c74d441 --- /dev/null +++ b/include/AssetManager.h @@ -0,0 +1,28 @@ +#include +#include + +#include "TextureManager.h" +#include "Vector2D.h" +#include "Components.h" +#include "ECS.h" + +class AssetManager { + +public: + + AssetManager(Manager* manager); + ~AssetManager(); + + //game object management + void createProjectile(Vector2D pos, Vector2D velocity, bool source, int scale, int range, int speed, const char* texturePath); + + //texture management + void addTexture(std::string id, const char* path); + + SDL_Texture* getTexture(std::string id); + +private: + + Manager* man; + std::map textures; +}; diff --git a/include/ColliderComponent.h b/include/ColliderComponent.h index 2e24cf0..a090b1f 100644 --- a/include/ColliderComponent.h +++ b/include/ColliderComponent.h @@ -10,11 +10,18 @@ public: const char* tag; TransformComponent* transform; + bool hasCollision; + ColliderComponent(const char* tag) { this->tag = tag; + this->hasCollision = true; } + ~ColliderComponent() { + + } + void init() override { if (!entity->hasComponent()) @@ -33,4 +40,8 @@ public: collider.w = transform->width * transform->scale; collider.h = transform->height * transform->scale; } + + void removeCollision() { + this->hasCollision = false; + } }; \ No newline at end of file diff --git a/include/Components.h b/include/Components.h index 607d792..2f29913 100644 --- a/include/Components.h +++ b/include/Components.h @@ -5,4 +5,5 @@ #include "KeyboardController.h" #include "ColliderComponent.h" #include "TileComponent.h" +#include "ProjectileComponent.h" diff --git a/include/ECS.h b/include/ECS.h index 9b50830..96b05a8 100644 --- a/include/ECS.h +++ b/include/ECS.h @@ -7,6 +7,7 @@ #include #include + class Component; class Entity; class Manager; @@ -63,7 +64,9 @@ class Entity } bool isActive() const { return this->active; } - void destroy() { this->active = false; } + void destroy() { + this->active = false; + } bool hasGroup(Group mGroup) { diff --git a/include/Game.h b/include/Game.h index 838f66a..f680679 100644 --- a/include/Game.h +++ b/include/Game.h @@ -6,6 +6,8 @@ #include #include + +class AssetManager; class ColliderComponent; class Game @@ -26,6 +28,16 @@ class Game static SDL_Renderer* renderer; static SDL_Event event; static std::vector colliders; + static AssetManager* assets; + + enum GroupLabel + { + GROUP_MAP, + GROUP_PLAYERS, + GROUP_ENEMIES, + GROUP_COLLIDERS, + PROJECTILE + }; private: int counter = 0; diff --git a/include/KeyboardController.h b/include/KeyboardController.h index dbd75ff..01bfe0d 100644 --- a/include/KeyboardController.h +++ b/include/KeyboardController.h @@ -12,14 +12,21 @@ public: SDL_Scancode down; SDL_Scancode left; SDL_Scancode right; - //SDL_Scancode action; + SDL_Scancode fire; + + Uint32 lastFireTime; + Uint32 fireCooldown = 1000; KeyboardController(); - KeyboardController(SDL_Scancode up, SDL_Scancode down, SDL_Scancode left, SDL_Scancode right/*, SDL_Scancode action*/); + KeyboardController(SDL_Scancode up, SDL_Scancode down, SDL_Scancode left, SDL_Scancode right, SDL_Scancode fire, Vector2D fireVelocity); ~KeyboardController(); void init() override; void update() override; + +private: + TransformComponent* player; + Vector2D fireVelocity; }; diff --git a/include/ProjectileComponent.h b/include/ProjectileComponent.h new file mode 100644 index 0000000..7cdb308 --- /dev/null +++ b/include/ProjectileComponent.h @@ -0,0 +1,49 @@ +#pragma once + +#include "ECS.h" +#include "Components.h" +#include "Vector2D.h" + +class ProjectileComponent : public Component { + +public: + + ProjectileComponent(int range, int speed, Vector2D velocity, bool source) : range(range), speed(speed), velocity(velocity), source(source) { + + } + + ~ProjectileComponent() {} + + void init() override { + transformComponent = &entity->getComponent(); + } + + void update() override { + transformComponent->velocity = velocity; + distance += speed; + + if (distance > range) { + entity->destroy(); + entity->getComponent().removeCollision(); + std::cout << "out of range" << std::endl; + } + + } + + bool getSource() { + return this->source; + } + + +private: + + TransformComponent* transformComponent; + + int range = 0; + int speed = 0; + int distance = 0; + + const bool source; + + Vector2D velocity; +}; \ No newline at end of file diff --git a/include/SpriteComponent.h b/include/SpriteComponent.h index 9a5667c..8ba9c26 100644 --- a/include/SpriteComponent.h +++ b/include/SpriteComponent.h @@ -2,6 +2,10 @@ #include "Components.h" #include "SDL.h" #include "TextureManager.h" +#include "Game.h" + +class Game; +class AssetManager; class SpriteComponent : public Component { @@ -14,7 +18,7 @@ class SpriteComponent : public Component ~SpriteComponent() { - SDL_DestroyTexture(this->texture); + //SDL_DestroyTexture(this->texture); } void setTexture(const char* path) diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp new file mode 100644 index 0000000..8b57afb --- /dev/null +++ b/src/AssetManager.cpp @@ -0,0 +1,26 @@ +#include "AssetManager.h" +#include "Components.h" + +AssetManager::AssetManager(Manager* manager) : man(manager) { + +} + +AssetManager::~AssetManager() {} + +void AssetManager::addTexture(std::string id, const char* path) { + textures.emplace(id, TextureManager::get().loadTexture(path)); +} + +SDL_Texture* AssetManager::getTexture(std::string id) { + return textures.at(id); +} + +void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, bool source, int scale, int range, int speed, const char* texturePath) { + + auto& projectile(man->addEntity()); + projectile.addComponent(pos.x, pos.y, 32, 32, scale); + projectile.addComponent(texturePath); + projectile.addComponent(range, speed, velocity, source); + projectile.addComponent("projectile"); + projectile.addGroup(Game::PROJECTILE); +} \ No newline at end of file diff --git a/src/Game.cpp b/src/Game.cpp index 622f521..f5ef63c 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -4,11 +4,13 @@ #include "ECS.h" #include "Components.h" #include "Vector2D.h" - +#include "AssetManager.h" Map* map; Manager manager; +AssetManager* Game::assets = new AssetManager(&manager); + SDL_Renderer* Game::renderer = nullptr; SDL_Event Game::event; @@ -18,14 +20,9 @@ std::vector Game::colliders; auto& player(manager.addEntity()); auto& enemy(manager.addEntity()); auto& wall(manager.addEntity()); +auto& projectile (manager.addEntity()); + -enum GroupLabel -{ - GROUP_MAP, - GROUP_PLAYERS, - GROUP_ENEMIES, - GROUP_COLLIDERS -}; Game::Game() { @@ -66,22 +63,41 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo map = new Map(); map->loadMap("assets/SDL_map_test.txt", 25, 20); + assets->addTexture("player1", "assets/chicken_neutral_knight.png"); + assets->addTexture("player2", "assets/chicken_neutral.png"); + assets->addTexture("bigEgg", "assets/bigger_egg.png"); + + //ecs implementation player.addComponent(0,0,2); //posx, posy, scale player.addComponent("assets/chicken_neutral_knight.png"); //adds sprite (32x32px), path needed - player.addComponent(SDL_SCANCODE_W, SDL_SCANCODE_S, SDL_SCANCODE_A, SDL_SCANCODE_D);//custom keycontrols can be added + player.addComponent(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("player"); //adds tag (for further use, reference tag) player.addGroup(GROUP_PLAYERS); //tell programm what group it belongs to for rendering order enemy.addComponent(600, 500, 2); enemy.addComponent("assets/chicken_neutral.png"); - enemy.addComponent(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT); + enemy.addComponent(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_RCTRL, Vector2D(-1, 0)); enemy.addComponent("enemy"); enemy.addGroup(GROUP_ENEMIES); + /* + projectile.addComponent(500, 500, 32, 32, 2); + projectile.addComponent("assets/chicken_neutral_knight.png"); + projectile.addComponent(200, 1, Vector2D(1,0)); + projectile.addComponent("projectile"); + projectile.addGroup(Game::PROJECTILE); + + assets->createProjectile(Vector2D(50, 100), Vector2D(1,0), 1, 180, 1, "assets/chicken_neutral_knight.png"); + */ } +auto& tiles(manager.getGroup(Game::GROUP_MAP)); +auto& players(manager.getGroup(Game::GROUP_PLAYERS)); +auto& enemies(manager.getGroup(Game::GROUP_ENEMIES)); +auto& projectiles(manager.getGroup(Game::PROJECTILE)); + void Game::handleEvents() { SDL_PollEvent(&event); @@ -107,21 +123,35 @@ void Game::update() for (auto cc : colliders) { - if (SDL_HasIntersection(&player.getComponent().collider, &cc->collider) && strcmp(cc->tag, "player")) + if (SDL_HasIntersection(&player.getComponent().collider, &cc->collider) && strcmp(cc->tag, "player") && cc->hasCollision) { player.getComponent().position = playerPos; } - if (SDL_HasIntersection(&enemy.getComponent().collider, &cc->collider) && strcmp(cc->tag, "enemy")) + if (SDL_HasIntersection(&enemy.getComponent().collider, &cc->collider) && strcmp(cc->tag, "enemy") && cc->hasCollision) { enemy.getComponent().position = enemyPos; } } -} -auto& tiles(manager.getGroup(GROUP_MAP)); -auto& players(manager.getGroup(GROUP_PLAYERS)); -auto& enemies(manager.getGroup(GROUP_ENEMIES)); + for (auto& p : projectiles) { + if(SDL_HasIntersection(&enemy.getComponent().collider, &p->getComponent().collider) + && (p->getComponent().hasCollision) && !p->getComponent().getSource()) { + std::cout << "Enemy hit!"; + p->getComponent().removeCollision(); + p->destroy(); + } + + if(SDL_HasIntersection(&player.getComponent().collider, &p->getComponent().collider) + && (p->getComponent().hasCollision) && p->getComponent().getSource()) { + std::cout << "Player hit!"; + p->getComponent().removeCollision(); + p->destroy(); + } + } + + +} void Game::render() { @@ -138,6 +168,9 @@ void Game::render() { e->draw(); } + for (auto& p : projectiles) + p->draw(); + SDL_RenderPresent(renderer); } @@ -154,7 +187,7 @@ void Game::addTile(int id, int x, int y) auto& tile(manager.addEntity()); tile.addComponent(x, y, TILE_SIZE, TILE_SIZE, id); if (id == 1) tile.addComponent("water"); - tile.addGroup(GROUP_MAP); + tile.addGroup(Game::GROUP_MAP); } bool Game::running() diff --git a/src/KeyboardController.cpp b/src/KeyboardController.cpp index 1d71e02..88ef377 100644 --- a/src/KeyboardController.cpp +++ b/src/KeyboardController.cpp @@ -1,16 +1,19 @@ #include "KeyboardController.h" +#include "AssetManager.h" KeyboardController::KeyboardController() { } -KeyboardController::KeyboardController(SDL_Scancode up, SDL_Scancode down, SDL_Scancode left, SDL_Scancode right) +KeyboardController::KeyboardController(SDL_Scancode up, SDL_Scancode down, SDL_Scancode left, SDL_Scancode right, SDL_Scancode fire, Vector2D fireVelocity) { this->up = up; this->down = down; this->left = left; this->right = right; + this->fire = fire; + this->fireVelocity = fireVelocity; } KeyboardController::~KeyboardController() @@ -40,4 +43,23 @@ void KeyboardController::update() if (keystates[this->right]) { transform->velocity.x = 1; } + + if (keystates[this->fire]) { + Uint32 currentTicks = SDL_GetTicks(); + if (currentTicks - lastFireTime >= fireCooldown) { + + player = &entity->getComponent(); + if(fireVelocity.x > 0) { + Game::assets->createProjectile(Vector2D(player->position.x, player->position.y), fireVelocity, + false,1, 180, 1, "assets/chicken_neutral_knight.png"); + } + else { + Game::assets->createProjectile(Vector2D(player->position.x, player->position.y), fireVelocity, + true,1, 180, 1, "assets/chicken_neutral_knight.png"); + } + + lastFireTime = currentTicks; + } + + } } \ No newline at end of file