Compare commits

..

10 Commits

Author SHA1 Message Date
9320b46f68 add particles 2026-07-19 12:44:07 +03:00
ae088c5a0e optimize minion iteration 2026-07-19 10:58:24 +03:00
e4307fb543 implement upgrades 2026-07-19 10:48:36 +03:00
3c61d2164d add fire animation 2026-07-19 06:50:20 +03:00
19e37f507d add gradient at bottom 2026-07-19 03:55:21 +03:00
096a082ac7 tree lerped health bar 2026-07-19 03:42:07 +03:00
df7bbf087e add wood position lerping 2026-07-19 03:18:06 +03:00
b356038f1f render trees 2026-07-19 02:19:04 +03:00
892fbb38be add terrain 2026-07-18 23:50:32 +03:00
f94ae22214 limit camera offset 2026-07-18 20:40:34 +03:00
11 changed files with 1190 additions and 281 deletions

BIN
assets/fire/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
assets/fire/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
assets/fire/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
assets/fire/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
assets/fire/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -11,11 +11,11 @@ pub fn build(b: *std.Build) !void {
"Prototype_Character/Default/idle.png", "Prototype_Character/Default/idle.png",
"Prototype_Character/Default/walk.png", "Prototype_Character/Default/walk.png",
"Prototype_Character/Default/death.png", "Prototype_Character/Default/death.png",
"font/pixeloid/PixeloidSans.ttf" "font/pixeloid/PixeloidSans.ttf",
// "sokoban/sokoban_tilesheet.png", "tranquil_tunnels_transparent.png",
// "roboto-font/Roboto-Regular.ttf", "fire/1.png",
// "tiled/map.tmx", "fire/2.png",
// "tiled/tileset.tsx" "fire/5.png",
}; };
const asset_dir_realpath = try b.build_root.join(b.graph.arena, &.{ assets_dir }); const asset_dir_realpath = try b.build_root.join(b.graph.arena, &.{ assets_dir });

File diff suppressed because it is too large Load Diff

View File

@ -41,3 +41,12 @@ pub fn rgb_hex(text: []const u8) ?Color {
const b = std.fmt.parseInt(u8, text[5..7], 16) catch return null; const b = std.fmt.parseInt(u8, text[5..7], 16) catch return null;
return rgb(r, g, b); return rgb(r, g, b);
} }
pub fn lerp(self: Color, other: Color, t: f32) Color {
return Color{
.r = std.math.lerp(self.r, other.r, t),
.g = std.math.lerp(self.g, other.g, t),
.b = std.math.lerp(self.b, other.b, t),
.a = std.math.lerp(self.a, other.a, t),
};
}

View File

