add wood position lerping

This commit is contained in:
Rokas Puzonas 2026-07-19 03:18:06 +03:00
parent b356038f1f
commit df7bbf087e
2 changed files with 80 additions and 11 deletions

View File

@ -166,6 +166,7 @@ const AnimationDirection = enum {
const Entity = struct { const Entity = struct {
type: Type = .nil, type: Type = .nil,
flags: Flags = .{}, flags: Flags = .{},
seed: u64 = 0,
target_entity: ?EntityId = null, target_entity: ?EntityId = null,
targeted_by_entity: ?EntityId = null, targeted_by_entity: ?EntityId = null,
@ -180,7 +181,6 @@ const Entity = struct {
tree_health: u32 = 0, tree_health: u32 = 0,
tree_max_health: u32 = 0, tree_max_health: u32 = 0,
tree_seed: u64 = 0,
station_spawn_tree_cooldown: Nanoseconds = 0, station_spawn_tree_cooldown: Nanoseconds = 0,
station_owned_tree: ?EntityId = null, station_owned_tree: ?EntityId = null,
@ -189,7 +189,9 @@ const Entity = struct {
wood_burning: bool = false, wood_burning: bool = false,
wood_health: f32 = 0, wood_health: f32 = 0,
wood_max_health: f32 = 0, wood_max_health: f32 = 0,
wood_prev_carried: ?EntityId = null,
wood_next_carried: ?EntityId = null, wood_next_carried: ?EntityId = null,
wood_visual_pos: Vec2 = .init(0, 0),
pos: Vec2 = .init(0, 0), pos: Vec2 = .init(0, 0),
vel: Vec2 = .init(0, 0), vel: Vec2 = .init(0, 0),
@ -716,7 +718,7 @@ fn spawnTree(self: *App, station_id: EntityId) void {
.type = .tree, .type = .tree,
.tree_health = health, .tree_health = health,
.tree_max_health = health, .tree_max_health = health,
.tree_seed = rng.int(u64), .seed = rng.int(u64),
.pos = station.pos .pos = station.pos
})) |id| { })) |id| {
@ -728,8 +730,11 @@ fn destroyTree(self: *App, tree_id: EntityId) void {
const tree = self.entities.get(tree_id) orelse return; const tree = self.entities.get(tree_id) orelse return;
assert(tree.type == .tree); assert(tree.type == .tree);
var rng = self.prng.random();
for (0..self.upgrades.tree_wood_amount) |_| { for (0..self.upgrades.tree_wood_amount) |_| {
self.spawnWood(tree.pos); const offset = (rng.float(f32)-0.5)*2 * 30;
self.spawnWood(tree.pos.add(.init(offset, 0)));
} }
self.entities.removeAssumeExists(tree_id); self.entities.removeAssumeExists(tree_id);
@ -738,11 +743,15 @@ fn destroyTree(self: *App, tree_id: EntityId) void {
fn spawnWood(self: *App, pos: Vec2) void { fn spawnWood(self: *App, pos: Vec2) void {
const health = self.upgrades.tree_wood_health; const health = self.upgrades.tree_wood_health;
const rng = self.prng.random();
_ = self.spawnEntity(Entity{ _ = self.spawnEntity(Entity{
.type = .wood, .type = .wood,
.pos = pos, .pos = pos,
.seed = rng.int(u64),
.wood_health = health, .wood_health = health,
.wood_max_health = health .wood_max_health = health,
.wood_visual_pos = pos,
}); });
} }
@ -917,10 +926,16 @@ fn minionPushWood(self: *App, minion_id: EntityId, wood_id: EntityId) void {
const minion = self.entities.get(minion_id) orelse return; const minion = self.entities.get(minion_id) orelse return;
const wood = self.entities.get(wood_id) orelse return; const wood = self.entities.get(wood_id) orelse return;
wood.wood_carried_by = minion_id; if (minion.minion_carried_wood_head) |head_id| {
if (self.entities.get(head_id)) |head| {
head.wood_prev_carried = wood_id;
}
}
wood.wood_next_carried = minion.minion_carried_wood_head; wood.wood_next_carried = minion.minion_carried_wood_head;
wood.flags.has_kinematics = false;
minion.minion_carried_wood_head = wood_id; minion.minion_carried_wood_head = wood_id;
wood.wood_carried_by = minion_id;
wood.flags.has_kinematics = false;
minion.minion_carried_wood_len += 1; minion.minion_carried_wood_len += 1;
} }
@ -931,6 +946,11 @@ fn minionPopWood(self: *App, minion_id: EntityId) ?EntityId {
minion.minion_carried_wood_len -= 1; minion.minion_carried_wood_len -= 1;
if (self.entities.get(wood_id)) |wood| { if (self.entities.get(wood_id)) |wood| {
minion.minion_carried_wood_head = wood.wood_next_carried; minion.minion_carried_wood_head = wood.wood_next_carried;
if (minion.minion_carried_wood_head) |head_id| {
if (self.entities.get(head_id)) |head| {
head.wood_prev_carried = null;
}
}
wood.wood_carried_by = null; wood.wood_carried_by = null;
wood.wood_next_carried = null; wood.wood_next_carried = null;
return wood_id; return wood_id;
@ -1427,6 +1447,23 @@ fn showDebug(self: *App, plt: Platform.Frame) !void {
ImGUI.separator(); ImGUI.separator();
self.showDebugShopItems("Fire", self.shop.fire_upgrades); self.showDebugShopItems("Fire", self.shop.fire_upgrades);
} }
if (ImGUI.beginTabItem("Wood")) {
defer ImGUI.endTabItem();
var minion_iter = self.initEntityIteratorByType(.minion);
while (minion_iter.next()) |minion_id| {
const minion = self.entities.getAssumeExists(minion_id);
ImGUI.text("{f}, wood_head: {?f}", .{minion_id, minion.minion_carried_wood_head});
}
ImGUI.separator();
var wood_iter = self.initEntityIteratorByType(.wood);
while (wood_iter.next()) |wood_id| {
const wood = self.entities.getAssumeExists(wood_id);
ImGUI.text("{f}, carried_by: {?f}, next: {?f}", .{wood_id, wood.wood_carried_by, wood.wood_next_carried});
}
}
} }
} }
@ -1775,8 +1812,21 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
if (wood.wood_carried_by) |minion_id| { if (wood.wood_carried_by) |minion_id| {
const minion = self.entities.getAssumeExists(minion_id); const minion = self.entities.getAssumeExists(minion_id);
wood.pos = minion.pos.add(.init(0, -50));
if (wood.wood_prev_carried) |prev_wood_id| {
const follow_distance = 20;
const next_wood = self.entities.getAssumeExists(prev_wood_id);
var dir = next_wood.pos.sub(wood.pos);
if (dir.length() > follow_distance) {
wood.pos = wood.pos.add(dir.normalized().multiplyScalar(dir.length() - follow_distance));
} }
} else {
wood.pos = minion.pos.add(.init(0, -60));
}
}
wood.wood_visual_pos.x = std.math.lerp(wood.wood_visual_pos.x, wood.pos.x, 0.03);
wood.wood_visual_pos.y = std.math.lerp(wood.wood_visual_pos.y, wood.pos.y, 0.03);
} }
} }
@ -1799,7 +1849,7 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
while (tree_iter.next()) |id| { while (tree_iter.next()) |id| {
const e = self.entities.getAssumeExists(id); const e = self.entities.getAssumeExists(id);
self.drawTree(e.tree_seed, e.pos); self.drawTree(e.seed, e.pos);
const progress = @as(f32, @floatFromInt(e.tree_health)) / @as(f32, @floatFromInt(e.tree_max_health)); const progress = @as(f32, @floatFromInt(e.tree_health)) / @as(f32, @floatFromInt(e.tree_max_health));
drawProgressBar(progress, e.pos.add(.init(0, 20)), .init(40, 10), .rgb(0, 100, 20)); drawProgressBar(progress, e.pos.add(.init(0, 20)), .init(40, 10), .rgb(0, 100, 20));
@ -1915,7 +1965,26 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
while (wood_iter.next()) |id| { while (wood_iter.next()) |id| {
const wood = self.entities.getAssumeExists(id); const wood = self.entities.getAssumeExists(id);
Gfx.drawRectangle(wood.pos.sub(.init(10, 10)), .init(20, 20), .rgb(100, 100, 20)); var prng = Prng.init(wood.seed);
const rng = prng.random();
const sprites = &[_]Gfx.Sprite.Id{
self.terrain_sheet.get(125, 41),
self.terrain_sheet.get(125, 40),
self.terrain_sheet.get(125, 39),
};
var rect = Gfx.Quad.initRect(
terrain_tile_size.divideScalar(-2),
terrain_tile_size
);
rect.applyRotate(rng.float(f32) * std.math.pi * 2, .init(0, 0));
rect.applyOffset(wood.wood_visual_pos);
Gfx.drawSpriteQuad(
sprites[rng.uintLessThan(u32, sprites.len)],
rect,
.white
);
} }
} }

View File

@ -2350,13 +2350,13 @@ pub const Quad = struct {
}; };
} }
pub fn rotate(self: *Quad, rad: f32, origin: Vec2) void { pub fn applyRotate(self: *Quad, rad: f32, origin: Vec2) void {
for (&self.positions) |*pos| { for (&self.positions) |*pos| {
pos.* = pos.sub(origin).rotate(rad).add(origin); pos.* = pos.sub(origin).rotate(rad).add(origin);
} }
} }
pub fn offset(self: *Quad, vec2: Vec2) void { pub fn applyOffset(self: *Quad, vec2: Vec2) void {
for (&self.positions) |*pos| { for (&self.positions) |*pos| {
pos.* = pos.add(vec2); pos.* = pos.add(vec2);
} }