Skip to content

Commit

Permalink
feat: char base class and collision detection
Browse files Browse the repository at this point in the history
  • Loading branch information
araujo88 committed Apr 2, 2024
1 parent 1818634 commit d2cab53
Show file tree
Hide file tree
Showing 16 changed files with 204 additions and 56 deletions.
17 changes: 9 additions & 8 deletions include/NPC.hpp
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
#ifndef NPC_H_
#define NPC_H_

#include "character.hpp"
#include "constants.hpp"
#include "entity.hpp"
#include <chrono>
#include <random>
#include <string>
#include <thread>

namespace nano {
class NPC : public IEntity {
class NPC : public Character {
private:
int x, y;
const int max_speed = 10;
SDL_Texture *texture;
std::string name;
std::string spritePath;
std::random_device rd;
Uint32 lastMoveTime = 0;

public:
NPC(SDL_Renderer *renderer, std::string spritePath);
NPC(std::string name, int x, int y, SDL_Renderer *renderer,
std::string spritePath);
void move();
void render(SDL_Renderer *renderer) override;
void handleEvent(SDL_Event *event) override;
void update() override;
~NPC();
std::string getName() override;
SDL_Rect getBoundingBox() override;
void handleCollision() override;
bool isColliding(const SDL_Rect &box) override;
~NPC() override = default;
};
} // namespace nano

Expand Down
31 changes: 31 additions & 0 deletions include/character.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef CHARACTER_H_
#define CHARACTER_H_

#include "constants.hpp"
#include "entity.hpp"
#include <chrono>
#include <random>
#include <string>
#include <thread>

namespace nano {
class Character : public IEntity {
protected:
int x = 0, y = 0;
SDL_Texture *texture;
std::string spritePath;

public:
Character(std::string name, int x, int y, SDL_Renderer *renderer,
std::string spritePath);
void render(SDL_Renderer *renderer) override;
void handleEvent(SDL_Event *event) override;
void update() override;
bool isColliding(const SDL_Rect &box) override;
virtual ~Character();
std::string getName() override;
SDL_Rect getBoundingBox() override;
void handleCollision() override;
};
} // namespace nano
#endif
6 changes: 3 additions & 3 deletions include/constants.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#ifndef CONSTANTS_H_
#define CONSTANTS_H_

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 640
#define TILE_SIZE 32
#define WINDOW_WIDTH 832
#define WINDOW_HEIGHT 576
#define TILE_SIZE 64
#define TILES_X WINDOW_WIDTH / TILE_SIZE
#define TILES_Y WINDOW_HEIGHT / TILE_SIZE
#define WORLD_WIDTH 100
Expand Down
8 changes: 8 additions & 0 deletions include/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@

namespace nano {
class IEntity {
protected:
SDL_Rect boundingBox;
std::string name;

public:
virtual void render(SDL_Renderer *renderer) = 0;
virtual void handleEvent(SDL_Event *event) = 0;
virtual void update() = 0;
virtual bool isColliding(const SDL_Rect &box) = 0;
virtual std::string getName() = 0;
virtual SDL_Rect getBoundingBox() = 0;
virtual void handleCollision() = 0;
};
} // namespace nano

Expand Down
17 changes: 9 additions & 8 deletions include/player.hpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
#ifndef PLAYER_H_
#define PLAYER_H_

#include "character.hpp"
#include "constants.hpp"
#include "entity.hpp"
#include <string>

namespace nano {
class Player : public IEntity {
class Player : public Character {
private:
int x, y;
int speed;
SDL_Texture *texture;
std::string name;
std::string spritePath;

public:
Player(int x, int y, int speed, SDL_Renderer *renderer,
Player(std::string name, SDL_Renderer *renderer, std::string spritePath);
Player(std::string name, int x, int y, int speed, SDL_Renderer *renderer,
std::string spritePath);
void moveUp();
void moveDown();
Expand All @@ -24,7 +21,11 @@ class Player : public IEntity {
void render(SDL_Renderer *renderer) override;
void handleEvent(SDL_Event *event) override;
void update() override;
~Player();
std::string getName() override;
SDL_Rect getBoundingBox() override;
void handleCollision() override;
bool isColliding(const SDL_Rect &box) override;
~Player() override = default;
};
} // namespace nano

Expand Down
4 changes: 4 additions & 0 deletions include/world.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class World : public IEntity {
void render(SDL_Renderer *renderer) override;
void handleEvent(SDL_Event *event) override;
void update() override;
std::string getName() override;
SDL_Rect getBoundingBox() override;
void handleCollision() override;
bool isColliding(const SDL_Rect &box) override;
~World();
};
} // namespace nano
Expand Down
Binary file added sprites/chud.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added sprites/chud2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added sprites/wojak.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added sprites/wojak.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions src/character.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "../include/character.hpp"

using namespace nano;

Character::Character(std::string name, int x, int y, SDL_Renderer *renderer,
std::string spritePath) {
texture = IMG_LoadTexture(renderer, spritePath.c_str());
if (!texture) {
SDL_Log("Failed to load character texture: %s", IMG_GetError());
exit(1);
}
this->name = name;
this->x = x;
this->y = y;
this->boundingBox = {this->x, this->y, TILE_SIZE, TILE_SIZE};

SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION,
"%s bounding box: h:%d,w:%d,x:%d,y:%d", this->name.c_str(),
this->boundingBox.h, this->boundingBox.w, this->boundingBox.x,
this->boundingBox.y);
};

void Character::render(SDL_Renderer *renderer) {
SDL_Rect CharacterRect = {x, y, TILE_SIZE, TILE_SIZE};
SDL_RenderCopy(renderer, texture, NULL, &CharacterRect);
}

void Character::handleEvent(SDL_Event *event) {}

void Character::update() {}

bool Character::isColliding(const SDL_Rect &box) {
return (this->boundingBox.x < box.x + box.w) &&
(this->boundingBox.x + this->boundingBox.w > box.x) &&
(this->boundingBox.y < box.y + box.h) &&
(this->boundingBox.y + this->boundingBox.h > box.y);
}

std::string Character::getName() { return this->name; };

SDL_Rect Character::getBoundingBox() { return this->boundingBox; };

void Character::handleCollision() {}

Character::~Character() { SDL_DestroyTexture(texture); }
30 changes: 30 additions & 0 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,38 @@ void Game::clear() {

void Game::update() {
SDL_RenderPresent(renderer);

IEntity *player = nullptr;
// Find the player entity, if it exists
for (auto &entity : entities) {
if (entity->getName() == "Player") {
player = entity; // Directly use the raw pointer since entities are raw
// pointers
break; // Stop the loop once the player is found
}
}

// Update all entities
for (auto &entity : entities) {
entity->update();
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION,
"%s bounding box: h:%d,w:%d,x:%d,y:%d",
entity->getName().c_str(), entity->getBoundingBox().h,
entity->getBoundingBox().w, entity->getBoundingBox().x,
entity->getBoundingBox().y);
}

// If a player is found, then check for collisions with other entities
if (player) {
for (auto &character : entities) {
// Make sure not to check the player against itself
if (character != player &&
player->isColliding(character->getBoundingBox())) {
character->handleCollision();
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION,
"Collision detected between Player and another entity.");
}
}
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ int main(void) {

nano::World world = nano::World(game.getRenderer(), "sprites/grass.png");

nano::Player player = nano::Player(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, 10,
game.getRenderer(), "sprites/player.png");
nano::Player player =
nano::Player("Player", WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, 32,
game.getRenderer(), "sprites/wojak.png");

std::vector<nano::NPC *> npcs;

for (int i = 0; i < 10; ++i)
npcs.push_back(new nano::NPC(game.getRenderer(), "sprites/angry_sun.png"));
npcs.push_back(
new nano::NPC("NPC", 0, 0, game.getRenderer(), "sprites/chud.png"));

game.addEntity(&world);
game.addEntity(&player);
Expand Down
30 changes: 17 additions & 13 deletions src/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@

using namespace nano;

NPC::NPC(SDL_Renderer *renderer, std::string spritePath) {
NPC::NPC(std::string name, int x, int y, SDL_Renderer *renderer,
std::string spritePath)
: Character(name, x, y, renderer, spritePath) {
std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()

std::uniform_int_distribution<> distribX(0, WINDOW_WIDTH);
std::uniform_int_distribution<> distribY(0, WINDOW_HEIGHT);

this->x = distribX(gen);
this->y = distribY(gen);

texture = IMG_LoadTexture(renderer, spritePath.c_str());
if (!texture) {
SDL_Log("Failed to load NPC texture: %s", IMG_GetError());
exit(1);
}
};

void NPC::move() {
Expand All @@ -33,11 +29,9 @@ void NPC::move() {
if ((y < WINDOW_HEIGHT - TILE_SIZE) && (y > 0)) {
y += speed_y;
}
}

void NPC::render(SDL_Renderer *renderer) {
SDL_Rect NPCRect = {x, y, TILE_SIZE, TILE_SIZE};
SDL_RenderCopy(renderer, texture, NULL, &NPCRect);
this->boundingBox.x = x;
this->boundingBox.y = y;
}

void NPC::update() {
Expand All @@ -49,6 +43,16 @@ void NPC::update() {
}
}

void NPC::handleEvent(SDL_Event *event) {}
void NPC::render(SDL_Renderer *renderer) { Character::render(renderer); }

bool NPC::isColliding(const SDL_Rect &box) {
return Character::isColliding(box);
}

std::string NPC::getName() { return Character::getName(); };

SDL_Rect NPC::getBoundingBox() { return Character::getBoundingBox(); };

NPC::~NPC() { SDL_DestroyTexture(texture); }
void NPC::handleCollision() {}

void NPC::handleEvent(SDL_Event *event) {}
Loading

0 comments on commit d2cab53

Please sign in to comment.