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

worst tutorial, but projectiles added

This commit is contained in:
Markus 2024-01-21 13:28:58 -06:00
parent 091ffb4a33
commit 98f8cbc221
13 changed files with 224 additions and 24 deletions

View File

@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.15)
project(SDL_Minigame) project(SDL_Minigame)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
@ -27,7 +28,10 @@ include_directories(
${PNG_INCLUDE_DIRS}) ${PNG_INCLUDE_DIRS})
file(GLOB_RECURSE SOURCES ${PROJECT_SOURCE_DIR}/src/*.cpp) 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 target_link_libraries(${PROJECT_NAME} PRIVATE
SDL2::SDL2main SDL2::SDL2main

2
extern/zlib vendored

@ -1 +1 @@
Subproject commit 09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851 Subproject commit 95bb91dcec40c39693a1ab727e60b9ba076d8383

28
include/AssetManager.h Normal file
View File

@ -0,0 +1,28 @@
#include <map>
#include <string>
#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<std::string, SDL_Texture*> textures;
};

View File

@ -10,11 +10,18 @@ public:
const char* tag; const char* tag;
TransformComponent* transform; TransformComponent* transform;
bool hasCollision;
ColliderComponent(const char* tag) ColliderComponent(const char* tag)
{ {
this->tag = tag; this->tag = tag;
this->hasCollision = true;
} }
~ColliderComponent() {
}
void init() override void init() override
{ {
if (!entity->hasComponent<TransformComponent>()) if (!entity->hasComponent<TransformComponent>())
@ -33,4 +40,8 @@ public:
collider.w = transform->width * transform->scale; collider.w = transform->width * transform->scale;
collider.h = transform->height * transform->scale; collider.h = transform->height * transform->scale;
} }
void removeCollision() {
this->hasCollision = false;
}
}; };

View File

@ -5,4 +5,5 @@
#include "KeyboardController.h" #include "KeyboardController.h"
#include "ColliderComponent.h" #include "ColliderComponent.h"
#include "TileComponent.h" #include "TileComponent.h"
#include "ProjectileComponent.h"

View File

@ -7,6 +7,7 @@
#include <bitset> #include <bitset>
#include <array> #include <array>
class Component; class Component;
class Entity; class Entity;
class Manager; class Manager;
@ -63,7 +64,9 @@ class Entity
} }
bool isActive() const { return this->active; } bool isActive() const { return this->active; }
void destroy() { this->active = false; } void destroy() {
this->active = false;
}
bool hasGroup(Group mGroup) bool hasGroup(Group mGroup)
{ {

View File

@ -6,6 +6,8 @@
#include <vector> #include <vector>
#include <string.h> #include <string.h>
class AssetManager;
class ColliderComponent; class ColliderComponent;
class Game class Game
@ -26,6 +28,16 @@ class Game
static SDL_Renderer* renderer; static SDL_Renderer* renderer;
static SDL_Event event; static SDL_Event event;
static std::vector<ColliderComponent*> colliders; static std::vector<ColliderComponent*> colliders;
static AssetManager* assets;
enum GroupLabel
{
GROUP_MAP,
GROUP_PLAYERS,
GROUP_ENEMIES,
GROUP_COLLIDERS,
PROJECTILE
};
private: private:
int counter = 0; int counter = 0;

View File

@ -12,14 +12,21 @@ public:
SDL_Scancode down; SDL_Scancode down;
SDL_Scancode left; SDL_Scancode left;
SDL_Scancode right; SDL_Scancode right;
//SDL_Scancode action; SDL_Scancode fire;
Uint32 lastFireTime;
Uint32 fireCooldown = 1000;
KeyboardController(); 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(); ~KeyboardController();
void init() override; void init() override;
void update() override; void update() override;
private:
TransformComponent* player;
Vector2D fireVelocity;
}; };

View File

@ -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<TransformComponent>();
}
void update() override {
transformComponent->velocity = velocity;
distance += speed;
if (distance > range) {
entity->destroy();
entity->getComponent<ColliderComponent>().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;
};

View File

@ -2,6 +2,10 @@
#include "Components.h" #include "Components.h"
#include "SDL.h" #include "SDL.h"
#include "TextureManager.h" #include "TextureManager.h"
#include "Game.h"
class Game;
class AssetManager;
class SpriteComponent : public Component class SpriteComponent : public Component
{ {
@ -14,7 +18,7 @@ class SpriteComponent : public Component
~SpriteComponent() ~SpriteComponent()
{ {
SDL_DestroyTexture(this->texture); //SDL_DestroyTexture(this->texture);
} }
void setTexture(const char* path) void setTexture(const char* path)

26
src/AssetManager.cpp Normal file
View File

@ -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<TransformComponent>(pos.x, pos.y, 32, 32, scale);
projectile.addComponent<SpriteComponent>(texturePath);
projectile.addComponent<ProjectileComponent>(range, speed, velocity, source);
projectile.addComponent<ColliderComponent>("projectile");
projectile.addGroup(Game::PROJECTILE);
}

View File

@ -4,11 +4,13 @@
#include "ECS.h" #include "ECS.h"
#include "Components.h" #include "Components.h"
#include "Vector2D.h" #include "Vector2D.h"
#include "AssetManager.h"
Map* map; Map* map;
Manager manager; Manager manager;
AssetManager* Game::assets = new AssetManager(&manager);
SDL_Renderer* Game::renderer = nullptr; SDL_Renderer* Game::renderer = nullptr;
SDL_Event Game::event; SDL_Event Game::event;
@ -18,14 +20,9 @@ std::vector<ColliderComponent*> Game::colliders;
auto& player(manager.addEntity()); auto& player(manager.addEntity());
auto& enemy(manager.addEntity()); auto& enemy(manager.addEntity());
auto& wall(manager.addEntity()); auto& wall(manager.addEntity());
auto& projectile (manager.addEntity());
enum GroupLabel
{
GROUP_MAP,
GROUP_PLAYERS,
GROUP_ENEMIES,
GROUP_COLLIDERS
};
Game::Game() 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 = new Map();
map->loadMap("assets/SDL_map_test.txt", 25, 20); 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 //ecs implementation
player.addComponent<TransformComponent>(0,0,2); //posx, posy, scale player.addComponent<TransformComponent>(0,0,2); //posx, posy, scale
player.addComponent<SpriteComponent>("assets/chicken_neutral_knight.png"); //adds sprite (32x32px), path needed player.addComponent<SpriteComponent>("assets/chicken_neutral_knight.png"); //adds sprite (32x32px), path needed
player.addComponent<KeyboardController>(SDL_SCANCODE_W, SDL_SCANCODE_S, SDL_SCANCODE_A, SDL_SCANCODE_D);//custom keycontrols can be added 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
player.addComponent<ColliderComponent>("player"); //adds tag (for further use, reference tag) player.addComponent<ColliderComponent>("player"); //adds tag (for further use, reference tag)
player.addGroup(GROUP_PLAYERS); //tell programm what group it belongs to for rendering order player.addGroup(GROUP_PLAYERS); //tell programm what group it belongs to for rendering order
enemy.addComponent<TransformComponent>(600, 500, 2); enemy.addComponent<TransformComponent>(600, 500, 2);
enemy.addComponent<SpriteComponent>("assets/chicken_neutral.png"); enemy.addComponent<SpriteComponent>("assets/chicken_neutral.png");
enemy.addComponent<KeyboardController>(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT); enemy.addComponent<KeyboardController>(SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_RCTRL, Vector2D(-1, 0));
enemy.addComponent<ColliderComponent>("enemy"); enemy.addComponent<ColliderComponent>("enemy");
enemy.addGroup(GROUP_ENEMIES); enemy.addGroup(GROUP_ENEMIES);
/*
projectile.addComponent<TransformComponent>(500, 500, 32, 32, 2);
projectile.addComponent<SpriteComponent>("assets/chicken_neutral_knight.png");
projectile.addComponent<ProjectileComponent>(200, 1, Vector2D(1,0));
projectile.addComponent<ColliderComponent>("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() void Game::handleEvents()
{ {
SDL_PollEvent(&event); SDL_PollEvent(&event);
@ -107,21 +123,35 @@ void Game::update()
for (auto cc : colliders) for (auto cc : colliders)
{ {
if (SDL_HasIntersection(&player.getComponent<ColliderComponent>().collider, &cc->collider) && strcmp(cc->tag, "player")) if (SDL_HasIntersection(&player.getComponent<ColliderComponent>().collider, &cc->collider) && strcmp(cc->tag, "player") && cc->hasCollision)
{ {
player.getComponent<TransformComponent>().position = playerPos; player.getComponent<TransformComponent>().position = playerPos;
} }
if (SDL_HasIntersection(&enemy.getComponent<ColliderComponent>().collider, &cc->collider) && strcmp(cc->tag, "enemy")) if (SDL_HasIntersection(&enemy.getComponent<ColliderComponent>().collider, &cc->collider) && strcmp(cc->tag, "enemy") && cc->hasCollision)
{ {
enemy.getComponent<TransformComponent>().position = enemyPos; enemy.getComponent<TransformComponent>().position = enemyPos;
} }
} }
}
auto& tiles(manager.getGroup(GROUP_MAP)); for (auto& p : projectiles) {
auto& players(manager.getGroup(GROUP_PLAYERS)); if(SDL_HasIntersection(&enemy.getComponent<ColliderComponent>().collider, &p->getComponent<ColliderComponent>().collider)
auto& enemies(manager.getGroup(GROUP_ENEMIES)); && (p->getComponent<ColliderComponent>().hasCollision) && !p->getComponent<ProjectileComponent>().getSource()) {
std::cout << "Enemy hit!";
p->getComponent<ColliderComponent>().removeCollision();
p->destroy();
}
if(SDL_HasIntersection(&player.getComponent<ColliderComponent>().collider, &p->getComponent<ColliderComponent>().collider)
&& (p->getComponent<ColliderComponent>().hasCollision) && p->getComponent<ProjectileComponent>().getSource()) {
std::cout << "Player hit!";
p->getComponent<ColliderComponent>().removeCollision();
p->destroy();
}
}
}
void Game::render() void Game::render()
{ {
@ -138,6 +168,9 @@ void Game::render()
{ {
e->draw(); e->draw();
} }
for (auto& p : projectiles)
p->draw();
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }
@ -154,7 +187,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(GROUP_MAP); tile.addGroup(Game::GROUP_MAP);
} }
bool Game::running() bool Game::running()

View File

@ -1,16 +1,19 @@
#include "KeyboardController.h" #include "KeyboardController.h"
#include "AssetManager.h"
KeyboardController::KeyboardController() 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->up = up;
this->down = down; this->down = down;
this->left = left; this->left = left;
this->right = right; this->right = right;
this->fire = fire;
this->fireVelocity = fireVelocity;
} }
KeyboardController::~KeyboardController() KeyboardController::~KeyboardController()
@ -40,4 +43,23 @@ void KeyboardController::update()
if (keystates[this->right]) { if (keystates[this->right]) {
transform->velocity.x = 1; transform->velocity.x = 1;
} }
if (keystates[this->fire]) {
Uint32 currentTicks = SDL_GetTicks();
if (currentTicks - lastFireTime >= fireCooldown) {
player = &entity->getComponent<TransformComponent>();
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;
}
}
} }