add tilemap rendering

This commit is contained in:
Rokas Puzonas 2026-01-27 07:42:54 +02:00
parent 4c425720cc
commit a121b8bcdb
250 changed files with 586 additions and 165 deletions

View File

@ -1,4 +1,12 @@
# Game template
# Gaem
* Run & gun
* Nuclear throne -esque
* Single gun type
* Single map
* Single enemy type
* Collect letters to win, up to 7 letters we have 8 character sprites
* The word is WINNER
## Run
@ -16,15 +24,3 @@ Cross-compile for Windows from Linux:
```sh
zig build -Dtarget=x86_64-windows
```
## TODO
* Use [Skribidi](https://github.com/memononen/Skribidi) instead of fontstash for text rendering
* Support for audio formats (Might not need all of them, haven't decided):
* QOA, maybe [qoa.h](https://github.com/phoboslab/qoa/blob/master/qoa.h)?
* Flac, maybe [dr_flac.h](https://github.com/mackron/dr_libs/blob/master/dr_flac.h)?
* Wav, maybe [dr_wav.h](https://github.com/mackron/dr_libs/blob/master/dr_wav.h)?
* Mp3, maybe [dr_mp3.h](https://github.com/mackron/dr_libs/blob/master/dr_mp3.h)?
* Gamepad support.
* WASM Support. Currently a build config isn't provided for this target.
* Update build config for other platforms to reduce binary size. All of the video and audio drivers aren't needed, only gamepads

View File

@ -2,6 +2,8 @@ const std = @import("std");
const sokol = @import("sokol");
const builtin = @import("builtin");
const project_name = "game-2026-01-18";
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
@ -105,12 +107,12 @@ pub fn build(b: *std.Build) !void {
// from here on different handling for native vs wasm builds
if (target.result.cpu.arch.isWasm()) {
try buildWasm(b, .{
.name = "sokol_template",
.name = project_name,
.mod_main = mod_main,
.dep_sokol = dep_sokol,
});
} else {
try buildNative(b, "sokol_template", mod_main, has_console);
try buildNative(b, project_name, mod_main, has_console);
}
}

View File

@ -94,7 +94,7 @@ pub const TileVariant = struct {
try temp_tiles.appendSlice(scratch.allocator(), tiles.items);
} else if (node.isTag("chunk")) {
const chunk = try initChunkDataFromXml(scratch.allocator(), scratch, lexer, encoding);
const chunk = try initChunkDataFromXml(arena, scratch, lexer, encoding);
try temp_chunks.append(scratch.allocator(), chunk);
continue;
@ -105,11 +105,18 @@ pub const TileVariant = struct {
try iter.finish("data");
if (temp_chunks.items.len > 0) {
return .{
.chunks = try arena.dupe(Chunk, temp_chunks.items)
};
} else {
return .{
.fixed = try arena.dupe(u32, temp_tiles.items)
};
}
}
fn parseEncoding(
encoding: Encoding,
allocator: std.mem.Allocator,
@ -136,13 +143,76 @@ pub const TileVariant = struct {
return result;
}
pub fn getBounds(self: TileVariant) void {
_ = self; // autofix
const Bounds = struct {
left: i32,
right: i32,
top: i32,
bottom: i32,
pub fn width(self: Bounds) u32 {
return @intCast(self.right - self.left);
}
pub fn get(self: TileVariant, x: usize, y: usize) ?u32 {
pub fn height(self: Bounds) u32 {
return @intCast(self.bottom - self.top);
}
};
pub fn getBounds(self: TileVariant) Bounds {
if (self.data == .fixed) {
return Bounds{
.left = 0,
.right = @intCast(self.width),
.top = 0,
.bottom = @intCast(self.height),
};
} else if (self.data == .chunks) {
const chunks = self.data.chunks;
var result = Bounds{
.left = 0,
.right = 0,
.top = 0,
.bottom = 0
};
if (chunks.len > 0) {
result.left = chunks[0].x;
result.right = chunks[0].x + @as(i32, @intCast(chunks[0].width));
result.top = chunks[0].y;
result.bottom = chunks[0].y + @as(i32, @intCast(chunks[0].height));
for (chunks[1..]) |chunk| {
result.left = @min(result.left, chunk.x);
result.right = @max(result.right, chunk.x + @as(i32, @intCast(chunk.width)));
result.top = @min(result.top, chunk.y);
result.bottom = @max(result.bottom, chunk.y + @as(i32, @intCast(chunk.height)));
}
}
return result;
} else {
unreachable;
}
}
pub fn get(self: TileVariant, x: i32, y: i32) ?u32 {
if (self.data == .fixed) {
if ((0 <= x and x < self.width) and (0 <= y and y < self.height)) {
return self.data[y * self.width + x];
const x_u32: u32 = @intCast(x);
const y_u32: u32 = @intCast(y);
return self.data.fixed[y_u32 * self.width + x_u32];
}
} else if (self.data == .chunks) {
for (self.data.chunks) |chunk| {
const ox = x - chunk.x;
const oy = y - chunk.y;
if ((0 <= ox and ox < chunk.width) and (0 <= oy and oy < chunk.height)) {
const ox_u32: u32 = @intCast(ox);
const oy_u32: u32 = @intCast(oy);
return chunk.data[oy_u32 * chunk.width + ox_u32];
}
}
} else {
unreachable;
}
return null;
}

View File

@ -215,7 +215,18 @@ fn getTilesetByGid(self: *const Tilemap, gid: u32) ?TilesetReference {
return result;
}
pub fn getTile(self: *const Tilemap, layer: *const Layer, tilesets: Tileset.List, x: usize, y: usize) ?Tile {
pub fn getTile(self: *const Tilemap, tilesets: Tileset.List, gid: u32) ?Tile {
const tileset_ref = self.getTilesetByGid(gid & GlobalTileId.Flag.clear) orelse return null;
const tileset = tilesets.get(tileset_ref.source) orelse return null;
const id = gid - tileset_ref.first_gid;
return Tile{
.tileset = tileset,
.id = id
};
}
pub fn getTileByPosition(self: *const Tilemap, layer: *const Layer, tilesets: Tileset.List, x: usize, y: usize) ?Tile {
assert(layer.variant == .tile);
const tile_variant = layer.variant.tile;

View File

@ -4,6 +4,7 @@ const tiled = @import("tiled");
const Math = @import("./engine/math.zig");
const Engine = @import("./engine/root.zig");
const STBImage = @import("stb_image");
const Gfx = Engine.Graphics;
const Audio = Engine.Audio;
@ -21,6 +22,8 @@ font_id: FontName.EnumArray,
wood01: Audio.Data.Id,
map: tiled.Tilemap,
tilesets: tiled.Tileset.List,
tileset_texture: Gfx.TextureId,
tile_size: Engine.Vec2,
pub fn init(gpa: std.mem.Allocator) !Assets {
const font_id_array: FontName.EnumArray = .init(.{
@ -57,11 +60,24 @@ pub fn init(gpa: std.mem.Allocator) !Assets {
var tilesets: tiled.Tileset.List = .empty;
try tilesets.add(gpa, "tileset.tsx", tileset);
const tileset_image = try STBImage.load(@embedFile("assets/kenney_desert-shooter-pack_1.0/PNG/Tiles/tilemap_packed.png"));
defer tileset_image.deinit();
const tileset_texture = try Gfx.addTexture(&.{
.{
.width = tileset_image.width,
.height = tileset_image.height,
.rgba = tileset_image.rgba8_pixels
}
});
return Assets{
.font_id = font_id_array,
.wood01 = wood01,
.map = map,
.tilesets = tilesets
.tilesets = tilesets,
.tileset_texture = tileset_texture,
.tile_size = .init(16, 16)
};
}

View File

@ -26,7 +26,7 @@
"scaleInEditor": 1
}
},
"last.imagePath": "/home/rokas/code/games/game-2026-01-18/src/assets/kenney_desert-shooter-pack_1.0/PNG/Tiles/Tilemap",
"last.imagePath": "/home/rokas/code/games/game-2026-01-18/src/assets/kenney_desert-shooter-pack_1.0/PNG/Tiles",
"map.fixedSize": false,
"map.lastUsedFormat": "tmx",
"map.tileHeight": 16,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

Some files were not shown because too many files have changed in this diff Show More