entity destruction, etc.
This commit is contained in:
116
CMakeLists.txt
116
CMakeLists.txt
@@ -4,59 +4,83 @@ project(Letnik3Zadnja)
|
|||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# Include FetchContent to download SDL from source
|
# Compile flags
|
||||||
include(FetchContent)
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-unused-parameter -O2")
|
||||||
|
|
||||||
# Download SDL3 from source
|
|
||||||
FetchContent_Declare(
|
|
||||||
SDL3
|
|
||||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
|
||||||
GIT_TAG release-3.4.2
|
|
||||||
)
|
|
||||||
|
|
||||||
# Download SDL3_image from source
|
|
||||||
FetchContent_Declare(
|
|
||||||
SDL3_image
|
|
||||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
|
|
||||||
GIT_TAG release-3.2.4
|
|
||||||
)
|
|
||||||
|
|
||||||
# Download SDL3_ttf from source
|
|
||||||
FetchContent_Declare(
|
|
||||||
SDL3_ttf
|
|
||||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_ttf.git
|
|
||||||
GIT_TAG release-3.2.2
|
|
||||||
)
|
|
||||||
|
|
||||||
# Download SDL3_mixer from source
|
|
||||||
FetchContent_Declare(
|
|
||||||
SDL3_mixer
|
|
||||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_mixer.git
|
|
||||||
GIT_TAG release-3.2.0
|
|
||||||
)
|
|
||||||
|
|
||||||
# Work around PipeWire API mismatch on some Linux distributions.
|
|
||||||
# Disable PipeWire backend in SDL; PulseAudio/ALSA backends remain available.
|
|
||||||
set(SDL_PIPEWIRE OFF CACHE BOOL "Disable SDL PipeWire backend" FORCE)
|
|
||||||
set(SDL_PIPEWIRE_SHARED OFF CACHE BOOL "Disable dynamic PipeWire loading in SDL" FORCE)
|
|
||||||
|
|
||||||
# Make SDL libraries available
|
|
||||||
FetchContent_MakeAvailable(SDL3)
|
|
||||||
FetchContent_MakeAvailable(SDL3_image)
|
|
||||||
FetchContent_MakeAvailable(SDL3_ttf)
|
|
||||||
FetchContent_MakeAvailable(SDL3_mixer)
|
|
||||||
|
|
||||||
# Collect all source files from src/ and nested directories
|
# Collect all source files from src/ and nested directories
|
||||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "src/*.cpp")
|
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "src/*.cpp")
|
||||||
|
|
||||||
# Compile flags
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-unused-parameter -O2")
|
|
||||||
|
|
||||||
# Create the executable
|
# Create the executable
|
||||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||||
|
|
||||||
# Include headers from include/
|
# Include headers from include/
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE include)
|
target_include_directories(${PROJECT_NAME} PRIVATE include)
|
||||||
|
|
||||||
# Link SDL3 and SDL3_image to the executable
|
# ------------------------------------------------------------
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE SDL3::SDL3 SDL3_image::SDL3_image SDL3_ttf::SDL3_ttf SDL3_mixer::SDL3_mixer)
|
# Platform-specific dependency handling
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
|
||||||
|
# Include FetchContent to download SDL libraries
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
# Download SDL3
|
||||||
|
FetchContent_Declare(
|
||||||
|
SDL3
|
||||||
|
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||||
|
GIT_TAG release-3.4.2
|
||||||
|
)
|
||||||
|
|
||||||
|
# Download SDL3_image
|
||||||
|
FetchContent_Declare(
|
||||||
|
SDL3_image
|
||||||
|
GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
|
||||||
|
GIT_TAG release-3.2.4
|
||||||
|
)
|
||||||
|
|
||||||
|
# Download SDL3_ttf
|
||||||
|
FetchContent_Declare(
|
||||||
|
SDL3_ttf
|
||||||
|
GIT_REPOSITORY https://github.com/libsdl-org/SDL_ttf.git
|
||||||
|
GIT_TAG release-3.2.2
|
||||||
|
)
|
||||||
|
|
||||||
|
# Download SDL3_mixer
|
||||||
|
FetchContent_Declare(
|
||||||
|
SDL3_mixer
|
||||||
|
GIT_REPOSITORY https://github.com/libsdl-org/SDL_mixer.git
|
||||||
|
GIT_TAG release-3.2.0
|
||||||
|
)
|
||||||
|
|
||||||
|
# Disable PipeWire backend (Linux-only but harmless here)
|
||||||
|
set(SDL_PIPEWIRE OFF CACHE BOOL "Disable SDL PipeWire backend" FORCE)
|
||||||
|
set(SDL_PIPEWIRE_SHARED OFF CACHE BOOL "Disable dynamic PipeWire loading in SDL" FORCE)
|
||||||
|
|
||||||
|
# Make SDL libraries available
|
||||||
|
FetchContent_MakeAvailable(SDL3)
|
||||||
|
FetchContent_MakeAvailable(SDL3_image)
|
||||||
|
FetchContent_MakeAvailable(SDL3_ttf)
|
||||||
|
FetchContent_MakeAvailable(SDL3_mixer)
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
# macOS / Linux → use system-installed packages
|
||||||
|
find_package(SDL3 REQUIRED)
|
||||||
|
find_package(SDL3_image REQUIRED)
|
||||||
|
find_package(SDL3_ttf REQUIRED)
|
||||||
|
find_package(SDL3_mixer REQUIRED)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# Link SDL libraries
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
SDL3::SDL3
|
||||||
|
SDL3_image::SDL3_image
|
||||||
|
SDL3_ttf::SDL3_ttf
|
||||||
|
SDL3_mixer::SDL3_mixer
|
||||||
|
)
|
||||||
@@ -23,13 +23,14 @@ namespace Game::Object {
|
|||||||
Entity& operator=(const Entity&);
|
Entity& operator=(const Entity&);
|
||||||
Entity(Entity&&) noexcept;
|
Entity(Entity&&) noexcept;
|
||||||
Entity& operator=(Entity&&) noexcept;
|
Entity& operator=(Entity&&) noexcept;
|
||||||
virtual ~Entity() = 0;
|
virtual ~Entity() = 0; // Destructor
|
||||||
|
|
||||||
// Start is called when the entity is spawned
|
// Start is called when the entity is spawned
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
// Update is called every update cycle; deltaTime is the time (in seconds) since the last update call
|
// Update is called every update cycle; deltaTime is the time (in seconds) since the last update call
|
||||||
virtual void update(float deltaTime) = 0;
|
virtual void update(float deltaTime) = 0;
|
||||||
virtual void onWindowResized(int newWidth, int newHeight) {} // Called when the window is resized, with the new width and height in pixels
|
virtual void onWindowResized(int newWidth, int newHeight) {} // Called when the window is resized, with the new width and height in pixels
|
||||||
|
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);
|
||||||
|
|
||||||
// Setters and getters
|
// Setters and getters
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace Game::State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sort(); // Sort entities by zIndex for correct rendering order
|
void sort(); // Sort entities by zIndex for correct rendering order
|
||||||
|
void wipe();
|
||||||
Object::Entity* getEntityByName(const std::string& name); // Get an entity by name, returns nullptr if no entity with the name exists
|
Object::Entity* getEntityByName(const std::string& name); // Get an entity by name, returns nullptr if no entity with the name exists
|
||||||
std::vector<Object::Entity*> getEntitiesSnapshot(bool sortByZIndex = false); // Get a stable snapshot of entity pointers for iteration outside the lock
|
std::vector<Object::Entity*> getEntitiesSnapshot(bool sortByZIndex = false); // Get a stable snapshot of entity pointers for iteration outside the lock
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ namespace Game::State {
|
|||||||
Object::Entity* getAtIndex(size_t at);
|
Object::Entity* getAtIndex(size_t at);
|
||||||
// Add an entity to the gamestate.
|
// Add an entity to the gamestate.
|
||||||
void addEntity(std::unique_ptr<Object::Entity> entity);
|
void addEntity(std::unique_ptr<Object::Entity> entity);
|
||||||
|
bool removeEntity(const std::string& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::mutex mMutex; // Shared mutex for thread safety
|
mutable std::mutex mMutex; // Shared mutex for thread safety
|
||||||
|
|||||||
@@ -37,5 +37,8 @@ namespace Game::AGame {
|
|||||||
} else if (playerY > bottomBound) {
|
} else if (playerY > bottomBound) {
|
||||||
Object::Camera::getInstance().move(0.f, mSpeed * deltaTime);
|
Object::Camera::getInstance().move(0.f, mSpeed * deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool* state = SDL_GetKeyboardState(nullptr);
|
||||||
|
mSpeed = state[SDL_SCANCODE_LSHIFT] ? 400.f : 200.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,5 +33,6 @@ namespace Game::AGame {
|
|||||||
if (state[SDL_SCANCODE_S]) mTransform.y += mSpeed * deltaTime;
|
if (state[SDL_SCANCODE_S]) mTransform.y += mSpeed * deltaTime;
|
||||||
if (state[SDL_SCANCODE_A]) mTransform.x -= mSpeed * deltaTime;
|
if (state[SDL_SCANCODE_A]) mTransform.x -= mSpeed * deltaTime;
|
||||||
if (state[SDL_SCANCODE_D]) mTransform.x += mSpeed * deltaTime;
|
if (state[SDL_SCANCODE_D]) mTransform.x += mSpeed * deltaTime;
|
||||||
|
mSpeed = state[SDL_SCANCODE_LSHIFT] ? 400.f : 200.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,6 +24,19 @@ namespace Game::State {
|
|||||||
LOG("Added entity '" << addedEntity->getName() << "' to GameState");
|
LOG("Added entity '" << addedEntity->getName() << "' to GameState");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GameState::removeEntity(const std::string& name) {
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex); // Lock the mutex for thread safety
|
||||||
|
for (size_t i = 0; i < mEntities.size(); i++) {
|
||||||
|
if (mEntities[i]->getName() == name) {
|
||||||
|
mEntities[i]->destroyed();
|
||||||
|
mEntities.erase(mEntities.begin() + i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void GameState::sort() {
|
void GameState::sort() {
|
||||||
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
|
||||||
std::sort(mEntities.begin(), mEntities.end(), [](const std::unique_ptr<Object::Entity>& a, const std::unique_ptr<Object::Entity>& b) {
|
std::sort(mEntities.begin(), mEntities.end(), [](const std::unique_ptr<Object::Entity>& a, const std::unique_ptr<Object::Entity>& b) {
|
||||||
@@ -31,6 +44,16 @@ namespace Game::State {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameState::wipe() {
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
for (const auto& entity : mEntities) {
|
||||||
|
if (entity) {
|
||||||
|
entity->destroyed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mEntities.clear();
|
||||||
|
}
|
||||||
|
|
||||||
Object::Entity* GameState::getEntityByName(const std::string& name) {
|
Object::Entity* GameState::getEntityByName(const std::string& name) {
|
||||||
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
|
||||||
for (const auto& entity : mEntities) {
|
for (const auto& entity : mEntities) {
|
||||||
|
|||||||
Reference in New Issue
Block a user