Compare commits
4 Commits
d3af793092
...
feature/co
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4fcd56f10 | ||
|
|
2f346c11c3 | ||
|
|
df6d323e42 | ||
|
|
1ce793c6e8 |
90
CMakeLists.txt
Normal file
90
CMakeLists.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(PathfindingDemo)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Find required packages
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SDL3 REQUIRED sdl3)
|
||||
pkg_check_modules(SDL3_image REQUIRED sdl3-image)
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLEW REQUIRED)
|
||||
|
||||
# Add Google Test
|
||||
find_package(GTest REQUIRED)
|
||||
|
||||
# Include directories
|
||||
include_directories(cpp/src)
|
||||
|
||||
# Source files for the main executable
|
||||
set(MAIN_SOURCES
|
||||
cpp/src/main.cpp
|
||||
cpp/src/camera.cpp
|
||||
cpp/src/entities.cpp
|
||||
cpp/src/gameloop.cpp
|
||||
cpp/src/map.cpp
|
||||
cpp/src/pathfinder/base.cpp
|
||||
cpp/src/pathfinder/bfs.cpp
|
||||
cpp/src/pathfinder/dijkstra.cpp
|
||||
cpp/src/pathfinder/gbfs.cpp
|
||||
cpp/src/pathfinder/utils.cpp
|
||||
cpp/src/pathfindingdemo.cpp
|
||||
cpp/src/sprite.cpp
|
||||
cpp/src/tile.cpp
|
||||
cpp/src/user_input.cpp
|
||||
cpp/src/window.cpp
|
||||
)
|
||||
|
||||
# Header files (for IDE support)
|
||||
set(HEADERS
|
||||
cpp/src/array.hpp
|
||||
cpp/src/camera.hpp
|
||||
cpp/src/entities.hpp
|
||||
cpp/src/gameloop.hpp
|
||||
cpp/src/log.hpp
|
||||
cpp/src/map.hpp
|
||||
cpp/src/math.hpp
|
||||
cpp/src/pathfinder/base.hpp
|
||||
cpp/src/pathfinder/bfs.hpp
|
||||
cpp/src/pathfinder/dijkstra.hpp
|
||||
cpp/src/pathfinder/gbfs.hpp
|
||||
cpp/src/pathfinder/utils.hpp
|
||||
cpp/src/pathfindingdemo.hpp
|
||||
cpp/src/sprite.hpp
|
||||
cpp/src/tile.hpp
|
||||
cpp/src/user_input.hpp
|
||||
cpp/src/window.hpp
|
||||
)
|
||||
|
||||
# Create main executable
|
||||
add_executable(pathfinding_demo ${MAIN_SOURCES} ${HEADERS})
|
||||
|
||||
# Link libraries for main executable
|
||||
target_link_libraries(pathfinding_demo
|
||||
${SDL3_LIBRARIES}
|
||||
${SDL3_image_LIBRARIES}
|
||||
OpenGL::GL
|
||||
GLEW::GLEW
|
||||
)
|
||||
|
||||
# Add compile flags
|
||||
target_compile_options(pathfinding_demo PRIVATE ${SDL3_CFLAGS_OTHER})
|
||||
|
||||
# Test executable
|
||||
add_executable(tests cpp/test/test.cpp)
|
||||
target_link_libraries(tests GTest::gtest GTest::gtest_main)
|
||||
|
||||
# Enable testing
|
||||
enable_testing()
|
||||
add_test(NAME unit_tests COMMAND tests)
|
||||
|
||||
# Compiler-specific options
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
target_compile_options(pathfinding_demo PRIVATE -Wall -Wextra -Wpedantic)
|
||||
target_compile_options(tests PRIVATE -Wall -Wextra -Wpedantic)
|
||||
endif()
|
||||
|
||||
# Debug/Release configurations
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
|
||||
@@ -15,6 +15,18 @@ public:
|
||||
WorldPos WindowToWorld(WindowPos) const;
|
||||
WindowSize WorldToWindowSize(WorldSize) const;
|
||||
WorldSize WindowToWorldSize(WindowSize) const;
|
||||
|
||||
template <typename T>
|
||||
requires std::floating_point<T>
|
||||
T WindowToWorldSize(T window_size) const {
|
||||
return window_size / static_cast<T>(m_Zoom);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires std::floating_point<T>
|
||||
T WorldToWindowSize(T world_size) const {
|
||||
return world_size * static_cast<T>(m_Zoom);
|
||||
}
|
||||
|
||||
private:
|
||||
// TODO this should be replaced with a matrix
|
||||
|
||||
@@ -67,6 +67,10 @@ public:
|
||||
|
||||
bool IsCollisionBoxVisible() const { return m_CollisionBoxVisible; }
|
||||
|
||||
void Select() { m_Selected = true; }
|
||||
void Deselect() { m_Selected = false; }
|
||||
bool IsSelected() const { return m_Selected; }
|
||||
|
||||
protected:
|
||||
WorldPos m_Position;
|
||||
WorldPos m_ActualVelocity;
|
||||
@@ -76,6 +80,7 @@ protected:
|
||||
private:
|
||||
bool m_FlagExpired = false;
|
||||
bool m_CollisionBoxVisible = true;
|
||||
bool m_Selected = false;
|
||||
};
|
||||
|
||||
class Player final : public Entity {
|
||||
|
||||
@@ -43,13 +43,19 @@ void GameLoop::Draw() {
|
||||
// draw all the entities (player etc)
|
||||
for (auto &entity : m_Game->GetEntities()) {
|
||||
const auto &camera = m_Game->GetCamera();
|
||||
auto entity_pos_window = camera.WorldToWindow(entity->GetPosition());
|
||||
m_Window->DrawSprite(entity_pos_window,
|
||||
auto entity_pos = camera.WorldToWindow(entity->GetPosition());
|
||||
m_Window->DrawSprite(entity_pos,
|
||||
entity->GetSprite(),
|
||||
camera.GetZoom());
|
||||
if (entity->IsCollisionBoxVisible())
|
||||
{
|
||||
m_Window->DrawCircle(entity_pos_window, entity->GetCollisionRadius());
|
||||
float collision_radius = camera.WorldToWindowSize(entity->GetCollisionRadius());
|
||||
m_Window->DrawCircle(entity_pos, collision_radius, 255, 0, 0);
|
||||
}
|
||||
if (entity->IsSelected())
|
||||
{
|
||||
float collision_radius = camera.WorldToWindowSize(entity->GetCollisionRadius());
|
||||
m_Window->DrawCircle(entity_pos, collision_radius, 0, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +63,7 @@ void GameLoop::Draw() {
|
||||
if (m_Game->IsSelectionBoxActive())
|
||||
{
|
||||
const auto& [corner_pos, size] = m_Game->GetSelectionBoxPosSize();
|
||||
m_Window->DrawRect(corner_pos, size, 200, 20, 20, 100);
|
||||
m_Window->DrawRect(corner_pos, size, 200, 20, 20);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -207,6 +207,7 @@ void PathFindingDemo::HandleActions(const std::vector<UserAction> &actions)
|
||||
{
|
||||
m_SelectionBox.active = true;
|
||||
m_SelectionBox.start = action.Argument.position;
|
||||
m_SelectionBox.end = action.Argument.position;
|
||||
}
|
||||
else if (action.type == UserAction::Type::SELECTION_END)
|
||||
{
|
||||
@@ -228,10 +229,21 @@ void PathFindingDemo::HandleActions(const std::vector<UserAction> &actions)
|
||||
};
|
||||
}
|
||||
|
||||
void PathFindingDemo::DeselectEntities()
|
||||
{
|
||||
std::for_each(m_SelectedEntities.begin(), m_SelectedEntities.end(), [](auto& x)
|
||||
{
|
||||
if (auto entity = x.lock())
|
||||
entity->Deselect();
|
||||
}
|
||||
);
|
||||
m_SelectedEntities.clear();
|
||||
}
|
||||
|
||||
void PathFindingDemo::SelectEntitiesInRectangle(WorldPos A, WorldPos B)
|
||||
{
|
||||
DeselectEntities();
|
||||
// TODO use colliders for this
|
||||
m_SelectedEntities.clear();
|
||||
auto [x_min, x_max] = std::minmax(A.x(), B.x());
|
||||
auto [y_min, y_max] = std::minmax(A.y(), B.y());
|
||||
for (const auto& entity : m_Entities)
|
||||
@@ -242,6 +254,7 @@ void PathFindingDemo::SelectEntitiesInRectangle(WorldPos A, WorldPos B)
|
||||
if (x_in_range && y_in_range)
|
||||
{
|
||||
m_SelectedEntities.push_back(std::weak_ptr(entity));
|
||||
entity->Select();
|
||||
}
|
||||
}
|
||||
LOG_INFO("Selected ", m_SelectedEntities.size(), " entities");
|
||||
|
||||
@@ -43,8 +43,10 @@ public:
|
||||
WorldPos GetRandomPosition() const;
|
||||
|
||||
void SelectEntitiesInRectangle(WorldPos A, WorldPos B);
|
||||
void DeselectEntities();
|
||||
bool IsSelectionBoxActive() const { return m_SelectionBox.active; }
|
||||
std::pair<WindowPos, WindowSize> GetSelectionBoxPosSize();
|
||||
std::vector<std::weak_ptr<Entity>> GetSelectedEntities() { return m_SelectedEntities; }
|
||||
|
||||
private:
|
||||
const std::vector<Collision>& GetEntityCollisions();
|
||||
|
||||
@@ -91,12 +91,10 @@ void Window::DrawFilledRect(const WindowPos &position, const WindowSize size, ui
|
||||
SDL_RenderFillRect(m_Renderer.get(), &rect);
|
||||
}
|
||||
|
||||
void Window::DrawRect(const WindowPos &position, const WindowSize size, uint8_t R,
|
||||
uint8_t G, uint8_t B, uint8_t fill_alpha) {
|
||||
void Window::DrawRect(const WindowPos &position, const WindowSize size, uint8_t R, uint8_t G, uint8_t B) {
|
||||
SDL_FRect rect = {position.x(), position.y(), size.x(), size.y()};
|
||||
SDL_SetRenderDrawColor(m_Renderer.get(), R, G, B, 255);
|
||||
SDL_RenderRect(m_Renderer.get(), &rect);
|
||||
//SDL_RenderFillRect(m_Renderer.get(), &rect);
|
||||
}
|
||||
|
||||
void Window::ClearWindow() {
|
||||
@@ -106,10 +104,11 @@ void Window::ClearWindow() {
|
||||
|
||||
void Window::Flush() { SDL_RenderPresent(m_Renderer.get()); }
|
||||
|
||||
void Window::DrawCircle(const WindowPos &position, float radius) {
|
||||
// TODO use some struct for color
|
||||
void Window::DrawCircle(const WindowPos &position, float radius, uint8_t R, uint8_t G, uint8_t B) {
|
||||
int cx = static_cast<int>(position.x());
|
||||
int cy = static_cast<int>(position.y());
|
||||
SDL_SetRenderDrawColor(m_Renderer.get(), 255, 0, 0, 255);
|
||||
SDL_SetRenderDrawColor(m_Renderer.get(), R, G, B, 255);
|
||||
for (int i = 0; i < 360; ++i) {
|
||||
double a = i * M_PI / 180.0;
|
||||
SDL_RenderPoint(m_Renderer.get(),
|
||||
|
||||
@@ -25,11 +25,10 @@ public:
|
||||
void DrawSprite(const WindowPos &position, Sprite &s, float scale = 1.0f);
|
||||
void DrawFilledRect(const WindowPos &position, const WindowSize size, uint8_t R,
|
||||
uint8_t G, uint8_t B, uint8_t A);
|
||||
void DrawRect(const WindowPos &position, const WindowSize size, uint8_t R,
|
||||
uint8_t G, uint8_t B, uint8_t fill_alpha);
|
||||
void DrawRect(const WindowPos &position, const WindowSize size, uint8_t R, uint8_t G, uint8_t B);
|
||||
void ClearWindow();
|
||||
void Flush();
|
||||
void DrawCircle(const WindowPos &position, float radius);
|
||||
void DrawCircle(const WindowPos &position, float radius, uint8_t R, uint8_t G, uint8_t B);
|
||||
void DrawLine(const WindowPos &A, const WindowPos &B);
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user