summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlec Goncharow <alec@goncharow.dev>2024-02-11 23:00:27 -0500
committerAlec Goncharow <alec@goncharow.dev>2024-02-11 23:00:27 -0500
commit0085d899650006679365a1d68dcb43650c297486 (patch)
tree5b5f5c292d8dd4bc76f98e2d560fe26ba654f69e /src
parentdb229ae38f04e8a6b9759c1e5208af75b81344aa (diff)
some cheeky animation action
Diffstat (limited to 'src')
-rw-r--r--src/Animation.zig41
-rw-r--r--src/context.zig14
-rw-r--r--src/root.zig51
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();