@ -39,8 +39,8 @@ const State = struct {
nearest_sampler: sg.Sampler, nearest_sampler: sg.Sampler,
default_sampler: Sampler, default_sampler: Sampler,
quads_buffer: [2048]Quad, quads_buffer: [8192]VertexQuad,
quads: std.ArrayList(Quad), quads: std.ArrayList(VertexQuad),
clear_color: Color, clear_color: Color,
@ -126,7 +126,7 @@ pub fn init(gpa: std.mem.Allocator, logger: sg.Logger) !void {
const max_quads = self.quads_buffer.len; const max_quads = self.quads_buffer.len;
bindings.vertex_buffers[0] = sg.makeBuffer(.{ bindings.vertex_buffers[0] = sg.makeBuffer(.{
.size = @sizeOf(Quad) * max_quads, .size = @sizeOf(VertexQuad) * max_quads,
.usage = .{ .vertex_buffer = true, .stream_update = true }, .usage = .{ .vertex_buffer = true, .stream_update = true },
.label = "quad-vertices" .label = "quad-vertices"
}); });
@ -530,9 +530,13 @@ pub fn endFrame() void {
} }
pub fn drawRectangle(pos: Vec2, size: Vec2, color: Color) void { pub fn drawRectangle(pos: Vec2, size: Vec2, color: Color) void {
drawQuad(Quad.initRect(pos, size), color);
}
pub fn drawQuad(quad: Quad, color: Color) void {
const self = &g_state; const self = &g_state;
drawSprite(self.default_sprite, pos, size, color); drawSpriteQuad(self.default_sprite, quad, color);
} }
pub fn drawRectangleOutline(pos: Vec2, size: Vec2, color: Color, width: f32, alignment: f32) void { pub fn drawRectangleOutline(pos: Vec2, size: Vec2, color: Color, width: f32, alignment: f32) void {
@ -543,42 +547,42 @@ pub fn drawRectangleOutline(pos: Vec2, size: Vec2, color: Color, width: f32, ali
drawSpriteQuad( drawSpriteQuad(
self.default_sprite, self.default_sprite,
.{ .init(.{
.init(outer_rect.right(), outer_rect.top()), .init(outer_rect.right(), outer_rect.top()),
.init(outer_rect.left(), outer_rect.top()), .init(outer_rect.left(), outer_rect.top()),
.init(inner_rect.right(), inner_rect.top()), .init(inner_rect.right(), inner_rect.top()),
.init(inner_rect.left(), inner_rect.top()), .init(inner_rect.left(), inner_rect.top()),
}, }),
color color
); );
drawSpriteQuad( drawSpriteQuad(
self.default_sprite, self.default_sprite,
.{ .init(.{
.init(outer_rect.right(), outer_rect.top()), .init(outer_rect.right(), outer_rect.top()),
.init(inner_rect.right(), inner_rect.top()), .init(inner_rect.right(), inner_rect.top()),
.init(outer_rect.right(), outer_rect.bottom()), .init(outer_rect.right(), outer_rect.bottom()),
.init(inner_rect.right(), inner_rect.bottom()), .init(inner_rect.right(), inner_rect.bottom()),
}, }),
color color
); );
drawSpriteQuad( drawSpriteQuad(
self.default_sprite, self.default_sprite,
.{ .init(.{
.init(outer_rect.left(), outer_rect.top()), .init(outer_rect.left(), outer_rect.top()),
.init(inner_rect.left(), inner_rect.top()), .init(inner_rect.left(), inner_rect.top()),
.init(outer_rect.left(), outer_rect.bottom()), .init(outer_rect.left(), outer_rect.bottom()),
.init(inner_rect.left(), inner_rect.bottom()), .init(inner_rect.left(), inner_rect.bottom()),
}, }),
color color
); );
drawSpriteQuad( drawSpriteQuad(
self.default_sprite, self.default_sprite,
.{ .init(.{
.init(outer_rect.right(), outer_rect.bottom()), .init(outer_rect.right(), outer_rect.bottom()),
.init(outer_rect.left(), outer_rect.bottom()), .init(outer_rect.left(), outer_rect.bottom()),
.init(inner_rect.right(), inner_rect.bottom()), .init(inner_rect.right(), inner_rect.bottom()),
.init(inner_rect.left(), inner_rect.bottom()), .init(inner_rect.left(), inner_rect.bottom()),
}, }),
color color
); );
} }
@ -588,14 +592,14 @@ pub fn drawLine(from: Vec2, to: Vec2, color: Color, width: f32) void {
const step = to.sub(from).normalized().multiplyScalar(width/2); const step = to.sub(from).normalized().multiplyScalar(width/2);
const top_left = from.add(step.rotateLeft90()); const top_left = from.add(step.rotateLeft90());
const bottom_left = from.add(step.rotateRight90()); const bottom_left = from.add(step.rotateRight90());
const top_right = to.add(step.rotateLeft90()); const top_right = to.add(step.rotateLeft90());
const bottom_right = to.add(step.rotateRight90()); const bottom_right = to.add(step.rotateRight90());
drawSpriteQuad( drawSpriteQuad(
self.default_sprite, self.default_sprite,
.{ top_right, top_left, bottom_right, bottom_left }, .init(.{ top_right, top_left, bottom_right, bottom_left }),
color color
); );
} }
@ -755,7 +759,7 @@ pub fn setTexture(id: Texture.Id, texture_data: ImageData) void {
} }
pub fn drawTexture(id: Texture.Id, pos: Vec2, size: Vec2, color: Color) void { pub fn drawTexture(id: Texture.Id, pos: Vec2, size: Vec2, color: Color) void {
var quad: Quad = undefined; var quad: VertexQuad = undefined;
quad.setColor(color); quad.setColor(color);
quad.setRect(.{ .pos = pos, .size = size }); quad.setRect(.{ .pos = pos, .size = size });
quad.setUVRect(.init(0, 0, 1, 1)); quad.setUVRect(.init(0, 0, 1, 1));
@ -795,7 +799,7 @@ pub const Sampler = enum {
const DrawOptions = struct { const DrawOptions = struct {
sampler: ?Sampler = null, sampler: ?Sampler = null,
texture: Texture.Id, texture: Texture.Id,
quad: Quad quad: VertexQuad
}; };
pub fn draw(opts: DrawOptions) void { pub fn draw(opts: DrawOptions) void {
@ -1180,15 +1184,15 @@ pub fn getSpriteUVRect(id: Sprite.Id) ?Rect {
return uv_rect; return uv_rect;
} }
fn drawSpriteQuad(id: Sprite.Id, points: [4]Vec2, color: Color) void { pub fn drawSpriteQuad(id: Sprite.Id, points: Quad, color: Color) void {
const self = &g_state; const self = &g_state;
var quad: Quad = undefined; var quad: VertexQuad = undefined;
quad.setColor(color); quad.setColor(color);
quad.vertices[0].position = points[0]; quad.vertices[0].position = points.positions[0];
quad.vertices[1].position = points[1]; quad.vertices[1].position = points.positions[1];
quad.vertices[2].position = points[2]; quad.vertices[2].position = points.positions[2];
quad.vertices[3].position = points[3]; quad.vertices[3].position = points.positions[3];
var texture: ?Texture.Id = null; var texture: ?Texture.Id = null;
if (id != self.nil_sprite) { if (id != self.nil_sprite) {
@ -1208,12 +1212,7 @@ fn drawSpriteQuad(id: Sprite.Id, points: [4]Vec2, color: Color) void {
} }
pub fn drawSprite(id: Sprite.Id, pos: Vec2, size: Vec2, color: Color) void { pub fn drawSprite(id: Sprite.Id, pos: Vec2, size: Vec2, color: Color) void {
const rect = .{ const rect = Quad.initRect(pos, size);
pos,
pos.add(.init(size.x, 0)),
pos.add(.init(0, size.y)),
pos.add(size),
};
drawSpriteQuad(id, rect, color); drawSpriteQuad(id, rect, color);
} }
@ -1716,7 +1715,7 @@ pub const ImageData = struct {
} }
} }
fn getPixel(self: ImageData, x: u32, y: u32) []u8 { pub fn getPixel(self: ImageData, x: u32, y: u32) []u8 {
const pixel_index = y * self.width + x; const pixel_index = y * self.width + x;
if (self.pixels) |pixels| { if (self.pixels) |pixels| {
return switch (pixels) { return switch (pixels) {
@ -1823,7 +1822,7 @@ pub const Sprite = struct {
position: ?Vec2, position: ?Vec2,
padding: u32, padding: u32,
const max_sprites = 128; const max_sprites = 256;
const SlotMap = SlotMapType(std.math.IntFittingRange(0, max_sprites-1), u8, Sprite); const SlotMap = SlotMapType(std.math.IntFittingRange(0, max_sprites-1), u8, Sprite);
pub const Id = SlotMap.Id; pub const Id = SlotMap.Id;
}; };
@ -2296,16 +2295,16 @@ pub const Vertex = extern struct {
color: Vec4, color: Vec4,
}; };
pub const Quad = extern struct { pub const VertexQuad = extern struct {
vertices: [4]Vertex, vertices: [4]Vertex,
pub fn init(vertices: [4]Vertex) Quad { pub fn init(vertices: [4]Vertex) VertexQuad {
return Quad{ return VertexQuad{
.vertices = vertices .vertices = vertices
}; };
} }
pub fn setColor(self: *Quad, color: Color) void { pub fn setColor(self: *VertexQuad, color: Color) void {
for (&self.vertices) |*vertex| { for (&self.vertices) |*vertex| {
vertex.color = Vec4{ vertex.color = Vec4{
.x = color.r, .x = color.r,
@ -2316,7 +2315,7 @@ pub const Quad = extern struct {
} }
} }
pub fn setUVRect(self: *Quad, rect: Rect) void { pub fn setUVRect(self: *VertexQuad, rect: Rect) void {
const pos = rect.pos; const pos = rect.pos;
const size = rect.size; const size = rect.size;
self.vertices[0].texcoord = pos; self.vertices[0].texcoord = pos;
@ -2325,7 +2324,7 @@ pub const Quad = extern struct {
self.vertices[3].texcoord = pos.add(size); self.vertices[3].texcoord = pos.add(size);
} }
pub fn setRect(self: *Quad, rect: Rect) void { pub fn setRect(self: *VertexQuad, rect: Rect) void {
const pos = rect.pos; const pos = rect.pos;
const size = rect.size; const size = rect.size;
self.vertices[0].position = pos; self.vertices[0].position = pos;
@ -2335,6 +2334,39 @@ pub const Quad = extern struct {
} }
}; };
pub const Quad = struct {
positions: [4]Vec2,
pub fn init(positions: [4]Vec2) Quad {
return Quad{
.positions = positions
};
}
pub fn initRect(pos: Vec2, size: Vec2) Quad {
return Quad{
.positions = .{
pos,
pos.add(.init(size.x, 0)),
pos.add(.init(0, size.y)),
pos.add(size),
}
};
}
pub fn applyRotate(self: *Quad, rad: f32, origin: Vec2) void {
for (&self.positions) |*pos| {
pos.* = pos.sub(origin).rotate(rad).add(origin);
}
}
pub fn applyOffset(self: *Quad, vec2: Vec2) void {
for (&self.positions) |*pos| {
pos.* = pos.add(vec2);
}
}
};
pub const TransformFrame = struct { pub const TransformFrame = struct {
offset: Vec2, offset: Vec2,
scale: Vec2, scale: Vec2,

View File

@ -47,7 +47,7 @@ pub fn isMousePressed(self: Input, button: MouseButton) bool {
return self.mouse_buttons.pressed.contains(button); return self.mouse_buttons.pressed.contains(button);
} }
pub fn iMouseReleased(self: Input, button: MouseButton) bool { pub fn isMouseReleased(self: Input, button: MouseButton) bool {
return self.mouse_buttons.released.contains(button); return self.mouse_buttons.released.contains(button);
} }

View File

@ -403,6 +403,11 @@ fn PlatformType(App: type) type {
.unfocused = {} .unfocused = {}
}); });
}, },
.RESIZED => {
self.pushEvent(.{
.window_resize = .initFromInt(i32, e.window_width, e.window_height)
});
},
else => {} else => {}
} }