From 585f72a4bdd7387e44f98badeaa3b521d49a8f11 Mon Sep 17 00:00:00 2001 From: Jake Date: Tue, 27 May 2025 21:57:39 -0400 Subject: [PATCH] Minor quality of life updates, pause, adjustable window, ability to place all block types. --- README.md | 10 +++ assets/TextureAtlas.png | Bin 5578 -> 6325 bytes assets/TextureAtlas.xcf | Bin 11947 -> 12726 bytes include/atlasDefinitions.h | 1 + include/blockTypes.h | 1 + include/chunkStructures.h | 2 +- source/blockTypes.c | 18 +++-- source/voxelThing.c | 141 ++++++++++++++++++++++++------------- 8 files changed, 112 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 3b06880..edb8c1d 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,15 @@ Implements a voxel chunk renderer. Chunks are stored as a 3D array of block stru Code is rough and messy and not much is implemented yet. +Controls: + - WASD - move + - Mouse - look + - LMB - Remove block + - RMB - Place Block + - ESC - Pause + - F11 - Fullscreen + - 1-8 - Select Block + Depends on Raylib. ## Build Instructions: @@ -12,4 +21,5 @@ Depends on Raylib. 1) Install Raylib. 2) Clone the repo. 3) Build by running make. +4) run bin/voxelThing diff --git a/assets/TextureAtlas.png b/assets/TextureAtlas.png index 50cca6d07acf39ad97432d8a01042c16c0742a6d..e90c0acc0654c4666137b2a8d865043f8892ab0e 100644 GIT binary patch literal 6325 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 CzZG-< literal 5578 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 lbQP4YV=xD^44c3dgJBz#?t;>NPIxpkG_is zgQuOnn+Jo7v#YC{tBa)_p^Iop5W)3b448B%2F1}vAcAgCG7S`TAZVW+Io*wot7XGdbp56?e z_HI6YZuMUF7S`_dj13HjiZTxEU&C;CJp;p*(!4?jhVngY(&N{sR~}?oo0DC*nqk$t z%F?1miOHGE7;+1;4=^z7i71QQQ5>J1ym?vSMsPr^%FkQ5YE5cs$qI%gC$=##>KZ6T|uKYibgTS28f{&&Xc2Z^ypb+ZZ;aX6@d) zp5aXTmd%BgsYh2a)Nk3vu(fdAo`dVQ7p7*e2M2_zlAs_zgP;HdgMgZfDg%SMAitu# zfTFq}1HZDe3O@rszq*<#pS*$+KZCN0vLFM4pp2TVfU3Nrf&jm&029Mseiaoa{>O@H zs{9OmLINOpegS0xK^b)c1_2dSegOu4ekP6U{OXDV4E2KiY69{C41)5SD*OWc4E*Xc zLJTSb3_|i6>H>U%{DRu50t`$7=LOYe)%n!a`IQyb1Q_^~R0RbT`32Qfgp`#87zFsW zH3ayD82D5*_*4WL_+$mtlmwUBoEPBNkXPkrU=UPN<`)zY6KI;~&^gU&=KJr_!^ zgwk6fGy}tA0sTFb74%sq&oh*m{6t@mx1NE4K@n6s*)uROOqMrjtk<0maWUAjV1j`` z_b|i&y~$8|K7 diff --git a/include/atlasDefinitions.h b/include/atlasDefinitions.h index a2ba30b..ebedf99 100644 --- a/include/atlasDefinitions.h +++ b/include/atlasDefinitions.h @@ -14,5 +14,6 @@ #define TILE_LOG_TOP 6 #define TILE_LOG_SIDE 7 #define TILE_LEAF 8 +#define TILE_PLANK 9 #endif diff --git a/include/blockTypes.h b/include/blockTypes.h index 36eb485..44bf5cf 100644 --- a/include/blockTypes.h +++ b/include/blockTypes.h @@ -11,6 +11,7 @@ #define BLOCK_GRAVEL 5 // 5 #define BLOCK_LOG 6 // top 6, sides 7, bottom 6 #define BLOCK_LEAF 7 // 8 +#define BLOCK_PLANK 8 // 9 typedef struct { int id; diff --git a/include/chunkStructures.h b/include/chunkStructures.h index c4d4a37..1918df2 100644 --- a/include/chunkStructures.h +++ b/include/chunkStructures.h @@ -6,7 +6,7 @@ #include "raylib.h" #define CHUNK_SIZE_X 16 -#define CHUNK_SIZE_Y 16 +#define CHUNK_SIZE_Y 256 #define CHUNK_SIZE_Z 16 diff --git a/source/blockTypes.c b/source/blockTypes.c index fa9ce4f..862e04e 100644 --- a/source/blockTypes.c +++ b/source/blockTypes.c @@ -37,16 +37,9 @@ static const BlockType blockTable[] = { .faceTiles = { TILE_SAND, TILE_SAND, TILE_SAND, TILE_SAND, TILE_SAND, TILE_SAND } }, [BLOCK_GRAVEL] = { - .id = BLOCK_GRASS, - .name = "Grass", - .faceTiles = { - TILE_GRASS_SIDE, // -X - TILE_GRASS_SIDE, // +X - TILE_DIRT, // -Y - TILE_GRASS_TOP, // +Y - TILE_GRASS_SIDE, // -Z - TILE_GRASS_SIDE // +Z - } + .id = BLOCK_GRAVEL, + .name = "Gravel", + .faceTiles = { TILE_GRAVEL, TILE_GRAVEL, TILE_GRAVEL, TILE_GRAVEL, TILE_GRAVEL, TILE_GRAVEL } }, [BLOCK_LOG] = { .id = BLOCK_LOG, @@ -65,6 +58,11 @@ static const BlockType blockTable[] = { .name = "Leaves", .faceTiles = { TILE_LEAF, TILE_LEAF, TILE_LEAF, TILE_LEAF, TILE_LEAF, TILE_LEAF } }, + [BLOCK_PLANK] = { + .id = BLOCK_PLANK, + .name = "Planks", + .faceTiles = { TILE_PLANK, TILE_PLANK, TILE_PLANK, TILE_PLANK, TILE_PLANK, TILE_PLANK } + }, }; const BlockType *GetBlockType(int blockID) { diff --git a/source/voxelThing.c b/source/voxelThing.c index 9af4648..95f04fb 100644 --- a/source/voxelThing.c +++ b/source/voxelThing.c @@ -14,9 +14,14 @@ #include "playerController.h" #include "chunkGenerator.h" +// Bunch of global variables to clean up later. float cameraYaw = 0; float cameraPitch = 0; +bool paused = false; +RaycastHit hit; +int blockSelection = BLOCK_SAND; +// Random helper function for returning what direction you're facing.' const char* GetCompassDirection(float yaw) { yaw = fmodf(yaw * RAD2DEG + 360.0f, 360.0f); if (yaw < 22.5f || yaw >= 337.5f) return "South (+Z)"; @@ -29,11 +34,18 @@ const char* GetCompassDirection(float yaw) { return "Southeast (-X+Z)"; } +// Another random helper function, this time for checking if a Vector3 is non-zero. +static inline bool Vector3IsNonZero(Vector3 v) { + return v.x != 0.0f || v.y != 0.0f || v.z != 0.0f; +} + int main(void) { // --- Screen setup --- - const int screenWidth = 800; - const int screenHeight = 600; + int screenWidth = 800; + int screenHeight = 600; + SetConfigFlags(FLAG_WINDOW_RESIZABLE); InitWindow(screenWidth, screenHeight, "VoxelThing"); + SetExitKey(-1); DisableCursor(); // Lock mouse to window for FPS-style camera // --- World generation --- @@ -52,68 +64,97 @@ int main(void) { camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Initial camera position camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Looking toward origin camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Y-up world - camera.fovy = 45.0f; // Field of view + camera.fovy = 90.0f; // Field of view camera.projection = CAMERA_PERSPECTIVE; // Use perspective projection SetTargetFPS(60); // --- Main game loop --- while (!WindowShouldClose()) { + screenWidth = GetScreenWidth(); + screenHeight = GetScreenHeight(); BeginDrawing(); ClearBackground(RAYWHITE); - // --- Update camera and direction --- - - UpdateFreeCamera(&camera, 10.0f, &cameraYaw, &cameraPitch); // Move camera with user input - - - // --- Raycasting from screen center --- - Vector2 screenCenter = { screenWidth / 2.0f, screenHeight / 2.0f }; - // This is where we grab the ray... - // Ray ray = GetMouseRay(screenCenter, camera); - Vector3 camDir = { - cosf(cameraPitch) * sinf(cameraYaw), - sinf(cameraPitch), - cosf(cameraPitch) * cosf(cameraYaw) - }; - - Ray ray = { - .position = camera.position, - .direction = Vector3Normalize(camDir) - }; - RaycastHit hit = RaycastChunk(&chunk, ray.position, ray.direction, 10.0f); - - // --- Begin 3D rendering --- - BeginMode3D(camera); - - DrawMesh(chunkMesh, mat, MatrixIdentity()); - - if (hit.hit) { - // Draw a wireframe cube where the ray hit - DrawCubeWires(Vector3Add(hit.position, (Vector3){0.5f, 0.5f, 0.5f}), 1.02f, 1.02f, 1.02f, RED); - DrawFaceHighlight(hit.position, hit.normal); // Highlight the specific face hit + // --- Handle jumping to fullscreen mode with F11 --- + if (IsKeyPressed(KEY_F11)) { + ToggleFullscreen(); + Vector2 center = { GetScreenWidth() / 2.0f, GetScreenHeight() / 2.0f }; + SetMousePosition(center.x, center.y); } - // Draw debug ray. - camDir = Vector3Normalize(Vector3Subtract(camera.target, camera.position)); - Vector3 rayEnd = Vector3Add(camera.position, Vector3Scale(camDir, 10.0f)); - DrawLine3D(camera.position, rayEnd, PURPLE); - Vector3 hitPoint = Vector3Add(ray.position, Vector3Scale(ray.direction, hit.t)); - DrawCubeWires(hitPoint, 0.05f, 0.05f, 0.05f, RED); + // --- Handle pausing --- + if (IsKeyPressed(KEY_ESCAPE)) { + paused = !paused; + if (paused) EnableCursor(); + else DisableCursor(); + } - EndMode3D(); + // --- Handle selecting blocks --- - Vector3 testPoint = Vector3Add(camera.position, Vector3Scale(camDir, 2.0f)); - Vector2 projected = GetWorldToScreen(testPoint, camera); - DrawCircleV(projected, 4, RED); + if (IsKeyPressed(KEY_ONE)) blockSelection = BLOCK_STONE; + if (IsKeyPressed(KEY_TWO)) blockSelection = BLOCK_DIRT; + if (IsKeyPressed(KEY_THREE)) blockSelection = BLOCK_GRASS; + if (IsKeyPressed(KEY_FOUR)) blockSelection = BLOCK_SAND; + if (IsKeyPressed(KEY_FIVE)) blockSelection = BLOCK_GRAVEL; + if (IsKeyPressed(KEY_SIX)) blockSelection = BLOCK_LOG; + if (IsKeyPressed(KEY_SEVEN)) blockSelection = BLOCK_LEAF; + if (IsKeyPressed(KEY_EIGHT)) blockSelection = BLOCK_PLANK; - // --- Draw crosshair in screen center --- - DrawLine(screenWidth/2 - 5, screenHeight/2, screenWidth/2 + 5, screenHeight/2, DARKGRAY); - DrawLine(screenWidth/2, screenHeight/2 - 5, screenWidth/2, screenHeight/2 + 5, DARKGRAY); + if (!paused) { + // --- Update camera and direction --- - // -- Draw debug info --- - DrawText(TextFormat("Facing: %s", GetCompassDirection(cameraYaw)), 10, 10, 20, DARKGRAY); - DrawText(TextFormat("Yaw: %.1f° Pitch: %.1f°", cameraYaw * RAD2DEG, cameraPitch * RAD2DEG), 10, 30, 20, GRAY); + UpdateFreeCamera(&camera, 10.0f, &cameraYaw, &cameraPitch); // Move camera with user input + + + // --- Raycasting from screen center --- + Vector2 screenCenter = { screenWidth / 2.0f, screenHeight / 2.0f }; + // This is where we grab the ray... + // Ray ray = GetMouseRay(screenCenter, camera); + Vector3 camDir = { + cosf(cameraPitch) * sinf(cameraYaw), + sinf(cameraPitch), + cosf(cameraPitch) * cosf(cameraYaw) + }; + + Ray ray = { + .position = camera.position, + .direction = Vector3Normalize(camDir) + }; + hit = RaycastChunk(&chunk, ray.position, ray.direction, 10.0f); + + // --- Begin 3D rendering --- + BeginMode3D(camera); + + DrawMesh(chunkMesh, mat, MatrixIdentity()); + + if (hit.hit) { + // Draw a wireframe cube where the ray hit + DrawCubeWires(Vector3Add(hit.position, (Vector3){0.5f, 0.5f, 0.5f}), 1.02f, 1.02f, 1.02f, BLACK); + //DrawFaceHighlight(hit.position, hit.normal); // Highlight the specific face hit + } + + // Draw a lil debug cube where the player is looking. + //Vector3 hitPoint = Vector3Add(ray.position, Vector3Scale(ray.direction, hit.t)); + //DrawCubeWires(hitPoint, 0.05f, 0.05f, 0.05f, RED); + + EndMode3D(); + + // --- Draw crosshair in screen center --- + DrawLine(screenWidth/2 - 5, screenHeight/2, screenWidth/2 + 5, screenHeight/2, DARKGRAY); + DrawLine(screenWidth/2, screenHeight/2 - 5, screenWidth/2, screenHeight/2 + 5, DARKGRAY); + + // -- Draw debug info --- + DrawText(TextFormat("Facing: %s", GetCompassDirection(cameraYaw)), 10, 10, 20, DARKGRAY); + DrawText(TextFormat("Yaw: %.1f° Pitch: %.1f°", cameraYaw * RAD2DEG, cameraPitch * RAD2DEG), 10, 30, 20, GRAY); + } + + // --- Draw pause menu if paused --- + if (paused) { + DrawRectangle(0, 0, screenWidth, screenHeight, Fade(DARKGRAY, 0.5f)); + DrawText("Paused", screenWidth / 2 - MeasureText("Paused", 40) / 2, screenHeight / 2 - 20, 40, RAYWHITE); + DrawText("Press ESC to resume", screenWidth / 2 - MeasureText("Press ESC to resume", 20) / 2, screenHeight / 2 + 30, 20, LIGHTGRAY); + } EndDrawing(); @@ -136,7 +177,7 @@ int main(void) { py >= 0 && py < CHUNK_SIZE_Y && pz >= 0 && pz < CHUNK_SIZE_Z) { - chunk.blocks[px][py][pz].type = BLOCK_SAND; + chunk.blocks[px][py][pz].type = blockSelection; chunkMesh = GenerateChunkMesh(&chunk); printf("Hit at (%f %f %f), normal (%f %f %f), placing at (%d %d %d)\n",