From 0e2ca5332037d1fb14b4bd29e38d410bc3cc3f98 Mon Sep 17 00:00:00 2001 From: Brandon Skewes Date: Sun, 7 Dec 2025 22:28:16 +1100 Subject: [PATCH] added idle for all directions and hoe --- src/entities/player.zig | 137 +++++++++++++++++++++++++++++++++++----- src/main.zig | 19 ++++-- src/maps/basemap.zig | 42 ++++++++++++ src/maps/data.zig | 1 + 4 files changed, 179 insertions(+), 20 deletions(-) create mode 100644 src/maps/basemap.zig create mode 100644 src/maps/data.zig diff --git a/src/entities/player.zig b/src/entities/player.zig index 445c172..67d951a 100644 --- a/src/entities/player.zig +++ b/src/entities/player.zig @@ -2,9 +2,26 @@ const rl = @import("raylib"); pub const premium_character_path = "/Users/ratludu/Downloads/Sprout Lands - Sprites - premium pack/Characters/Premium Charakter Spritesheet.png"; -const state = enum { idle, hoeForward, walkLeft, walkRight, walkUp, walkDown }; -const direction = enum { left, right, up, down }; -const animations = enum { repeating, oneshot }; +const state = enum { + idle, + hoe, + walkLeft, + walkRight, + walkUp, + walkDown, +}; + +const direction = enum { + left, + right, + up, + down, +}; + +const animations = enum { + repeating, + oneshot, +}; pub const Animation = struct { type: animations, @@ -64,12 +81,14 @@ pub const Animation = struct { pub const Player = struct { sourceRect: rl.Rectangle, + destRect: rl.Rectangle, playerSprite: rl.Texture2D, playerState: state, playerDirection: direction, anim: Animation, + cam: rl.Camera2D, - pub fn init() rl.RaylibError!Player { + pub fn init(screenWidth: i32, screenHeight: i32) rl.RaylibError!Player { const player_sprite = try rl.loadTexture(premium_character_path); var source_rect = rl.Rectangle.init(0, 0, 48, 48); _ = &source_rect; @@ -77,15 +96,32 @@ pub const Player = struct { var anim = Animation.init(.repeating, 0, 7, 0); _ = &anim; + var dest_rect = rl.Rectangle.init(@floatFromInt(@divFloor(screenWidth, 2) - 100 / 2), @floatFromInt(@divFloor(screenHeight, 2) - 100 / 2), 100, 100); + _ = &dest_rect; + + var cam = rl.Camera2D{ + .offset = .{ .x = @as(f32, @floatFromInt(@divFloor(screenWidth, 2))) - dest_rect.width, .y = @as(f32, @floatFromInt(@divFloor(screenHeight, 2))) - dest_rect.height }, + .target = .{ .x = dest_rect.x - dest_rect.width / 2.0, .y = dest_rect.y - dest_rect.height / 2.0 }, + .rotation = 0.0, + .zoom = 1.0, + }; + _ = &cam; + return Player{ .sourceRect = source_rect, .playerSprite = player_sprite, .playerState = state.idle, .playerDirection = direction.down, .anim = anim, + .destRect = dest_rect, + .cam = cam, }; } + pub fn updateCam(self: *Player) void { + self.cam.target = .{ .x = self.destRect.x - self.destRect.width / 2.0, .y = self.destRect.y - self.destRect.height / 2.0 }; + } + pub fn update(self: *Player, new_state: state) void { if (new_state == self.playerState) { return; @@ -98,44 +134,100 @@ pub const Player = struct { idleAnimation(self); break :blk; }, - .hoeForward => blk: { - hoeForward(self); + .hoe => blk: { + hoe(self); break :blk; }, .walkLeft => blk: { + self.playerDirection = .left; walkLeft(self); break :blk; }, .walkRight => blk: { + self.playerDirection = .right; walkRight(self); break :blk; }, .walkUp => blk: { + self.playerDirection = .up; walkUp(self); break :blk; }, .walkDown => blk: { + self.playerDirection = .down; walkDown(self); break :blk; }, } } - pub fn animate(self: *Player, screenWidth: i32, screenHeight: i32) void { - rl.drawTexturePro(self.playerSprite, self.anim.animation_frame(8, 48), .{ .x = @floatFromInt(@divFloor(screenWidth, 2) - 100 / 2), .y = @floatFromInt(@divFloor(screenHeight, 2) - 100 / 2), .width = 100, .height = 100 }, .{ .x = 0.0, .y = 0.0 }, 0.0, .white); + pub fn animate(self: *Player) void { + rl.drawTexturePro(self.playerSprite, self.anim.animation_frame(8, 48), self.destRect, .{ .x = 0.0, .y = 0.0 }, 0.0, .white); } pub fn idleAnimation(self: *Player) void { - var anim = Animation.init(.repeating, 0, 7, 0); - _ = &anim; - self.anim = anim; + switch (self.playerDirection) { + .left => blk: { + const first = 8 * 3; + var anim = Animation.init(.repeating, first, first + 7, first); + _ = &anim; + self.anim = anim; + break :blk; + }, + .right => blk: { + const first = 8 * 2; + var anim = Animation.init(.repeating, first, first + 7, first); + _ = &anim; + self.anim = anim; + break :blk; + }, + .up => blk: { + const first = 8 * 1; + var anim = Animation.init(.repeating, first, first + 7, first); + _ = &anim; + self.anim = anim; + break :blk; + }, + .down => blk: { + var anim = Animation.init(.repeating, 0, 7, 0); + _ = &anim; + self.anim = anim; + break :blk; + }, + } } - pub fn hoeForward(self: *Player) void { - const first = 12 * 8; - var anim = Animation.init(.oneshot, first, first + 7, first); - _ = &anim; - self.anim = anim; + pub fn hoe(self: *Player) void { + switch (self.playerDirection) { + .left => blk: { + const first = 8 * 15; + var anim = Animation.init(.oneshot, first, first + 7, first); + _ = &anim; + self.anim = anim; + break :blk; + }, + .right => blk: { + const first = 8 * 14; + var anim = Animation.init(.oneshot, first, first + 7, first); + _ = &anim; + self.anim = anim; + break :blk; + }, + .up => blk: { + const first = 13 * 8; + var anim = Animation.init(.oneshot, first, first + 7, first); + _ = &anim; + self.anim = anim; + break :blk; + }, + .down => blk: { + const first = 12 * 8; + var anim = Animation.init(.oneshot, first, first + 7, first); + _ = &anim; + self.anim = anim; + break :blk; + }, + } } pub fn walkLeft(self: *Player) void { @@ -169,39 +261,52 @@ pub const Player = struct { pub fn walkingUpdate(self: *Player) void { if (rl.isKeyDown(rl.KeyboardKey.a)) { self.update(.walkLeft); + self.destRect.x -= 2; + return; } if (rl.isKeyDown(rl.KeyboardKey.d)) { self.update(.walkRight); + self.destRect.x += 2; + return; } if (rl.isKeyDown(rl.KeyboardKey.w)) { self.update(.walkUp); + self.destRect.y -= 2; + return; } if (rl.isKeyDown(rl.KeyboardKey.s)) { self.update(.walkDown); + self.destRect.y += 2; + return; } } pub fn resetToIdle(self: *Player) void { if (self.anim.current == self.anim.last and self.anim.type == .oneshot) { self.update(.idle); + return; } if (!rl.isKeyDown(rl.KeyboardKey.a) and self.playerState == .walkLeft) { self.update(.idle); + return; } if (!rl.isKeyDown(rl.KeyboardKey.d) and self.playerState == .walkRight) { self.update(.idle); + return; } if (!rl.isKeyDown(rl.KeyboardKey.s) and self.playerState == .walkDown) { self.update(.idle); + return; } if (!rl.isKeyDown(rl.KeyboardKey.w) and self.playerState == .walkUp) { self.update(.idle); + return; } } }; diff --git a/src/main.zig b/src/main.zig index c52b41a..b1cb0f7 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2,6 +2,7 @@ const std = @import("std"); const Hidden_Leaf_Island = @import("Hidden_Leaf_Island"); const rl = @import("raylib"); const Entities = @import("entities/player.zig"); +const Map = @import("maps/basemap.zig"); fn toggleFullScreen(windowWidth: i32, windowHeight: i32) void { if (!rl.isWindowFullscreen()) { @@ -25,9 +26,13 @@ pub fn main() anyerror!void { rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- - var player = try Entities.Player.init(); + var player = try Entities.Player.init(screenWidth, screenHeight); defer rl.unloadTexture(player.playerSprite); + var basemap = try Map.BaseMap.init(); + defer rl.unloadTexture(basemap.grass); + defer rl.unloadTexture(basemap.soil); + // Main game loop while (!rl.windowShouldClose()) { // Detect window close button or ESC key // Full screen toggle @@ -39,9 +44,10 @@ pub fn main() anyerror!void { player.resetToIdle(); if (rl.isKeyDown(rl.KeyboardKey.e)) { - player.update(.hoeForward); + player.update(.hoe); } player.walkingUpdate(); + player.updateCam(); player.anim.animationUpdate(); //---------------------------------------------------------------------------------- @@ -53,9 +59,14 @@ pub fn main() anyerror!void { rl.beginDrawing(); defer rl.endDrawing(); - player.animate(screenWidth, screenHeight); + rl.beginMode2D(player.cam); + defer rl.endMode2D(); - rl.clearBackground(.sky_blue); + basemap.draw(); + + player.animate(); + + rl.clearBackground(.white); //---------------------------------------------------------------------------------- } diff --git a/src/maps/basemap.zig b/src/maps/basemap.zig new file mode 100644 index 0000000..2baf937 --- /dev/null +++ b/src/maps/basemap.zig @@ -0,0 +1,42 @@ +const rl = @import("raylib"); +const data = @import("data.zig"); + +pub const grass_tiles = "/users/ratludu/Downloads/Sprout Lands - Sprites - premium pack/Tilesets/ground tiles/New tiles/Grass_tiles_v2.png"; +pub const soil_tiles = "/users/ratludu/Downloads/Sprout Lands - Sprites - premium pack/Tilesets/ground tiles/New tiles/Soil_Ground_HiIls_Tiles.png"; + +pub const BaseMap = struct { + sourceRectange: rl.Rectangle, + destRectange: rl.Rectangle, + grass: rl.Texture2D, + soil: rl.Texture2D, + map: [30 * 30]u32, + + pub fn init() !BaseMap { + const grass = try rl.loadTexture(grass_tiles); + const soil = try rl.loadTexture(soil_tiles); + var source_rect = rl.Rectangle.init(0, 16 * 6, 16, 16); + _ = &source_rect; + var dest_rectangle = rl.Rectangle.init(0, 0, 32, 32); + _ = &dest_rectangle; + + return BaseMap{ + .sourceRectange = source_rect, + .destRectange = dest_rectangle, + .grass = grass, + .soil = soil, + .map = data.test_map, + }; + } + pub fn draw(self: *BaseMap) void { + for (self.map, 0..) |tile, i| { + const new_i: i32 = @intCast(i); + self.destRectange.x = self.destRectange.width * @as(f32, @floatFromInt(@mod(new_i, 30))); + self.destRectange.y = self.destRectange.height * @as(f32, @floatFromInt(@divFloor(new_i, 30))); + if (tile == 67) { + rl.drawTexturePro(self.grass, self.sourceRectange, self.destRectange, rl.Vector2{ .x = self.destRectange.width, .y = self.destRectange.height }, 0.0, .white); + } else { + rl.drawTexturePro(self.soil, self.sourceRectange, self.destRectange, rl.Vector2{ .x = self.destRectange.width, .y = self.destRectange.height }, 0.0, .white); + } + } + } +}; diff --git a/src/maps/data.zig b/src/maps/data.zig new file mode 100644 index 0000000..c5e6656 --- /dev/null +++ b/src/maps/data.zig @@ -0,0 +1 @@ +pub const test_map = [_]u32{ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 144, 144, 144, 144, 144, 67, 67, 67, 67, 67, 67, 67, 67, 67 };