add fps camera

This commit is contained in:
2026-07-05 12:42:34 +03:00
parent d146abbc05
commit 54a2775f28
5 changed files with 192 additions and 24 deletions
+6 -18
View File
@@ -5,7 +5,8 @@ void DrawLevel00()
{ {
const int floorExtent = 25; const int floorExtent = 25;
const float tileSize = 5.0f; const float tileSize = 5.0f;
// Draw floor
for (int y = -floorExtent; y < floorExtent; y++) { for (int y = -floorExtent; y < floorExtent; y++) {
for (int x = -floorExtent; x < floorExtent; x++) { for (int x = -floorExtent; x < floorExtent; x++) {
if ((y & 1) ^ (x & 1)) { if ((y & 1) ^ (x & 1)) {
@@ -14,21 +15,8 @@ void DrawLevel00()
} }
} }
const Vector3 towerSize = (Vector3){ 16.0f, 32.0f, 16.0f }; 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
Vector3 towerPos = (Vector3){ 16.0f, 16.0f, 16.0f }; DrawCube((Vector3){ 16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, GREEN); // Draw a green wall
DrawCubeV(towerPos, towerSize, RED); DrawCube((Vector3){ 0.0f, 2.5f, 16.0f }, 32.0f, 5.0f, 1.0f, YELLOW); // Draw a yellow wall
DrawCubeWiresV(towerPos, towerSize, BLACK);
towerPos.x *= -1;
DrawCubeV(towerPos, towerSize, RED);
DrawCubeWiresV(towerPos, towerSize, BLACK);
towerPos.z *= -1;
DrawCubeV(towerPos, towerSize, RED);
DrawCubeWiresV(towerPos, towerSize, BLACK);
towerPos.x *= -1;
DrawCubeV(towerPos, towerSize, RED);
DrawCubeWiresV(towerPos, towerSize, BLACK);
} }
+58 -6
View File
@@ -1,21 +1,73 @@
#include "raylib.h" #include "raylib.h"
#include "raymath.h"
#include "screen.h" #include "screen.h"
#include "player.h"
extern Vector2 lookRotation;
extern Vector2 lean;
extern float headTimer;
extern float walkLerp;
static float heights[MAX_COLUMNS] = {0};
static Vector3 positions[MAX_COLUMNS] = {0};
static Color colors[MAX_COLUMNS] = {0};
int main() int main()
{ {
InitWindow(800, 600, "Super cool game"); InitWindow(800, 600, "Super cool game");
SetTargetFPS(GAME_FPS);
Body player = {0};
Vector2 sensitivity = { 0.001f, 0.001f };
float headLerp = STAND_HEIGHT;
Camera3D camera = { 0 }; Camera3D camera = { 0 };
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f };
camera.target = (Vector3){ 0.0f, 12.0f, 0.0f };
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
camera.fovy = 60.0f; camera.fovy = 60.0f;
camera.projection = CAMERA_PERSPECTIVE; camera.projection = CAMERA_PERSPECTIVE;
camera.position = (Vector3) {
player.position.x,
player.position.y + (BOTTOM_HEIGHT + headLerp),
player.position.z,
};
UpdateFpsCamera(&camera);
DisableCursor();
SetTargetFPS(GAME_FPS);
while (!WindowShouldClose()) { while (!WindowShouldClose()) {
UpdateCamera(&camera, CAMERA_FREE); Vector2 mouseDelta = GetMouseDelta();
DisableCursor(); 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,
};
if (player.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);
}
else {
walkLerp = Lerp(walkLerp, 0.0f, 10.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);
BeginDrawing(); BeginDrawing();
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
+98
View File
@@ -0,0 +1,98 @@
#include "raylib.h"
#include "raymath.h"
#include "player.h"
Vector2 lookRotation = {0};
Vector2 lean = {0};
float headTimer = 0.0f;
float walkLerp = 0.0f;
void UpdateFpsCamera(Camera *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;
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);
Vector3 pitch = Vector3RotateByAxisAngle(yaw, right, pitchAngle);
float headSin = sinf(headTimer*PI);
float headCos = cosf(headTimer*PI);
const float stepRotation = 0.01f;
camera->up = Vector3RotateByAxisAngle(up, pitch, headSin*stepRotation + lean.x);
const float bobSide = 0.1f;
const float bobUp = 0.15f;
Vector3 bobbing = Vector3Scale(right, headSin*bobSide);
bobbing.y = fabsf(headCos*bobUp);
camera->position = Vector3Add(camera->position, Vector3Scale(bobbing, walkLerp));
camera->target = Vector3Add(camera->position, pitch);
}
void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed, bool crouchHold)
{
Vector2 input = (Vector2){ (float)side, (float)-forward };
#if defined(NORMALIZE_INPUT)
// Slow down diagonal movement
if ((side != 0) && (forward != 0)) input = Vector2Normalize(input);
#endif
float delta = GetFrameTime();
if (!body->grounded) body->velocity.y -= GRAVITY*delta;
if (body->grounded && jumpPressed)
{
body->velocity.y = JUMP_FORCE;
body->grounded = false;
// Sound can be played at this moment
//SetSoundPitch(fxJump, 1.0f + (GetRandomValue(-100, 100)*0.001));
//PlaySound(fxJump);
}
Vector3 front = (Vector3){ sinf(rot), 0.f, cosf(rot) };
Vector3 right = (Vector3){ cosf(-rot), 0.f, sinf(-rot) };
Vector3 desiredDir = (Vector3){ input.x*right.x + input.y*front.x, 0.0f, input.x*right.z + input.y*front.z, };
body->dir = Vector3Lerp(body->dir, desiredDir, CONTROL*delta);
float decel = (body->grounded ? FRICTION : AIR_DRAG);
Vector3 hvel = (Vector3){ body->velocity.x*decel, 0.0f, body->velocity.z*decel };
float hvelLength = Vector3Length(hvel); // Magnitude
if (hvelLength < (MAX_SPEED*0.01f)) hvel = (Vector3){ 0 };
// This is what creates strafing
float speed = Vector3DotProduct(hvel, body->dir);
float maxSpeed = (crouchHold? CROUCH_SPEED : MAX_SPEED);
float accel = Clamp(maxSpeed - speed, 0.f, MAX_ACCEL*delta);
hvel.x += body->dir.x*accel;
hvel.z += body->dir.z*accel;
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;
// Fancy collision system against the floor
if (body->position.y <= 0.0f)
{
body->position.y = 0.0f;
body->velocity.y = 0.0f;
body->grounded = true; // Enable jumping
}
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef PLAYER_H
#define PLAYER_H
#include <stdbool.h>
#include "raylib.h"
#define GRAVITY 32.0f
#define MAX_SPEED 20.0f
#define CROUCH_SPEED 5.0f
#define JUMP_FORCE 12.0f
#define CONTROL 15.0f
#define MAX_ACCEL 150.0f
#define FRICTION 0.86f
#define AIR_DRAG 0.98f
#define BOTTOM_HEIGHT 0.5f
#define CROUCH_HEIGHT 0.4f
#define STAND_HEIGHT 1.0f
typedef struct {
Vector3 position;
Vector3 velocity;
Vector3 dir;
bool grounded;
} Body;
void UpdateFpsCamera(Camera *camera);
void UpdateBody(Body *body, float rot, char side, char forward, bool jump, bool crouch);
#endif
+1
View File
@@ -2,6 +2,7 @@
#define SCREEN_H #define SCREEN_H
#define GAME_FPS 60 #define GAME_FPS 60
#define MAX_COLUMNS 20
void DrawLevel00(); void DrawLevel00();