added idle for all directions and hoe

This commit is contained in:
Brandon Skewes
2025-12-07 22:28:16 +11:00
parent 3b59929a34
commit 0e2ca53320
4 changed files with 179 additions and 20 deletions

View File

@@ -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;
}
}
};

View File

@@ -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);
//----------------------------------------------------------------------------------
}

42
src/maps/basemap.zig Normal file
View File

@@ -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);
}
}
}
};

1
src/maps/data.zig Normal file
View File

@@ -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 };