add tilesheet.zig

This commit is contained in:
Rokas Puzonas 2026-09-15 00:21:52 +03:00
parent fff22349de
commit 94dc7fef0e
2 changed files with 60 additions and 53 deletions

View File

@ -3,15 +3,13 @@ const log = std.log.scoped(.app);
const assert = std.debug.assert; const assert = std.debug.assert;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const Math = @import("math");
const Vec2 = Math.Vec2;
const STBImage = @import("stb_image"); const STBImage = @import("stb_image");
const STBTrueType = @import("stb_truetype"); const STBTrueType = @import("stb_truetype");
const Tiled = @import("tiled"); const Tiled = @import("tiled");
const Platform = @import("platform/root.zig"); const Platform = @import("platform/root.zig");
const Gfx = Platform.Gfx; const Gfx = Platform.Gfx;
const Vec2 = Platform.Vec2;
const Audio = Platform.Audio; const Audio = Platform.Audio;
const ImGUI = Platform.ImGUI; const ImGUI = Platform.ImGUI;
const Rect = Platform.Rect; const Rect = Platform.Rect;
@ -19,6 +17,7 @@ const Color = Platform.Color;
const CanvasScaler = @import("./canvas_scaler.zig"); const CanvasScaler = @import("./canvas_scaler.zig");
const Font = @import("./font.zig"); const Font = @import("./font.zig");
const Tilesheet = @import("./tilesheet.zig");
const App = @This(); const App = @This();
@ -115,55 +114,6 @@ footstep_sound: Audio.SoundId = .nil,
sfx_bus: Audio.BusId, sfx_bus: Audio.BusId,
const Tilesheet = struct {
image: Gfx.ImageData,
sprites: []Gfx.Sprite.Id,
tile_size: Vec2,
width: u32,
height: u32,
pub fn init(gpa: Allocator, image: Gfx.ImageData, tile_width: u32, tile_height: u32) !Tilesheet {
const width = image.width / tile_width;
const height = image.height / tile_height;
const sprites = try gpa.alloc(Gfx.Sprite.Id, width * height);
errdefer gpa.free(sprites);
@memset(sprites, .nil);
return Tilesheet{
.sprites = sprites,
.image = image,
.width = width,
.height = height,
.tile_size = .initFromInt(u32, tile_width, tile_height)
};
}
pub fn deinit(self: Tilesheet) void {
for (self.sprites) |sprite| {
Gfx.deinitSprite(sprite);
}
}
pub fn get(self: Tilesheet, x: usize, y: usize) Gfx.Sprite.Id {
if (x >= self.width or y >= self.height) {
log.warn("Attempt to get tile which is out of bounds", .{});
return .nil;
}
const sprite_index = y * self.width + x;
if (self.sprites[sprite_index] == Gfx.Sprite.Id.nil) {
const sprite = Gfx.initSprite(.{ .padding = 1 });
Gfx.setSprite(sprite, .{
.image = self.image,
.rect = Rect.init(@floatFromInt(x), @floatFromInt(y), 1, 1).multiply(self.tile_size)
});
self.sprites[sprite_index] = sprite;
}
return self.sprites[sprite_index];
}
};
pub fn init(self: *App, plt: Platform.Init) !?u8 { pub fn init(self: *App, plt: Platform.Init) !?u8 {
const roboto_font = try Font.init(plt.gpa, .{ const roboto_font = try Font.init(plt.gpa, .{
.spritesheet = Gfx.initSpritesheet(.{ .format = .r8 }), .spritesheet = Gfx.initSpritesheet(.{ .format = .r8 }),
@ -178,7 +128,7 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
.height = tilesheet_png.height, .height = tilesheet_png.height,
.pixels = .{ .rgba8 = tilesheet_png.rgba8_pixels } .pixels = .{ .rgba8 = tilesheet_png.rgba8_pixels }
}, },
64, 64, .init(64, 64)
); );
var player_sprites: PlayerSprites = undefined; var player_sprites: PlayerSprites = undefined;

57
src/tilesheet.zig Normal file
View File

@ -0,0 +1,57 @@
const std = @import("std");
const log = std.log.scoped(.app);
const Allocator = std.mem.Allocator;
const Platform = @import("platform/root.zig");
const Gfx = Platform.Gfx;
const Vec2 = Platform.Vec2;
const Rect = Platform.Rect;
const Tilesheet = @This();
image: Gfx.ImageData,
sprites: []Gfx.Sprite.Id,
tile_size: Vec2,
width: u32,
height: u32,
pub fn init(gpa: Allocator, image: Gfx.ImageData, tile_size: Vec2) !Tilesheet {
const width = @divFloor(image.width, @as(u32, @intFromFloat(tile_size.x)));
const height = @divFloor(image.height, @as(u32, @intFromFloat(tile_size.y)));
const sprites = try gpa.alloc(Gfx.Sprite.Id, width * height);
errdefer gpa.free(sprites);
@memset(sprites, .nil);
return Tilesheet{
.sprites = sprites,
.image = image,
.width = width,
.height = height,
.tile_size = tile_size
};
}
pub fn deinit(self: Tilesheet) void {
for (self.sprites) |sprite| {
Gfx.deinitSprite(sprite);
}
}
pub fn get(self: Tilesheet, x: usize, y: usize) Gfx.Sprite.Id {
if (x >= self.width or y >= self.height) {
log.warn("Attempt to get tile which is out of bounds", .{});
return .nil;
}
const sprite_index = y * self.width + x;
if (self.sprites[sprite_index] == Gfx.Sprite.Id.nil) {
const sprite = Gfx.initSprite(.{ .padding = 1 });
Gfx.setSprite(sprite, .{
.image = self.image,
.rect = Rect.init(@floatFromInt(x), @floatFromInt(y), 1, 1).multiply(self.tile_size)
});
self.sprites[sprite_index] = sprite;
}
return self.sprites[sprite_index];
}