box collider
This commit is contained in:
@@ -10,6 +10,6 @@ GAME_ENTITY(Player)
|
|||||||
private:
|
private:
|
||||||
Object::Sound mSound;
|
Object::Sound mSound;
|
||||||
float mSpeed = 200.f; // Pixels per second
|
float mSpeed = 200.f; // Pixels per second
|
||||||
float mHealth = 100.f;
|
[[maybe_unused]] float mHealth = 100.f;
|
||||||
END_GAME_ENTITY()
|
END_GAME_ENTITY()
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <object/components/component.hpp>
|
#include <object/components/component.hpp>
|
||||||
|
#include <state/gamestate.hpp>
|
||||||
|
|
||||||
namespace Game::Object::Components {
|
namespace Game::Object::Components {
|
||||||
|
struct BoxColliderBounds {
|
||||||
|
float left, right, top, bottom;
|
||||||
|
};
|
||||||
|
|
||||||
class BoxCollider : public Component {
|
class BoxCollider : public Component {
|
||||||
public:
|
public:
|
||||||
BoxCollider() = default;
|
BoxCollider() = default;
|
||||||
@@ -15,6 +20,11 @@ namespace Game::Object::Components {
|
|||||||
void start(Object::Entity* thisEntity) override;
|
void start(Object::Entity* thisEntity) override;
|
||||||
void update(float deltaTime, Object::Entity* thisEntity) override;
|
void update(float deltaTime, Object::Entity* thisEntity) override;
|
||||||
|
|
||||||
|
BoxColliderBounds getBounds() const { return mBounds; }
|
||||||
|
bool isColliding() const { return mIsColliding; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BoxColliderBounds mBounds;
|
||||||
|
bool mIsColliding = false; // Whether this collider is currently colliding with another collider; used to determine whether to call onCollisionEnter vs onCollisionStay, and to call onCollisionExit when collisions end
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,14 @@ namespace Game::Object {
|
|||||||
virtual void destroyed() {}; // Pre-destruction call
|
virtual void destroyed() {}; // Pre-destruction call
|
||||||
void render(Game::Renderer::Renderer* renderer, Game::Renderer::RendererConfig config);
|
void render(Game::Renderer::Renderer* renderer, Game::Renderer::RendererConfig config);
|
||||||
|
|
||||||
|
// Collision calls
|
||||||
|
// Called once when a collision begins
|
||||||
|
virtual void onCollisionEnter(Entity* other) {}
|
||||||
|
// Called every update while a collision continues
|
||||||
|
virtual void onCollisionStay(Entity* other) {}
|
||||||
|
// Called once when a collision ends
|
||||||
|
virtual void onCollisionExit(Entity* other) {}
|
||||||
|
|
||||||
// Setters and getters
|
// Setters and getters
|
||||||
void setTexture(std::shared_ptr<Game::Renderer::Texture> tex) { mTex = tex; }
|
void setTexture(std::shared_ptr<Game::Renderer::Texture> tex) { mTex = tex; }
|
||||||
void setName(const std::string& name) { mName = name; }
|
void setName(const std::string& name) { mName = name; }
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ namespace Game::State {
|
|||||||
|
|
||||||
// Update entity at index, by REFERENCE.
|
// Update entity at index, by REFERENCE.
|
||||||
Object::Entity* getAtIndex(size_t at);
|
Object::Entity* getAtIndex(size_t at);
|
||||||
// Add an entity to the gamestate.
|
// Add an entity to the gamestate; Returns a temporary pointer to the entity added. Note that the validity of this pointer cannot be guaranteed after the first call.
|
||||||
void addEntity(std::unique_ptr<Object::Entity> entity);
|
Object::Entity* addEntity(std::unique_ptr<Object::Entity> entity);
|
||||||
bool removeEntity(const std::string& name);
|
bool removeEntity(const std::string& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
#include <mutex>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <renderer/texture.hpp>
|
#include <renderer/texture.hpp>
|
||||||
#include <renderer/font.hpp>
|
#include <renderer/font.hpp>
|
||||||
#include <game/agame/sampletextbox.hpp>
|
#include <game/agame/sampletextbox.hpp>
|
||||||
|
#include <object/components/boxcollider.hpp>
|
||||||
|
|
||||||
using namespace Game;
|
using namespace Game;
|
||||||
|
|
||||||
@@ -22,7 +23,8 @@ int main() {
|
|||||||
|
|
||||||
//Object::Transform t1{100.f, 100.f, 0.f, 1.f, 1.f};
|
//Object::Transform t1{100.f, 100.f, 0.f, 1.f, 1.f};
|
||||||
State::GameState::getInstance().addEntity(std::make_unique<AGame::Background>("BG", std::make_shared<Game::Renderer::Texture>("../resources/bgtest.png", window.getRenderer()->getSDLRenderer()), Object::DEFAULT_TRANSFORM));
|
State::GameState::getInstance().addEntity(std::make_unique<AGame::Background>("BG", std::make_shared<Game::Renderer::Texture>("../resources/bgtest.png", window.getRenderer()->getSDLRenderer()), Object::DEFAULT_TRANSFORM));
|
||||||
State::GameState::getInstance().addEntity(std::make_unique<AGame::Player>("Player", std::make_shared<Game::Renderer::Texture>("../resources/l3ladja.png", window.getRenderer()->getSDLRenderer()), Object::DEFAULT_TRANSFORM));
|
Object::Entity* player = State::GameState::getInstance().addEntity(std::make_unique<AGame::Player>("Player", std::make_shared<Game::Renderer::Texture>("../resources/l3ladja.png", window.getRenderer()->getSDLRenderer()), Object::DEFAULT_TRANSFORM));
|
||||||
|
player->addComponent<Object::Components::BoxCollider>();
|
||||||
//State::GameState::getInstance().addEntity(std::make_unique<AGame::Player>("Player2", std::make_shared<Game::Renderer::Font>("../resources/roboto.ttf", window.getRenderer()->getSDLRenderer(), 128, "Roboto"), t1));
|
//State::GameState::getInstance().addEntity(std::make_unique<AGame::Player>("Player2", std::make_shared<Game::Renderer::Font>("../resources/roboto.ttf", window.getRenderer()->getSDLRenderer(), 128, "Roboto"), t1));
|
||||||
|
|
||||||
window.run();
|
window.run();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <object/components/boxcollider.hpp>
|
#include <object/components/boxcollider.hpp>
|
||||||
|
#include <object/entity.hpp>
|
||||||
|
|
||||||
namespace Game::Object::Components {
|
namespace Game::Object::Components {
|
||||||
BoxCollider::BoxCollider(const BoxCollider& other) : Component(other) {
|
BoxCollider::BoxCollider(const BoxCollider& other) : Component(other) {
|
||||||
@@ -31,5 +32,44 @@ namespace Game::Object::Components {
|
|||||||
|
|
||||||
void BoxCollider::update(float deltaTime, Object::Entity* thisEntity) {
|
void BoxCollider::update(float deltaTime, Object::Entity* thisEntity) {
|
||||||
// Collision detection and response logic can go here
|
// Collision detection and response logic can go here
|
||||||
|
|
||||||
|
// Make box bounds
|
||||||
|
Transform* transform = thisEntity->getTransform();
|
||||||
|
float halfWidth = transform->scaleX * UNIVERSAL_SCALE_COEFFICIENT * 0.5f;
|
||||||
|
float halfHeight = transform->scaleY * UNIVERSAL_SCALE_COEFFICIENT * 0.5f;
|
||||||
|
float left = transform->x - halfWidth;
|
||||||
|
float right = transform->x + halfWidth;
|
||||||
|
float top = transform->y - halfHeight;
|
||||||
|
float bottom = transform->y + halfHeight;
|
||||||
|
|
||||||
|
mBounds = {left, right, top, bottom};
|
||||||
|
|
||||||
|
// Check for collisions with other entities that have box colliders
|
||||||
|
// For simplicity, just check each
|
||||||
|
std::vector<Entity*> entities = State::GameState::getInstance().getEntitiesSnapshot();
|
||||||
|
for (Entity* other : entities) {
|
||||||
|
if (other == thisEntity) continue; // Don't check collision with self
|
||||||
|
BoxCollider* otherCollider = other->getComponent<BoxCollider>();
|
||||||
|
if (!otherCollider) continue; // No collider, skip
|
||||||
|
BoxColliderBounds otherBounds = otherCollider->getBounds();
|
||||||
|
if (left < otherBounds.right && right > otherBounds.left && top < otherBounds.bottom && bottom > otherBounds.top) {
|
||||||
|
// Collision detected
|
||||||
|
if (!mIsColliding) {
|
||||||
|
mIsColliding = true;
|
||||||
|
thisEntity->onCollisionEnter(other);
|
||||||
|
other->onCollisionEnter(thisEntity);
|
||||||
|
} else {
|
||||||
|
thisEntity->onCollisionStay(other);
|
||||||
|
other->onCollisionStay(thisEntity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No collision
|
||||||
|
if (mIsColliding) {
|
||||||
|
mIsColliding = false;
|
||||||
|
thisEntity->onCollisionExit(other);
|
||||||
|
other->onCollisionExit(thisEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ namespace Game::State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState::addEntity(std::unique_ptr<Object::Entity> entity) {
|
Object::Entity* GameState::addEntity(std::unique_ptr<Object::Entity> entity) {
|
||||||
Object::Entity* addedEntity = nullptr;
|
Object::Entity* addedEntity = nullptr;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mMutex); // Lock the mutex for thread safety
|
std::lock_guard<std::mutex> lock(mMutex); // Lock the mutex for thread safety
|
||||||
@@ -23,6 +23,7 @@ namespace Game::State {
|
|||||||
|
|
||||||
addedEntity->start(); // Initialize the entity after insertion without holding the GameState lock.
|
addedEntity->start(); // Initialize the entity after insertion without holding the GameState lock.
|
||||||
LOG("Added entity '" << addedEntity->getName() << "' to GameState");
|
LOG("Added entity '" << addedEntity->getName() << "' to GameState");
|
||||||
|
return addedEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameState::removeEntity(const std::string& name) {
|
bool GameState::removeEntity(const std::string& name) {
|
||||||
|
|||||||
Reference in New Issue
Block a user