From c426dd2d9c45e75f0fdcc151a02c8a0f612e677a Mon Sep 17 00:00:00 2001 From: speckitor Date: Sun, 5 Jul 2026 22:37:41 +0700 Subject: [PATCH] grab and move cube --- src/cube.c | 19 ++++++++++ src/cube.h | 20 +++++++++++ src/level00.c | 39 +++++++++++++++++---- src/main.c | 47 +++++++++++++------------ src/player.c | 96 +++++++++++++++++++++++++++++++++++++++++++-------- src/player.h | 15 ++++++-- src/screen.h | 6 ++-- 7 files changed, 194 insertions(+), 48 deletions(-) create mode 100644 src/cube.c create mode 100644 src/cube.h diff --git a/src/cube.c b/src/cube.c new file mode 100644 index 0000000..91c85bf --- /dev/null +++ b/src/cube.c @@ -0,0 +1,19 @@ +#include "cube.h" + +void MyDrawCube(Cube *cube) +{ + if (!cube->grabbed && cube->position.y > cube->edge/2.0f) + { + float delta = GetFrameTime(); + cube->yvel -= delta*32.0f; + cube->position.y += cube->yvel*delta; + if (cube->position.y <= cube->edge/2.0f) + { + cube->position.y = cube->edge/2.0f; + cube->yvel = 0.0f; + } + } + + DrawModelEx(cube->model, cube->position, (Vector3){ 0.0f, 1.0f, 0.0f }, cube->hRotation, (Vector3){ 1.0f, 1.0f, 1.0f }, cube->color); + DrawModelWiresEx(cube->model, cube->position, (Vector3){ 0.0f, 1.0f, 0.0f }, cube->hRotation, (Vector3){ 1.0f, 1.0f, 1.0f }, cube->wiresColor); +} diff --git a/src/cube.h b/src/cube.h new file mode 100644 index 0000000..7230c3c --- /dev/null +++ b/src/cube.h @@ -0,0 +1,20 @@ +#ifndef CUBE_H +#define CUBE_H + +#include "raylib.h" + +typedef struct { + bool initialized; + Model model; + Vector3 position; + float edge; + Color color; + Color wiresColor; + bool grabbed; + float yvel; + float hRotation; +} Cube; + +void MyDrawCube(Cube *cube); + +#endif // CUBE_H diff --git a/src/level00.c b/src/level00.c index 3d57c79..aca5a13 100644 --- a/src/level00.c +++ b/src/level00.c @@ -1,22 +1,47 @@ +#include +#include #include "raylib.h" +#include "cube.h" +#include "player.h" #include "screen.h" -void DrawLevel00() +Cube cube = { + .initialized = false, + .position = (Vector3){ 0.0f, 0.5f, 0.0f }, + .edge = 1.0f, + .color = RED, + .wiresColor = BLACK, + .grabbed = false, +}; + +void DrawLevel00(Player *player) { + if (!cube.initialized) + { + cube.model = LoadModelFromMesh(GenMeshCube(1.0f, 1.0f, 1.0f)); + cube.initialized = true; + } + const int floorExtent = 25; const float tileSize = 5.0f; - + // Draw floor - for (int y = -floorExtent; y < floorExtent; y++) { - for (int x = -floorExtent; x < floorExtent; x++) { - if ((y & 1) ^ (x & 1)) { + for (int y = -floorExtent; y < floorExtent; y++) + { + for (int x = -floorExtent; x < floorExtent; x++) + { + if ((y & 1) ^ (x & 1)) + { DrawPlane((Vector3){ x*tileSize, 0.0f, y*tileSize}, (Vector2){ tileSize, tileSize }, LIGHTGRAY); - } + } } } - DrawPlane((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector2){ 32.0f, 32.0f }, LIGHTGRAY); // Draw ground DrawCube((Vector3){ -16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, BLUE); // Draw a blue wall DrawCube((Vector3){ 16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, GREEN); // Draw a green wall DrawCube((Vector3){ 0.0f, 2.5f, 16.0f }, 32.0f, 5.0f, 1.0f, YELLOW); // Draw a yellow wall + + UpdateGrab(player, &cube); // Check if we grabbed a cube + + MyDrawCube(&cube); // Draw a cube } diff --git a/src/main.c b/src/main.c index 4abd4cc..a9b3912 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,4 @@ +#include #include "raylib.h" #include "raymath.h" #include "screen.h" @@ -16,21 +17,24 @@ int main() { InitWindow(800, 600, "Super cool game"); - Body player = {0}; + Player player = {0}; + Camera *camera = &player.camera; + Body *body = &player.body; + player.grab = NULL; + Vector2 sensitivity = { 0.001f, 0.001f }; float headLerp = STAND_HEIGHT; - Camera3D camera = { 0 }; - camera.fovy = 60.0f; - camera.projection = CAMERA_PERSPECTIVE; - camera.position = (Vector3) { - player.position.x, - player.position.y + (BOTTOM_HEIGHT + headLerp), - player.position.z, + camera->fovy = 75.0f; + camera->projection = CAMERA_PERSPECTIVE; + camera->position = (Vector3) { + body->position.x, + body->position.y + (BOTTOM_HEIGHT + headLerp), + body->position.z, }; - UpdateFpsCamera(&camera); + UpdateFpsCamera(&player); DisableCursor(); SetTargetFPS(GAME_FPS); @@ -39,45 +43,44 @@ int main() Vector2 mouseDelta = GetMouseDelta(); lookRotation.x -= mouseDelta.x*sensitivity.x; lookRotation.y += mouseDelta.y*sensitivity.y; - + char sideway = (IsKeyDown(KEY_D) - IsKeyDown(KEY_A)); char forward = (IsKeyDown(KEY_W) - IsKeyDown(KEY_S)); bool crouching = IsKeyDown(KEY_LEFT_CONTROL); UpdateBody(&player, lookRotation.x, sideway, forward, IsKeyPressed(KEY_SPACE), crouching); - + float delta = GetFrameTime(); headLerp = Lerp(headLerp, (crouching ? CROUCH_HEIGHT : STAND_HEIGHT), 20.0f*delta); - camera.position = (Vector3){ - player.position.x, - player.position.y + (BOTTOM_HEIGHT + headLerp), - player.position.z, + camera->position = (Vector3){ + body->position.x, + body->position.y + (BOTTOM_HEIGHT + headLerp), + body->position.z, }; - if (player.grounded && ((forward != 0) || (sideway != 0))) { + if (body->grounded && ((forward != 0) || (sideway != 0))) { headTimer += delta*3.0f; walkLerp = Lerp(walkLerp, 1.0f, 10.0f*delta); - camera.fovy = Lerp(camera.fovy, 55.0f, 5.0f*delta); + camera->fovy = Lerp(camera->fovy, 55.0f, 5.0f*delta); } else { walkLerp = Lerp(walkLerp, 0.0f, 10.0f*delta); - camera.fovy = Lerp(camera.fovy, 60.0f, 5.0f*delta); + camera->fovy = Lerp(camera->fovy, 60.0f, 5.0f*delta); } lean.x = Lerp(lean.x, sideway*0.02f, 10.0f*delta); lean.y = Lerp(lean.y, forward*0.015f, 10.0f*delta); - UpdateFpsCamera(&camera); + UpdateFpsCamera(&player); BeginDrawing(); ClearBackground(RAYWHITE); - BeginMode3D(camera); - DrawLevel00(); + BeginMode3D(*camera); + DrawLevel00(&player); EndMode3D(); DrawFPS(10, 10); - EndDrawing(); } diff --git a/src/player.c b/src/player.c index 4045834..af5a6bf 100644 --- a/src/player.c +++ b/src/player.c @@ -1,3 +1,4 @@ +#include #include "raylib.h" #include "raymath.h" #include "player.h" @@ -7,23 +8,26 @@ Vector2 lean = {0}; float headTimer = 0.0f; float walkLerp = 0.0f; -void UpdateFpsCamera(Camera *camera) + +void UpdateFpsCamera(Player *player) { + Camera *camera = &player->camera; + const Vector3 up = (Vector3){ 0.0f, 1.0f, 0.0f }; const Vector3 targetOffset = (Vector3){ 0.0f, 0.0f, -1.0f }; - + Vector3 yaw = Vector3RotateByAxisAngle(targetOffset, up, lookRotation.x); - + float maxAngleUp = Vector3Angle(up, yaw); - maxAngleUp -= 0.001f; + maxAngleUp -= 0.001f; if ( -(lookRotation.y) > maxAngleUp) { lookRotation.y = -maxAngleUp; } Vector3 right = Vector3Normalize(Vector3CrossProduct(yaw, up)); - + float pitchAngle = -lookRotation.y - lean.y; - pitchAngle = Clamp(pitchAngle, -PI/2 + 0.0001f, PI/2 - 0.0001f); + pitchAngle = Clamp(pitchAngle, -PI/2 + 0.0001f, PI/2 - 0.0001f); Vector3 pitch = Vector3RotateByAxisAngle(yaw, right, pitchAngle); - + float headSin = sinf(headTimer*PI); float headCos = cosf(headTimer*PI); const float stepRotation = 0.01f; @@ -36,14 +40,30 @@ void UpdateFpsCamera(Camera *camera) camera->position = Vector3Add(camera->position, Vector3Scale(bobbing, walkLerp)); camera->target = Vector3Add(camera->position, pitch); + + if (player->grab) + { + Vector3 forward = Vector3Subtract(camera->target, camera->position); + forward = Vector3Normalize(forward); + Vector3 cubePosition = Vector3Add(camera->target, forward); + player->grab->position = cubePosition; + if (player->grab->position.y <= player->grab->edge/2.0f) + { + player->grab->position.y = player->grab->edge/2.0f; + } + player->grab->hRotation = lookRotation.x * RAD2DEG; + } + } -void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed, bool crouchHold) +void UpdateBody(Player *player, float rot, char side, char forward, bool jumpPressed, bool crouchHold) { + Body *body = &player->body; + Vector2 input = (Vector2){ (float)side, (float)-forward }; -#if defined(NORMALIZE_INPUT) // Slow down diagonal movement +#if defined(NORMALIZE_INPUT) if ((side != 0) && (forward != 0)) input = Vector2Normalize(input); #endif @@ -57,8 +77,8 @@ void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed body->grounded = false; // Sound can be played at this moment - //SetSoundPitch(fxJump, 1.0f + (GetRandomValue(-100, 100)*0.001)); - //PlaySound(fxJump); + // SetSoundPitch(fxJump, 1.0f + (GetRandomValue(-100, 100)*0.001)); + // PlaySound(fxJump); } Vector3 front = (Vector3){ sinf(rot), 0.f, cosf(rot) }; @@ -84,9 +104,21 @@ void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed body->velocity.x = hvel.x; body->velocity.z = hvel.z; - body->position.x += body->velocity.x*delta; - body->position.y += body->velocity.y*delta; - body->position.z += body->velocity.z*delta; + float diffx = body->velocity.x*delta; + float diffy = body->velocity.y*delta; + float diffz = body->velocity.z*delta; + + body->position.x += diffx; + body->position.y += diffy; + body->position.z += diffz; + + if (player->grab) + { + Cube *cube = player->grab; + cube->position.x += diffx; + cube->position.y += diffy; + cube->position.z += diffz; + } // Fancy collision system against the floor if (body->position.y <= 0.0f) @@ -96,3 +128,39 @@ void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed body->grounded = true; // Enable jumping } } + +void UpdateGrab(Player *player, Cube *cube) +{ + if (IsMouseButtonUp(0)) + { + if (player->grab) + { + player->grab->color = RED; + player->grab->grabbed = false; + player->grab = NULL; + } + return; + } + + if (player->grab) + { + return; + } + + float halfEdge = cube->edge/2; + BoundingBox cubeBox = { + (Vector3){ cube->position.x - halfEdge, cube->position.y - halfEdge, cube->position.z - halfEdge }, + (Vector3){ cube->position.x + halfEdge, cube->position.y + halfEdge, cube->position.z + halfEdge } + }; + + Vector2 screenCenter = { (float)GetScreenWidth()/2.0f, (float)GetScreenHeight()/2.0f}; + Ray lookRay = GetScreenToWorldRay(screenCenter, player->camera); + RayCollision collision = GetRayCollisionBox(lookRay, cubeBox); + + if (collision.hit && collision.distance <= 2.5f) + { + cube->color = BLUE; + player->grab = cube; + cube->grabbed = true; + } +} diff --git a/src/player.h b/src/player.h index 7a0c87f..13aa963 100644 --- a/src/player.h +++ b/src/player.h @@ -3,6 +3,7 @@ #include #include "raylib.h" +#include "cube.h" #define GRAVITY 32.0f #define MAX_SPEED 20.0f @@ -20,10 +21,18 @@ typedef struct { Vector3 position; Vector3 velocity; Vector3 dir; - bool grounded; + bool grounded; } Body; -void UpdateFpsCamera(Camera *camera); -void UpdateBody(Body *body, float rot, char side, char forward, bool jump, bool crouch); +typedef struct { + Body body; + Camera camera; + Cube *grab; +} Player; + +void UpdateFpsCamera(Player *player); +void UpdateBody(Player *player, float rot, char side, char forward, bool jump, bool crouch); + +void UpdateGrab(Player *player, Cube *cube); #endif diff --git a/src/screen.h b/src/screen.h index 63b2840..26eed10 100644 --- a/src/screen.h +++ b/src/screen.h @@ -1,9 +1,11 @@ #ifndef SCREEN_H #define SCREEN_H -#define GAME_FPS 60 +#include "player.h" + +#define GAME_FPS 60 #define MAX_COLUMNS 20 -void DrawLevel00(); +void DrawLevel00(Player *player); #endif