Compare commits

..

2 Commits

Author SHA1 Message Date
Jan Mrna
a52d670903 Basic zoom implemented 2025-10-05 21:20:30 +02:00
Jan Mrna
58fe1298c7 Refactor user input 2025-10-05 20:45:09 +02:00
6 changed files with 95 additions and 41 deletions

View File

@ -8,25 +8,26 @@
void Camera::Pan(const WorldPos& delta)
{
LOG_DEBUG("m_Pan before: ", m_Pan, " delta ", delta);
m_Pan += delta;
LOG_DEBUG("m_Pan after: ", m_Pan);
}
void Camera::Zoom(const WorldPos&)
void Camera::Zoom(float delta)
{
constexpr float ZOOM_SCALE = 0.1f;
m_Zoom += delta * ZOOM_SCALE;
LOG_DEBUG("Zoom: ", m_Zoom);
}
WindowPos Camera::WorldToWindow(WorldPos world) const
{
const auto& v = world + m_Pan;
return WindowPos{v[0], v[1]};
return WindowPos{v[0], v[1]} * m_Zoom;
}
WorldPos Camera::WindowToWorld(WindowPos window) const
{
return WorldPos{window[0], window[1]} - m_Pan;
window /= m_Zoom;
return WorldPos{window[0], window[1]} - m_Pan;
}

View File

@ -6,7 +6,7 @@ class Camera
{
public:
void Pan(const WorldPos& delta);
void Zoom(const WorldPos& delta);
void Zoom(float delta);
WindowPos WorldToWindow(WorldPos) const;
WorldPos WindowToWorld(WindowPos) const;
@ -15,6 +15,6 @@ public:
private:
// TODO this should be replaced with a matrix
float m_Zoom;
float m_Zoom = 1.0f;
WorldPos m_Pan;
};

View File

@ -127,6 +127,15 @@ public:
return a;
}
vec& operator/=(float scalar)
{
vec& a = *this;
auto b = std::views::repeat(scalar);
std::ranges::transform(a.m_Array, b, a.m_Array.begin(), std::divides{});
// TODO check all of this, could be done better with views instead of ranges?
return a;
}
//
// Utility functions
//

View File

