diff --git a/PlayBark.csproj b/PlayBark.csproj
index 8ae31a4..7d42e75 100644
--- a/PlayBark.csproj
+++ b/PlayBark.csproj
@@ -4,6 +4,7 @@
Exe
net8.0
enable
+ true
enable
diff --git a/Program.cs b/Program.cs
index b87b1e4..dc73294 100644
--- a/Program.cs
+++ b/Program.cs
@@ -5,7 +5,7 @@
///
/// The name of the configuration file (defaults to "config.toml").
/// A Config object populated with values from the file, or a default Config instance if the file is not found.
-static Config ReadConfig(string file)
+static Config Settings(string file)
{
var cfgPath = Path.Combine(Tracer.AppDirectory, file);
@@ -28,35 +28,116 @@ static Config ReadConfig(string file)
return model;
}
-void Init(int screenWidth, int screenHeight, int fps)
+// Update and Draw
+unsafe int Game()
{
+ var config = Settings("config.toml");
+ InitWindow(config.Width, config.Height, "PlayBark");
+
var pos = new Vector3(0.2f, 0.4f, 0.2f);
var target = new Vector3(0.0f, 0.0f, 0.0f);
var up = new Vector3(0.0f, 1.0f, 0.0f);
+ var camera = World3D.Camera(pos, target, up, CameraProjection.Perspective);
- InitWindow(screenWidth, screenHeight, $"PlayBark");
- World3D.InitCamera(pos, target, up, CameraProjection.Perspective);
- SetTargetFPS(fps);
-}
+ var imMap = LoadImage("resources/cubicmap.png");
+ var cubicmap = LoadTextureFromImage(imMap);
+ var model = World3D.CubicMap(imMap);
-int GameLoop()
-{
- var config = ReadConfig("config.toml");
- Init(config.Width, config.Height, 60);
+ var texture = LoadTexture("resources/cubicmap_atlas.png");
+
+ // Set map diffuse texture
+ Raylib.SetMaterialTexture(ref model, 0, MaterialMapIndex.Albedo, ref texture);
+
+ // Get image map data to be used for collission
+ var mapPixels = LoadImageColors(imMap);
+ UnloadImage(imMap);
+
+ var mapPosition = new Vector3(-16.0f, 0.0f, -8.0f);
+ var playerPosition = camera.Position;
+
+ SetTargetFPS(60);
while (!WindowShouldClose())
{
+ // Update
+ var oldCamPos = camera.Position;
+ UpdateCamera(ref camera, CameraMode.FirstPerson);
+
+ var playerPos = new Vector2(camera.Position.X, camera.Position.Z);
+
+ var playerRadius = 0.1f;
+
+ var playerCellX = (int)(playerPos.X - mapPosition.X + 0.5f);
+ var playerCellY = (int)(playerPos.Y - mapPosition.Z + 0.5f);
+
+ // Out-of-limits security check
+ if (playerCellX < 0)
+ {
+ playerCellX = 0;
+ }
+ else if (playerCellX >= cubicmap.Width)
+ {
+ playerCellX = cubicmap.Width - 1;
+ }
+
+ if (playerCellY < 0)
+ {
+ playerCellY = 0;
+ }
+ else if (playerCellY >= cubicmap.Height)
+ {
+ playerCellY = cubicmap.Height - 1;
+ }
+
+ for (var y = 0; y < cubicmap.Height; y++)
+ {
+ for (var x = 0; y < cubicmap.Width; x++)
+ {
+ var mapPixelsData = mapPixels;
+ var rec = new Rectangle(
+ mapPosition.X - x - 0.5f + x * 1.0f,
+ mapPosition.Y - y - 0.5f + x * 1.0f,
+ 1.0f,
+ 1.0f
+ );
+
+ var collision = CheckCollisionCircleRec(playerPos, playerRadius, rec);
+ if ((mapPixelsData[y * cubicmap.Width + x].R == 255) && collision)
+ {
+ // Collision detected, reset camera position
+ camera.Position = oldCamPos;
+ }
+ }
+ }
+
BeginDrawing();
- ClearBackground(Color.White);
+ ClearBackground(Color.RayWhite);
+ BeginMode3D(camera);
+ DrawModel(model, mapPosition, 1.0f, Color.White);
+ EndMode3D();
+
+ DrawTextureEx(cubicmap, new Vector2(GetScreenWidth() - cubicmap.Width * 4 - 20, 20), 0.0f, 4.0f, Color.White);
+ DrawRectangleLines(GetScreenWidth() - cubicmap.Width * 4 - 20, 20, cubicmap.Width * 4, cubicmap.Height * 4, Color.Green);
+
+ // Draw player position radar
+ DrawRectangle(GetScreenWidth() - cubicmap.Width * 4 - 20 + playerCellX * 4, 20 + playerCellY * 4, 4, 4, Color.Red);
+
DrawFPS(10, 10);
EndDrawing();
}
+ UnloadImageColors(mapPixels);
+
+ UnloadTexture(cubicmap);
+ UnloadTexture(texture);
+ UnloadModel(model);
+
CloseWindow();
return 0;
}
-GameLoop();
+// Entry point
+Game();
diff --git a/World3D.cs b/World3D.cs
index 7932cd9..be70601 100644
--- a/World3D.cs
+++ b/World3D.cs
@@ -1,11 +1,22 @@
// I hereby waive this project under the public domain - see UNLICENSE for details.
namespace PlayBark;
+///
+/// Provides utilities for creating and managing 3D world elements, including camera setup and map generation.
+///
internal static class World3D
{
- public static Camera3D InitCamera(Vector3 pos, Vector3 target, Vector3 up, CameraProjection projection)
+ ///
+ /// Creates and returns a configured Camera3D instance.
+ ///
+ /// The position of the camera in 3D space.
+ /// The point the camera is looking at.
+ /// The up direction for the camera.
+ /// The projection type of the camera.
+ /// A configured Camera3D instance.
+ public static Camera3D Camera(Vector3 pos, Vector3 target, Vector3 up, CameraProjection projection)
{
- Camera3D camera = new();
+ var camera = new Camera3D();
camera.Position = pos;
camera.Target = target;
camera.Up = up;
@@ -14,4 +25,17 @@ internal static class World3D
return camera;
}
+
+ ///
+ /// Generates a 3D cubic map model from a given image map.
+ ///
+ /// The image used to generate the cubic map.
+ /// A Model representing the cubic map.
+ public static Model CubicMap(Image imMap)
+ {
+ var mesh = GenMeshCubicmap(imMap, new Vector3(1.0f, 1.0f, 1.0f));
+ var model = LoadModelFromMesh(mesh);
+
+ return model;
+ }
}
\ No newline at end of file
diff --git a/resources/cubicmap_atlas.png b/resources/cubicmap_atlas.png
new file mode 100644
index 0000000..9fc404a
Binary files /dev/null and b/resources/cubicmap_atlas.png differ