From ac4d45893847070533c42a72a340f5bcea8935a7 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sun, 19 Jul 2026 10:31:23 +0700 Subject: [PATCH] Add ctrl-drag camera panning, live drag selection, space to attack --- game.cpp | 113 +++++++++++++++++-------------------------------------- game.h | 8 +++- 2 files changed, 41 insertions(+), 80 deletions(-) diff --git a/game.cpp b/game.cpp index 6295c23..82ca418 100644 --- a/game.cpp +++ b/game.cpp @@ -72,51 +72,17 @@ GameState *Init() { void Input(GameState *state) { if (IsMouseButtonPressed(0)) { - state->selection_mouse_start_pos = optional{GetScreenToWorld2D(GetMousePosition(), state->camera)}; + if (IsKeyDown(KEY_LEFT_CONTROL)) { + state->drag_camera_start_pos = optional{GetMousePosition()}; + state->camera_target_start_pos = state->camera.target; + } else { + auto point = GetScreenToWorld2D(GetMousePosition(), state->camera); + state->selection_mouse_start_pos = optional{point}; + } } if (IsMouseButtonReleased(0)) { - // TODO: This is what should happen when the distance is too small - // Point start_pos = game->selection_mouse_start_pos.some.point; - Point start_pos = state->selection_mouse_start_pos.value(); - Point current_pos = GetScreenToWorld2D(GetMousePosition(), state->camera); - - if (Vector2DistanceSqr(current_pos, start_pos) >= 100.0f) { - f32 width = current_pos.x - start_pos.x; - f32 height = current_pos.y - start_pos.y; - f32 x = width >= 0.0f ? start_pos.x : current_pos.x; - f32 y = height >= 0.0f ? start_pos.y : current_pos.y; - Rectangle rect = {x, y, fabs(width), fabs(height)}; - for (int i = 0; i < state->entity_count; i++) { - Rectangle mouse_select_area = { - state->knights[i].position.x + knight_colrect_select.x, - state->knights[i].position.y + knight_colrect_select.y, - knight_colrect_select.width, - knight_colrect_select.height, - }; - state->knights[i].selected = - CheckCollisionRecs(rect, mouse_select_area); - } - } else { - // TODO: This kind of sucks that we're doing all the math here to calculate - // the position of the collider, we need a helper that calculates origin offset - int k_idx = -1; - for (int i = 0; i < state->entity_count; i++) { - Rectangle mouse_select_area = { - state->knights[i].position.x + knight_colrect_select.x, - state->knights[i].position.y + knight_colrect_select.y, - knight_colrect_select.width, - knight_colrect_select.height, - }; - if (CheckCollisionPointRec(current_pos, mouse_select_area)) { - k_idx = i; - } - state->knights[i].selected = false; - } - if (k_idx != -1) { - state->knights[k_idx].selected = true; - } - } state->selection_mouse_start_pos = optional{}; + state->drag_camera_start_pos = optional{}; } if (IsMouseButtonPressed(1)) { @@ -134,26 +100,16 @@ void Input(GameState *state) { } } - f32 cam_speed = 5.0; - if (IsKeyDown(KEY_RIGHT)) { - state->camera.target.x += cam_speed; + if (IsKeyPressed(KEY_SPACE)) { + for (int i = 0; i < state->entity_count; i++) { + auto& knight = state->knights[i]; + if (knight.selected && knight.state != KnightState::ATTACKING) { + knight.ordered_to_move = false; + knight.state = KnightState::ATTACKING; + PlayAnimation(ANIM_KNIGHT_ATTACK_SIDE1, knight_anims, &state->anim_playbacks[i]); + } + } } - if (IsKeyDown(KEY_LEFT)) { - state->camera.target.x -= cam_speed; - } - if (IsKeyDown(KEY_UP)) { - state->camera.target.y -= cam_speed; - } - if (IsKeyDown(KEY_DOWN)) { - state->camera.target.y += cam_speed; - } - // if (IsKeyPressed(KEY_SPACE) && state->selected_knight != -1) { - // int k_idx = game->selected_knight; - // if (game->knights[k_idx].state != KNIGHT_ATTACKING) { - // game->knights[k_idx].state = KNIGHT_ATTACKING; - // PlayAnimation(ANIM_KNIGHT_ATTACK_SIDE1, knight_anims, &game->anim_playbacks[k_idx]); - // } - // } if (IsKeyPressed(KEY_F1)) { global_debug_mode = !global_debug_mode; } @@ -169,24 +125,25 @@ void Update(GameState *state) { Point start_pos = state->selection_mouse_start_pos.value(); Point current_pos = GetScreenToWorld2D(GetMousePosition(), state->camera); - if (Vector2DistanceSqr(current_pos, start_pos) >= 100.0f) { - f32 width = current_pos.x - start_pos.x; - f32 height = current_pos.y - start_pos.y; - f32 x = width >= 0.0f ? start_pos.x : current_pos.x; - f32 y = height >= 0.0f ? start_pos.y : current_pos.y; - Rectangle rect = {x, y, fabs(width), fabs(height)}; - for (int i = 0; i < state->entity_count; i++) { - Rectangle mouse_select_area = { - state->knights[i].position.x + knight_colrect_select.x, - state->knights[i].position.y + knight_colrect_select.y, - knight_colrect_select.width, - knight_colrect_select.height, - }; - state->knights[i].selected = - CheckCollisionRecs(rect, mouse_select_area); - } + f32 width = current_pos.x - start_pos.x; + f32 height = current_pos.y - start_pos.y; + f32 x = width >= 0.0f ? start_pos.x : current_pos.x; + f32 y = height >= 0.0f ? start_pos.y : current_pos.y; + Rectangle rect = {x, y, fabs(width), fabs(height)}; + for (int i = 0; i < state->entity_count; i++) { + Rectangle mouse_select_area = { + state->knights[i].position.x + knight_colrect_select.x, + state->knights[i].position.y + knight_colrect_select.y, + knight_colrect_select.width, + knight_colrect_select.height, + }; + state->knights[i].selected = CheckCollisionRecs(rect, mouse_select_area); } } + if (state->drag_camera_start_pos.has_value()) { + Point start_pos = state->drag_camera_start_pos.value(); + state->camera.target = state->camera_target_start_pos + (start_pos - GetMousePosition()); + } float dt = 0.33; const float cam_move_speed = 1050.0f * dt; // TODO: This was moved out of Input @@ -234,6 +191,7 @@ void Update(GameState *state) { } } if (i == 0) continue; + // TODO: This is likely getting called every frame, probably best to have a dirty flag to detect movement // Sort the entities by y position using Insertion Sort int j = i; while (j > 0 && state->knights[j].position.y < state->knights[j - 1].position.y) { @@ -305,7 +263,6 @@ void Draw2D(GameState *state) { knight_colrect_select.width, knight_colrect_select.height, }; - // Color color = game->selected_knight == NULL ? RED : GREEN; DrawRectangleLinesEx(knight_col_area, 2.0f, GREEN); } } diff --git a/game.h b/game.h index f1ee791..632f410 100644 --- a/game.h +++ b/game.h @@ -2,6 +2,7 @@ #include "raylib.h" #include "lib.h" #include "sprites.h" +#include #include @@ -17,7 +18,7 @@ using namespace std; bool global_debug_mode = false; -enum class KnightState : u8 { +enum class KnightState { IDLE = 0, RUNNING = 1, ATTACKING = 2, @@ -55,13 +56,16 @@ struct GameState { optional selected_point; Knight *knights; SpriteAnimationPlayback *anim_playbacks; - Knight *selected_knights; optional selection_mouse_start_pos; int entity_count; Assets assets; + optional drag_camera_start_pos; + + Point camera_target_start_pos; + ~GameState() { free(knights); free(anim_playbacks);