@ -93,7 +93,8 @@ void PathFindingDemo::UpdatePlayerVelocity() {
double tile_velocity_coeff = m_Map.GetTileVelocityCoeff(current_pos);
auto next_pos = GetMoveTarget();
WorldPos velocity = WorldPos{};
if (next_pos) {
if (next_pos)
{
velocity = next_pos.value() - current_pos;
velocity.Normalize();
//LOG_DEBUG("I want to move to: ", next_pos.value(),
@ -104,26 +105,40 @@ void PathFindingDemo::UpdatePlayerVelocity() {
player->Update(time_delta);
}
void PathFindingDemo::HandleActions(const std::vector<UserAction> &actions) {
for (const auto &action : actions) {
if (action.type == UserAction::Type::EXIT) {
void PathFindingDemo::HandleActions(const std::vector<UserAction> &actions)
{
for (const auto &action : actions)
{
if (action.type == UserAction::Type::EXIT)
{
LOG_INFO("Exit requested");
m_ExitRequested = true;
} else if (action.type == UserAction::Type::SET_MOVE_TARGET) {
}
else if (action.type == UserAction::Type::SET_MOVE_TARGET)
{
WorldPos wp = m_Camera.WindowToWorld(action.Argument.position);
LOG_INFO("Calculating path to target: ", wp);
m_Path = m_PathFinder->CalculatePath(m_Player->GetPosition(), wp);
LOG_INFO("Done, path node count: ", m_Path.size());
} else if (action.type == UserAction::Type::SELECT_PATHFINDER) {
}
else if (action.type == UserAction::Type::SELECT_PATHFINDER)
{
using namespace pathfinder;
PathFinderType type = static_cast<PathFinderType>(action.Argument.number);
m_PathFinder = pathfinder::utils::create(type, (const Map*)&m_Map);
LOG_INFO("Switched to path finding method: ", m_PathFinder->GetName());
} else if (action.type == UserAction::Type::CAMERA_PAN) {
}
else if (action.type == UserAction::Type::CAMERA_PAN)
{
const auto& window_pan = action.Argument.position;
WorldPos world_pan{window_pan.x(), window_pan.y()};
m_Camera.Pan(world_pan);
LOG_INFO("Camera pan delta: ", world_pan);
}
else if (action.type == UserAction::Type::CAMERA_ZOOM)
{
m_Camera.Zoom(action.Argument.float_number);
LOG_INFO("Camera zoom: ", action.Argument.float_number);
}
};
}

View File

@ -3,6 +3,7 @@
#include <map>
#include <string>
#include <vector>
#include <unordered_set>
#include "user_input.hpp"
@ -23,33 +24,46 @@ void UserInput::GetActions_mouse(const SDL_Event& event)
{
static bool mouse_pan = false;
if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
SDL_MouseButtonEvent mouse_event = event.button;
MouseButton button = static_cast<MouseButton>(mouse_event.button);
if (button == MouseButton::LEFT) {
SDL_MouseButtonEvent mouse_event = event.button;
MouseButton button = static_cast<MouseButton>(mouse_event.button);
if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN)
{
if (button == MouseButton::LEFT)
{
LOG_DEBUG("Mouse down: ", mouse_event.x, ", ", mouse_event.y);
m_Actions.emplace_back(UserAction::Type::SET_MOVE_TARGET,
WindowPos{mouse_event.x, mouse_event.y});
} else if (button == MouseButton::MIDDLE) {
}
else if (button == MouseButton::MIDDLE)
{
mouse_pan = true;
}
} else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP) {
SDL_MouseButtonEvent mouse_event = event.button;
MouseButton button = static_cast<MouseButton>(mouse_event.button);
if (button == MouseButton::MIDDLE) {
}
else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP)
{
if (button == MouseButton::MIDDLE)
{
mouse_pan = false;
}
} else if (event.type == SDL_EVENT_MOUSE_MOTION) {
}
else if (event.type == SDL_EVENT_MOUSE_MOTION)
{
SDL_MouseMotionEvent motion_event = event.motion;
if (mouse_pan) {
if (mouse_pan)
{
m_Actions.emplace_back(UserAction::Type::CAMERA_PAN,
WindowPos{motion_event.xrel, motion_event.yrel});
WindowPos{motion_event.xrel, motion_event.yrel});
}
}
else if(event.type == SDL_EVENT_MOUSE_WHEEL)
{
SDL_MouseWheelEvent mouse_wheel = event.wheel;
m_Actions.emplace_back(UserAction::Type::CAMERA_ZOOM, mouse_wheel.y);
}
}
void UserInput::GetActions_kbd(const SDL_Event& event)
void UserInput::GetActions_keyboard(const SDL_Event& event)
{
bool key_down = event.type == SDL_EVENT_KEY_DOWN ? true : false;
SDL_KeyboardEvent kbd_event = event.key;
@ -81,18 +95,31 @@ void UserInput::GetActions_kbd(const SDL_Event& event)
}
const std::vector<UserAction>& UserInput::GetActions() {
m_Actions.clear();
SDL_Event event;
static std::unordered_set<uint32_t> mouse_events = {
SDL_EVENT_MOUSE_MOTION,
SDL_EVENT_MOUSE_BUTTON_DOWN,
SDL_EVENT_MOUSE_BUTTON_UP,
SDL_EVENT_MOUSE_WHEEL,
SDL_EVENT_MOUSE_ADDED,
SDL_EVENT_MOUSE_REMOVED,
};
while (SDL_PollEvent(&event)) {
if (event.type == SDL_EVENT_KEY_DOWN
|| event.type == SDL_EVENT_KEY_UP)
static std::unordered_set<uint32_t> keyboard_events = {
SDL_EVENT_KEY_DOWN,
SDL_EVENT_KEY_UP,
};
SDL_Event event;
m_Actions.clear();
while (SDL_PollEvent(&event))
{
if (keyboard_events.contains(event.type))
{
GetActions_kbd(event);
GetActions_keyboard(event);
}
else if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN
|| event.type == SDL_EVENT_MOUSE_BUTTON_UP
|| event.type == SDL_EVENT_MOUSE_MOTION)
else if (mouse_events.contains(event.type))
{
GetActions_mouse(event);
}

View File

@ -18,7 +18,8 @@ public:
UserAction(Type t) : type(t), Argument{.number = 0} {}
UserAction(Type t, char key) : type(t), Argument{.key = key} {}
UserAction(Type t, WindowPos v) : type(t), Argument{.position = v} {}
UserAction(Type t, int arg) : type(t), Argument{.number = arg} {}
UserAction(Type t, int32_t arg) : type(t), Argument{.number = arg} {}
UserAction(Type t, float arg) : type(t), Argument{.float_number = arg} {}
~UserAction() = default;
Type type;
@ -26,7 +27,8 @@ public:
union {
WindowPos position;
char key;
int number;
int32_t number;
float float_number;
} Argument;
// TODO use std::variant
@ -50,6 +52,6 @@ public:
private:
std::vector<UserAction> m_Actions;
void GetActions_kbd(const SDL_Event&);
void GetActions_keyboard(const SDL_Event&);
void GetActions_mouse(const SDL_Event&);
};