diff options
| author | Alec Goncharow <alec@goncharow.dev> | 2024-02-11 23:00:27 -0500 |
|---|---|---|
| committer | Alec Goncharow <alec@goncharow.dev> | 2024-02-11 23:00:27 -0500 |
| commit | 0085d899650006679365a1d68dcb43650c297486 (patch) | |
| tree | 5b5f5c292d8dd4bc76f98e2d560fe26ba654f69e /src | |
| parent | db229ae38f04e8a6b9759c1e5208af75b81344aa (diff) | |
some cheeky animation action
Diffstat (limited to 'src')
| -rw-r--r-- | src/Animation.zig | 41 | ||||
| -rw-r--r-- | src/context.zig | 14 | ||||
| -rw-r--r-- | src/root.zig | 51 |
3 files changed, 94 insertions, 12 deletions
diff --git a/src/Animation.zig b/src/Animation.zig new file mode 100644 index 0000000..5201193 --- /dev/null +++ b/src/Animation.zig @@ -0,0 +1,41 @@ +const root = @import("root.zig"); +const rl = @cImport(@cInclude("raylib.h")); +const rlm = @cImport(@cInclude("raymath.h")); + +const Animation = @This(); + +world_from: rl.Vector2, +world_to: rl.Vector2, +duration: u32, // TODO frame independent durations +tick: u32, +active: bool, + +pub fn init() Animation { + return Animation{ + .world_from = .{ .x = 0.0, .y = 0.0 }, + .world_to = .{ .x = 0.0, .y = 0.0 }, + .duration = 60, // TODO speed based duration + .tick = 0, + .active = false, + }; +} + +pub fn next(self: *Animation) rl.Vector2 { + if (self.tick >= self.duration) { + self.active = false; + return self.world_to; + } + + self.tick += 1; + return self.lerp(); +} + +inline fn lerp(self: *Animation) rl.Vector2 { + const t: f32 = @as(f32, @floatFromInt(self.tick)) / @as(f32, @floatFromInt(self.duration)); + const v1 = self.world_from; + const v2 = self.world_to; + return .{ + .x = v1.x + (t * (v2.x - v1.x)), + .y = v1.y + (t * (v2.y - v1.y)), + }; +} diff --git a/src/context.zig b/src/context.zig index f3e88f2..0bffbd4 100644 --- a/src/context.zig +++ b/src/context.zig @@ -1,6 +1,7 @@ const std = @import("std"); const rl = @cImport(@cInclude("raylib.h")); const root = @import("root.zig"); +const Animation = @import("Animation.zig"); pub var camera: rl.Camera2D = undefined; pub var grid: []root.MyRect = undefined; @@ -9,7 +10,6 @@ pub const Grid = struct { buffer: std.MultiArrayList(root.Hex), cursor: usize, size: usize, - const Self = @This(); const GridError = error{ OutOfBounds, @@ -30,14 +30,14 @@ pub const Grid = struct { } // should only be used when standing up the buffer, afterwards should use q, r indexing - pub fn initPush(self: *Self, hex: root.Hex) GridError!void { + pub fn initPush(self: *Grid, hex: root.Hex) GridError!void { if (self.cursor >= self.size * 2) { return GridError.OutOfBounds; } self.buffer.insertAssumeCapacity(self.cursor, hex); } - pub fn set(self: *Self, hex: root.Hex) GridError!void { + pub fn set(self: *Grid, hex: root.Hex) GridError!void { const idx = hex.qr[1] * self.size + hex.qr[0]; if (idx >= self.size * 2) { return GridError.OutOfBounds; @@ -50,5 +50,13 @@ pub var hex_grid: Grid = undefined; pub var hovered_coords: root.HexCoord = root.HexCoord{ .q = 0, .r = 0 }; pub var hovered_handle: ?usize = null; +pub const Dude = struct { + world_coords: rl.Vector2, + hex_coords: root.HexCoord, + target_coords: root.HexCoord, + animation: Animation, +}; +pub var main_dude: Dude = undefined; + var Gpa = std.heap.GeneralPurposeAllocator(.{}){}; pub var gpa: std.mem.Allocator = Gpa.allocator(); diff --git a/src/root.zig b/src/root.zig index 286c0c2..8312f5d 100644 --- a/src/root.zig +++ b/src/root.zig @@ -1,8 +1,11 @@ const std = @import("std"); const rl = @cImport(@cInclude("raylib.h")); const context = @import("context.zig"); +const Animation = @import("Animation.zig"); -const grid_size: usize = 21; +const camera_move_speed: f32 = 10.0; + +const grid_size: usize = 45; const grid_central_row = grid_size / 2 + 1; pub const MyRect = struct { @@ -10,6 +13,8 @@ pub const MyRect = struct { color: rl.Color, }; +const dude_radius: f32 = 50.0; +var dude_rotation: f32 = 45.0; const hex_radius: f32 = 100.0; const hex_rotation = 30.0; @@ -24,6 +29,10 @@ pub const HexCoord = struct { return self.r / grid_size + self.q % grid_size; } + pub inline fn toWorld(self: HexCoord) rl.Vector2 { + return qrToWorld(self.q, self.r); + } + pub inline fn qrToWorld(q: i32, r: i32) rl.Vector2 { return .{ .x = hex_radius * (@sqrt(3.0) * @as(f32, @floatFromInt(q)) + @sqrt(3.0) / 2.0 * @as(f32, @floatFromInt(r))), @@ -73,6 +82,13 @@ pub fn setup() !void { const target = HexCoord.qrToWorld(grid_central_row, grid_central_row); context.camera = rl.Camera2D{ .target = target, .offset = rl.Vector2{ .x = 0, .y = 0 }, .rotation = 0, .zoom = 1 }; context.hex_grid = try context.Grid.init(context.gpa, grid_size); + context.main_dude = .{ + .world_coords = .{ .x = 0.0, .y = 0.0 }, + .hex_coords = .{ .q = (grid_size / 2) + 1, .r = (grid_size / 2) + 1 }, + .target_coords = .{ .q = (grid_size / 2) + 1, .r = (grid_size / 2) + 1 }, + .animation = Animation.init(), + }; + context.main_dude.world_coords = HexCoord.qrToWorld(@intCast(context.main_dude.hex_coords.q), @intCast(context.main_dude.hex_coords.r)); // TODO think what it means to populate a hex grid for (0..grid_size) |_| { @@ -86,33 +102,47 @@ pub fn setup() !void { } pub fn update() !void { - //---------------------------------------------------------------------------------- - const mouse_pos = rl.GetMousePosition(); const mouse_world_pos = rl.GetScreenToWorld2D(mouse_pos, context.camera); + var main_dude = &context.main_dude; context.hovered_coords = HexCoord.worldToQr(mouse_world_pos); const zoom_scale = context.camera.zoom; if (rl.IsKeyDown(rl.KEY_D)) { - context.camera.target.x += 2 / zoom_scale; + context.camera.target.x += camera_move_speed / zoom_scale; } if (rl.IsKeyDown(rl.KEY_A)) { - context.camera.target.x -= 2 / zoom_scale; + context.camera.target.x -= camera_move_speed / zoom_scale; } if (rl.IsKeyDown(rl.KEY_W)) { - context.camera.target.y -= 2 / zoom_scale; + context.camera.target.y -= camera_move_speed / zoom_scale; } if (rl.IsKeyDown(rl.KEY_S)) { - context.camera.target.y += 2 / zoom_scale; + context.camera.target.y += camera_move_speed / zoom_scale; } - if (rl.IsMouseButtonDown(rl.MOUSE_BUTTON_MIDDLE)) { + // TODO FIXME laptop dev doesnt allow middle mouse and mouse move to happen + // at same time and im not yak shavin this + if (rl.IsMouseButtonDown(rl.MOUSE_BUTTON_RIGHT)) { const delta = rl.GetMouseDelta(); context.camera.target.x -= delta.x / zoom_scale; context.camera.target.y -= delta.y / zoom_scale; } + if (main_dude.animation.active) { + main_dude.world_coords = main_dude.animation.next(); + main_dude.hex_coords = main_dude.target_coords; + } + + if (!main_dude.animation.active and rl.IsMouseButtonDown(rl.MOUSE_BUTTON_LEFT)) { + main_dude.animation.world_to = context.hovered_coords.toWorld(); + main_dude.animation.world_from = main_dude.hex_coords.toWorld(); + main_dude.animation.active = true; + main_dude.animation.tick = 0; + main_dude.target_coords = context.hovered_coords; + } + const wm = rl.GetMouseWheelMove(); if (wm != 0.0) { context.camera.zoom += wm * 0.05; @@ -150,9 +180,12 @@ pub fn draw() !void { } } - const center = HexCoord.qrToWorld(@intCast(context.hovered_coords.q), @intCast(context.hovered_coords.r)); + const center = context.hovered_coords.toWorld(); rl.DrawPolyLines(center, 6, hex_radius, hex_rotation, rl.WHITE); + const dude_center = context.main_dude.world_coords; + rl.DrawPoly(dude_center, 4, dude_radius, dude_rotation, rl.RED); + rl.EndMode2D(); rl.EndDrawing(); |
