diff --git a/README.md b/README.md index cfd0eec..139e983 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,19 @@ ## Run Linux and Windows: + ```sh zig build run ``` Web: + ```sh zig build -Dtarget=wasm32-emscripten run ``` Cross-compile for Windows from Linux: + ```sh zig build -Dtarget=x86_64-windows ``` diff --git a/assets/tiled/map.tmx b/assets/tiled/map.tmx index 865645c..bea0985 100644 --- a/assets/tiled/map.tmx +++ b/assets/tiled/map.tmx @@ -1,5 +1,5 @@ - + @@ -8,31 +8,211 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,90,90,90,90,90,90,90,90,0,0, -0,0,0,0,0,0,90,90,90,90,90,90,90,90,0,0, -0,0,0,0,0,0,90,90,90,90,90,90,90,90,0,0, -0,0,0,0,0,0,90,90,90,90,90,90,90,90,0,0, -0,0,0,0,0,0,90,90,90,90,90,90,90,90,0,0, -0,0,0,0,0,0,90,90,90,90,90,90,90,90,0,0, -0,0,0,0,0,0,90,90,90,90,90,90,90,90,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,91,91,91,91,91,91,0,0,0,0,0,0,0,0, +0,0,91,90,90,90,90,91,91,91,91,91,91,0,0,0, +0,0,91,90,90,90,90,90,90,90,90,90,91,91,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, -0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, -0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, -0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, -0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, -0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, -0,0,0,0,90,90,90,90,90,90,90,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,91,91,91,91,91,91,0,0,0,0,0,0,0,0, +0,0,91,90,90,90,90,91,91,91,91,91,91,0,0,0, +0,0,91,90,90,90,90,90,90,90,90,90,91,91,0,0 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,91,91,91,91,91,91,0,0,0,0,0,0,0,0,91, +0,91,90,90,90,90,91,91,91,91,91,91,0,0,0,91, +0,91,90,90,90,90,90,90,90,90,90,91,91,0,0,91 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +91,91,91,91,91,0,0,0,0,0,0,0,0,91,91,91, +90,90,90,90,91,91,91,91,91,91,0,0,0,91,90,90, +90,90,90,90,90,90,90,90,90,91,91,0,0,91,90,90 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +91,91,91,0,0,0,0,0,0,0,0,91,91,91,91,91, +90,90,91,91,91,91,91,91,0,0,0,91,90,90,90,90, +90,90,90,90,90,90,90,91,91,0,0,91,90,90,90,90 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +91,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +91,91,91,91,91,91,0,0,0,0,0,0,0,0,0,0, +90,90,90,90,90,91,91,0,0,0,0,0,0,0,0,0 + + +0,0,91,90,90,90,90,90,90,90,90,90,90,91,0,0, +0,0,91,90,90,90,90,90,90,90,90,90,91,91,0,0, +0,0,91,91,91,91,91,91,91,91,91,91,91,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +0,0,91,90,90,90,90,90,90,90,90,90,90,91,0,0, +0,0,91,90,90,90,90,90,90,90,90,90,91,91,0,0, +0,0,91,91,91,91,91,91,91,91,91,91,91,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +0,91,90,90,90,90,90,90,90,90,90,90,91,0,0,91, +0,91,90,90,90,90,90,90,90,90,90,91,91,0,0,91, +0,91,91,91,91,91,91,91,91,91,91,91,0,0,0,91, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +90,90,90,90,90,90,90,90,90,90,91,0,0,91,90,90, +90,90,90,90,90,90,90,90,90,91,91,0,0,91,90,90, +91,91,91,91,91,91,91,91,91,91,0,0,0,91,91,91, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +90,90,90,90,90,90,90,90,91,0,0,91,90,90,90,90, +90,90,90,90,90,90,90,91,91,0,0,91,90,90,90,90, +91,91,91,91,91,91,91,91,0,0,0,91,91,91,91,91, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +90,90,90,90,90,90,91,0,0,0,0,0,0,0,0,0, +90,90,90,90,90,91,91,0,0,0,0,0,0,0,0,0, +91,91,91,91,91,91,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -48,31 +228,211 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,98,98,101,98,98,98,98,98,0,0, -0,0,0,0,0,0,98,0,0,98,0,0,0,98,0,0, -0,0,0,0,0,0,98,0,0,0,0,0,0,98,0,0, -0,0,0,0,0,0,98,0,7,0,0,26,0,98,0,0, -0,0,0,0,0,0,98,0,0,0,0,0,0,101,0,0, -0,0,0,0,0,0,98,0,0,98,0,0,0,101,0,0, -0,0,0,0,0,0,98,98,98,98,98,101,101,101,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,98,98,98,98,98,98,0,0,0,0,0,0,0,0, +0,0,98,0,0,0,0,98,98,98,98,98,98,0,0,0, +0,0,98,0,0,0,0,0,0,0,0,0,98,98,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,98,98,98,98,98,98,98,0,0,0,0,0, -0,0,0,0,98,0,0,0,0,0,98,0,0,0,0,0, -0,0,0,0,98,0,7,0,26,0,98,0,0,0,0,0, -0,0,0,0,98,0,0,0,0,0,98,0,0,0,0,0, -0,0,0,0,98,0,7,0,26,0,98,0,0,0,0,0, -0,0,0,0,98,0,0,0,0,0,98,0,0,0,0,0, -0,0,0,0,98,98,98,98,98,98,98,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,98,98,98,98,98,98,0,0,0,0,0,0,0,0, +0,0,98,0,0,0,0,98,98,98,98,98,98,0,0,0, +0,0,98,0,0,0,0,7,0,0,0,0,98,98,0,0 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,98,98,98,98,98,98,0,0,0,0,0,0,0,0,98, +0,98,0,0,0,0,98,98,98,98,98,98,0,0,0,98, +0,98,0,0,0,0,7,0,0,99,0,98,98,0,0,98 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +98,98,98,98,98,0,0,0,0,0,0,0,0,98,98,98, +0,0,0,0,98,98,98,98,98,98,0,0,0,98,0,0, +0,0,0,7,0,0,0,99,0,98,98,0,0,98,0,0 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +98,98,98,0,0,0,0,0,0,0,0,98,98,98,98,98, +0,0,98,98,98,98,98,98,0,0,0,98,0,0,0,0, +0,0,0,0,99,99,0,98,98,0,0,98,0,0,0,0 + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +98,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +98,98,98,98,98,98,0,0,0,0,0,0,0,0,0,0, +0,0,0,99,0,98,98,0,0,0,0,0,0,0,0,0 + + +0,0,98,0,72,0,7,0,0,0,0,40,0,98,0,0, +0,0,98,0,0,0,0,0,0,0,0,0,98,98,0,0, +0,0,98,98,98,98,98,98,98,98,98,98,98,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +0,0,98,0,72,0,0,7,0,0,0,75,0,98,0,0, +0,0,98,0,0,0,0,7,0,0,0,0,98,98,0,0, +0,0,98,98,98,98,98,98,98,98,98,98,98,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +0,98,0,72,0,0,7,0,0,0,75,0,98,0,0,98, +0,98,0,0,0,0,7,0,0,99,0,98,98,0,0,98, +0,98,98,98,98,98,98,98,98,98,98,98,0,0,0,98, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +0,72,0,0,0,0,0,12,75,0,98,0,0,98,0,72, +0,0,0,0,0,0,0,99,0,98,98,0,0,98,0,0, +98,98,98,98,98,98,98,98,98,98,0,0,0,98,98,98, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +0,7,7,0,12,12,75,0,98,0,0,98,0,72,0,0, +0,0,0,0,99,99,0,98,98,0,0,98,0,0,0,0, +98,98,98,98,98,98,98,98,0,0,0,98,98,98,98,98, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + + +0,0,0,12,75,0,98,0,0,0,0,0,0,0,0,0, +7,0,0,99,0,98,98,0,0,0,0,0,0,0,0,0, +98,98,98,98,98,98,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -81,24 +441,36 @@ - - - - - - - - - - + + - + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/tiled/tileset.tsx b/assets/tiled/tileset.tsx index e1e3538..2267c09 100644 --- a/assets/tiled/tileset.tsx +++ b/assets/tiled/tileset.tsx @@ -26,6 +26,11 @@ + + + + + @@ -36,6 +41,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -46,6 +81,16 @@ + + + + + + + + + + diff --git a/src/app.zig b/src/app.zig index 5eac963..513b6c9 100644 --- a/src/app.zig +++ b/src/app.zig @@ -44,52 +44,19 @@ const PlayerSprites = struct { } }; -const Tile = struct { - ground_sprite: ?Gfx.Sprite.Id, +const Point = struct { + x: i32, + y: i32, - entities_by_layer: std.EnumArray(Entity.Layer, Entity.Id), - - const empty = Tile{ - .ground_sprite = null, - .entities_by_layer = .initFill(.nil) - }; -}; - -const Tilemap = struct { - tiles: []Tile, - width: usize, - height: usize, - - pub fn init(gpa: Allocator, width: usize, height: usize) !Tilemap { - const tiles = try gpa.alloc(Tile, width * height); - @memset(tiles, .empty); - - return Tilemap{ - .width = width, - .height = height, - .tiles = tiles + pub fn add(lhs: Point, rhs: Point) Point { + return Point{ + .x = lhs.x + rhs.x, + .y = lhs.y + rhs.y, }; } - pub fn clone(self: Tilemap, gpa: Allocator) !Tilemap { - const tiles = try gpa.dupe(Tile, self.tiles); - errdefer gpa.free(tiles); - - return Tilemap{ - .tiles = tiles, - .width = self.width, - .height = self.height, - }; - } - - pub fn deinit(self: *Tilemap, gpa: Allocator) void { - gpa.free(self.tiles); - } - - pub fn get(self: *Tilemap, x: usize, y: usize) *Tile { - assert(x < self.width); - assert(y < self.height); - return &self.tiles[y * self.width + x]; + pub fn eql(lhs: Point, rhs: Point) bool { + return lhs.x == rhs.x and lhs.y == rhs.y; } }; @@ -97,8 +64,7 @@ const Entity = struct { type: Type, layer: Layer, - pos_x: i32 = -1, - pos_y: i32 = -1, + pos: Point = .{ .x = -1, .y = -1 }, visual_pos: Vec2 = .init(0, 0), sprite: ?Gfx.Sprite.Id = null, @@ -106,14 +72,19 @@ const Entity = struct { player_frame_index: u32 = 0, const Type = enum { + nil, + player, box, - goal_marker, - wall + wall, + coin, + box_hole, + box_goal, }; const Layer = enum { ground, + on_ground, surface, }; @@ -121,14 +92,47 @@ const Entity = struct { const Id = SlotMap.Id; }; +const UndoFrame = struct { + const EntityState = struct { + id: Entity.Id, + pos: Point, + player_direction: Direction, + }; + + entities_buffer: [8]EntityState, + entities_len: usize, + + pub const empty = UndoFrame{ + .entities_buffer = undefined, + .entities_len = 0 + }; + + pub fn entities(self: *const UndoFrame) []const EntityState { + return self.entities_buffer[0..self.entities_len]; + } + + pub fn pushEntity(self: *UndoFrame, e: EntityState) bool { + if (self.entities_len < self.entities_buffer.len) { + self.entities_buffer[self.entities_len] = e; + self.entities_len += 1; + + return true; + } + + return false; + } + + pub fn isEmpty(self: UndoFrame) bool { + return self.entities_len == 0; + } +}; + const World = struct { - tilemap: Tilemap, entities: Entity.SlotMap, + width: u32, + height: u32, pub fn clone(self: World, gpa: Allocator) !World { - var tilemap = try self.tilemap.clone(gpa); - errdefer tilemap.deinit(gpa); - var entity_slots = try self.entities.slots.clone(gpa); errdefer entity_slots.deinit(gpa); @@ -136,85 +140,86 @@ const World = struct { entities.slots = entity_slots; return World{ - .tilemap = tilemap, - .entities = entities + .width = self.width, + .height = self.height, + .entities = entities, }; } pub fn deinit(self: *World, gpa: Allocator) void { - self.tilemap.deinit(gpa); self.entities.deinit(gpa); } fn spawnEntity(self: *World, opts: Entity) Entity.Id { - var e = opts; - e.pos_x = -1; - e.pos_y = -1; - const entity_id = self.entities.insert(e) catch |err| { + return self.entities.insert(opts) catch |err| { log.err("Failed to spawn entity: {}", .{err}); return .nil; }; + } - if (opts.pos_x != -1 or opts.pos_y != -1) { - assert(opts.pos_x != -1 and opts.pos_y != -1); - if (!self.setEntityPosition(entity_id, opts.pos_x, opts.pos_y)) { - log.err("Entity position: {}, {}", .{opts.pos_x, opts.pos_y}); - @panic("Failed to set initial entity position"); + fn findEntity(self: *World, pos: Point, layer: Entity.Layer) Entity.Id { + var entity_iter = self.entities.iterator(); + while (entity_iter.next()) |entity_id| { + const entity = self.entities.getAssumeExists(entity_id); + if (entity.layer == layer and entity.pos.eql(pos)) { + return entity_id; } } - return entity_id; + return .nil; } +}; - fn getTile(self: *World, x: i32, y: i32) ?*Tile { - const width: i32 = @intCast(self.tilemap.width); - const height: i32 = @intCast(self.tilemap.height); - if (0 <= x and x < width and 0 <= y and y < height) { - return &self.tilemap.tiles[@intCast(x + y * width)]; - } - return null; - } +const TickContext = struct { + world: *World, + undo_frame: UndoFrame = .empty, - fn setEntityPosition(self: *World, id: Entity.Id, x: i32, y: i32) bool { - const e = self.entities.get(id) orelse return false; - const destination_tile = self.getTile(x, y) orelse return false; - - if (self.entities.exists(destination_tile.entities_by_layer.get(e.layer))) { - // Cant't overwrite entity + fn moveEntity(self: *TickContext, id: Entity.Id, dir: Point) bool { + if (dir.x == 0 and dir.y == 0) { return false; } - destination_tile.entities_by_layer.set(e.layer, id); - if (self.getTile(e.pos_x, e.pos_y)) |tile| { - tile.entities_by_layer.set(e.layer, .nil); - } + const e = self.world.entities.get(id) orelse return false; - e.pos_x = x; - e.pos_y = y; - - return true; - } - - fn moveEntity(self: *World, id: Entity.Id, dx: i32, dy: i32) bool { - const e = self.entities.get(id) orelse return false; - - const next_x = e.pos_x+dx; - const next_y = e.pos_y+dy; - - const destination_tile = self.getTile(next_x, next_y) orelse return false; + const next_pos = e.pos.add(dir); if (e.type == .player or e.type == .box) { - const destination_entity_id = destination_tile.entities_by_layer.get(e.layer); - if (self.entities.get(destination_entity_id)) |destination_entity| { + const destination_entity_id = self.world.findEntity(next_pos, e.layer); + if (self.world.entities.get(destination_entity_id)) |destination_entity| { if (destination_entity.type == .box) { - if (!self.moveEntity(destination_entity_id, dx, dy)) { + if (!self.moveEntity(destination_entity_id, dir)) { return false; } } + else if (destination_entity.type == .wall) { + return false; + } } } - return self.setEntityPosition(id, next_x, next_y); + if (!self.undo_frame.pushEntity(.{ + .id = id, + .pos = e.pos, + .player_direction = e.player_direction + })) { + log.warn("Failed to push entity undo", .{}); + } + + if (e.type == .player) { + if (dir.x < 0) { + e.player_direction = .left; + } else if (dir.x > 0) { + e.player_direction = .right; + } else if (dir.y > 0) { + e.player_direction = .down; + } else if (dir.y < 0) { + e.player_direction = .up; + } + } + + e.pos = next_pos; + + return true; } }; @@ -224,6 +229,7 @@ const Level = struct { }; world: World, +undo_stack: std.ArrayList(UndoFrame) = .empty, current_level: u32 = 0, levels: std.ArrayList(Level), @@ -372,7 +378,6 @@ fn loadLevels(self: *App, gpa: Allocator, assets: *Platform.Assets) !std.ArrayLi std.mem.sort(Level, levels.items, Context{}, Context.lessThan); - return levels; } @@ -386,7 +391,8 @@ fn loadLevel( var level = Level{ .number = 0, .world = .{ - .tilemap = try .init(gpa, bounds.width(), bounds.height()), + .width = bounds.width(), + .height = bounds.height(), .entities = try .initCapacity(gpa, 256) } }; @@ -398,11 +404,18 @@ fn loadLevel( const x = bounds.min_x + @as(i32, @intCast(ox)); const y = bounds.min_y + @as(i32, @intCast(oy)); - const tile = level.world.tilemap.get(ox, oy); - if (tilemap.getTile(ground, tilesets, x, y)) |tiled_tile| { const pos = tiled_tile.getPosition(); - tile.ground_sprite = self.tilesheet.get(pos.x, pos.y); + + _ = level.world.spawnEntity(Entity{ + .type = .nil, + .layer = .ground, + .pos = .{ + .x = @intCast(ox), + .y = @intCast(oy), + }, + .sprite = self.tilesheet.get(pos.x, pos.y) + }); } if (tilemap.getTile(foreground, tilesets, x, y)) |tiled_tile| { @@ -416,19 +429,27 @@ fn loadLevel( entity_type = .wall; } else if (std.mem.eql(u8, props_type, "box")) { entity_type = .box; - } else if (std.mem.eql(u8, props_type, "goal_marker")) { - entity_type = .goal_marker; - layer = .ground; + } else if (std.mem.eql(u8, props_type, "player")) { + entity_type = .player; + } else if (std.mem.eql(u8, props_type, "coin")) { + entity_type = .coin; + } else if (std.mem.eql(u8, props_type, "box_hole")) { + entity_type = .box_hole; + } else if (std.mem.eql(u8, props_type, "box_goal")) { + entity_type = .box_goal; + layer = .on_ground; } else { - log.warn("Unknown tile type: '{s}'", .{props_type}); + log.warn("Unknown tile type: '{s}' at {} {}", .{props_type, x, y}); } if (entity_type != null) { _ = level.world.spawnEntity(Entity{ .type = entity_type.?, .layer = layer, - .pos_x = @intCast(ox), - .pos_y = @intCast(oy), + .pos = .{ + .x = @intCast(ox), + .y = @intCast(oy), + }, .sprite = self.tilesheet.get(pos.x, pos.y) }); } @@ -436,58 +457,43 @@ fn loadLevel( } } - for (tilemap.getLayer("Markers").?.variant.object.items) |obj| { - if (obj.shape != .point) { - continue; - } - if (!std.mem.eql(u8, obj.name, "spawn")) { - continue; - } - - var position = obj.shape.point; - position.x /= @floatFromInt(tilemap.tile_width); - position.y /= @floatFromInt(tilemap.tile_height); - - const pos_x: i32 = @intFromFloat(position.x); - const pos_y: i32 = @intFromFloat(position.y); - - if (bounds.isInside(pos_x, pos_y)) { - _ = level.world.spawnEntity(Entity{ - .type = .player, - .layer = .surface, - .pos_x = pos_x - bounds.min_x, - .pos_y = pos_y - bounds.min_y - }); - } - } - return level; } -fn updateWorld(world: *World) void { - _ = world; // autofix +const PlayerInput = struct { + move_dir: Point, + undo: bool +}; + +fn getPlayerInput(input: *Platform.Input) PlayerInput { + var result: PlayerInput = .{ + .move_dir = .{ .x = 0, .y = 0 }, + .undo = false + }; + + if (input.isKeyPressedOrRepeat(.S)) { + result.move_dir.y += 1; + } + if (input.isKeyPressedOrRepeat(.W)) { + result.move_dir.y -= 1; + } + if (input.isKeyPressedOrRepeat(.D)) { + result.move_dir.x += 1; + } + if (input.isKeyPressedOrRepeat(.A)) { + result.move_dir.x -= 1; + } + if (result.move_dir.x != 0) { + result.move_dir.y = 0; + } + + result.undo = input.isKeyPressedOrRepeat(.Z); + + return result; } pub fn frame(self: *App, plt: Platform.Frame) !void { - const input = plt.input; - - var dir_y: i32 = 0; - var dir_x: i32 = 0; - if (input.isKeyPressedOrRepeat(.S)) { - dir_y += 1; - } - if (input.isKeyPressedOrRepeat(.W)) { - dir_y -= 1; - } - if (input.isKeyPressedOrRepeat(.D)) { - dir_x += 1; - } - if (input.isKeyPressedOrRepeat(.A)) { - dir_x -= 1; - } - if (dir_x != 0) { - dir_y = 0; - } + const input = getPlayerInput(plt.input); const clear_color = Color.rgb(40, 40, 40); Gfx.setClearColor(clear_color); @@ -495,11 +501,25 @@ pub fn frame(self: *App, plt: Platform.Frame) !void { const tile_size = Vec2.init(48, 48); var canvas = CanvasScaler{ - .size = Vec2.initFromInt(usize, self.world.tilemap.width, self.world.tilemap.height).multiply(tile_size) + .size = Vec2.initFromInt(usize, self.world.width, self.world.height).multiply(tile_size) }; canvas.push(); defer canvas.pop(clear_color); + if (input.undo) { + if (self.undo_stack.pop()) |undo_frame| { + for (undo_frame.entities()) |e_state| { + var e = self.world.entities.getAssumeExists(e_state.id); + e.pos = e_state.pos; + e.player_direction = e_state.player_direction; + } + } + } + + var tick_context: TickContext = .{ + .world = &self.world + }; + var goal_count: u32 = 0; var box_at_goal_count: u32 = 0; { @@ -507,21 +527,10 @@ pub fn frame(self: *App, plt: Platform.Frame) !void { while (entity_iter.next()) |entity_id| { const entity = self.world.entities.getAssumeExists(entity_id); if (entity.type == .player) { - if ((dir_x != 0 or dir_y != 0) and self.world.moveEntity(entity_id, dir_x, dir_y)) { - var new_direction = entity.player_direction; - if (dir_x < 0) { - new_direction = .left; - } else if (dir_x > 0) { - new_direction = .right; - } else if (dir_y > 0) { - new_direction = .down; - } else if (dir_y < 0) { - new_direction = .up; - } - - if (entity.player_direction != new_direction) { + const prev_player_direction = entity.player_direction; + if (tick_context.moveEntity(entity_id, input.move_dir)) { + if (entity.player_direction != prev_player_direction) { entity.player_frame_index = 0; - entity.player_direction = new_direction; } self.footstep_sound = Audio.play(.{ .buffer = self.footstep_buffer, .bus = self.sfx_bus }); @@ -529,7 +538,7 @@ pub fn frame(self: *App, plt: Platform.Frame) !void { const frames = self.player_sprites.getDirection(entity.player_direction); - if (dir_x != 0 or dir_y != 0) { + if (input.move_dir.x != 0 or input.move_dir.y != 0) { self.animation_timer += plt.input.delta_time; const animatin_time = std.time.ns_per_s / 5; while (self.animation_timer >= animatin_time) { @@ -542,32 +551,25 @@ pub fn frame(self: *App, plt: Platform.Frame) !void { } entity.sprite = frames[entity.player_frame_index]; - } else if (entity.type == .goal_marker) { + } else if (entity.type == .box_goal) { goal_count += 1; - const tile = self.world.getTile(entity.pos_x, entity.pos_y).?; - if (self.world.entities.get(tile.entities_by_layer.get(.surface))) |above_entity| { + if (self.world.entities.get(self.world.findEntity(entity.pos, .surface))) |above_entity| { if (above_entity.type == .box) { box_at_goal_count += 1; } } } - entity.visual_pos = .initFromInt(i32, entity.pos_x, entity.pos_y); + entity.visual_pos = .initFromInt(i32, entity.pos.x, entity.pos.y); } } - for (0..self.world.tilemap.height) |y| { - for (0..self.world.tilemap.width) |x| { - const tile = self.world.tilemap.get(x, y); - - if (tile.ground_sprite) |sprite| { - Gfx.drawSprite(sprite, Vec2.initFromInt(usize, x, y).multiply(tile_size), tile_size, .white); - } - } + if (!tick_context.undo_frame.isEmpty()) { + try self.undo_stack.append(plt.gpa, tick_context.undo_frame); } - inline for (.{ Entity.Layer.ground, Entity.Layer.surface }) |layer| { + inline for (.{ Entity.Layer.ground, Entity.Layer.on_ground, Entity.Layer.surface }) |layer| { var entity_iter = self.world.entities.iterator(); while (entity_iter.next()) |entity_id| { const entity = self.world.entities.getAssumeExists(entity_id); @@ -603,4 +605,5 @@ pub fn deinit(self: *App, plt: Platform.Deinit) void { level.world.deinit(plt.gpa); } self.levels.deinit(plt.gpa); + self.undo_stack.deinit(plt.gpa); } diff --git a/src/platform/graphics.zig b/src/platform/graphics.zig index 45ec422..b14d1db 100644 --- a/src/platform/graphics.zig +++ b/src/platform/graphics.zig @@ -90,6 +90,7 @@ pub fn init(gpa: std.mem.Allocator, logger: sg.Logger) !void { const pipeline = sg.makePipeline(.{ .primitive_type = .TRIANGLES, .index_type = .UINT16, + .cull_mode = .BACK, .colors = init: { var s: [8]sg.ColorTargetState = @splat(.{}); s[0] = .{ diff --git a/src/platform/root.zig b/src/platform/root.zig index fb21f8c..ee6d4d4 100644 --- a/src/platform/root.zig +++ b/src/platform/root.zig @@ -152,6 +152,7 @@ fn PlatformType(App: type) type { if (ImGUI.beginTabItem("General")) { defer ImGUI.endTabItem(); ImGUI.text("Embedded assets: {B}", .{self.assets.totalSize()}); + ImGUI.text("Graphics backend: {}", .{sg.queryBackend()}); } if (ImGUI.beginTabItem("Graphics")) {