Add camera movement

master
John Montagu, the 4th Earl of Sandvich 2026-02-22 22:44:16 -08:00
parent b78362bc9a
commit c8574ac85e
Signed by: sandvich
GPG Key ID: 9A39BE37E602B22D
2 changed files with 58 additions and 6 deletions

View File

@ -34,10 +34,12 @@ run the executable with the following command:
# Instructions on how to use the program
Use W and S to accelerate the penguin forward and backward. Use A and D to
change heading direction. The penguin will only accelerate in the direction
facing and will retain its velocity even when not accelerating or changing
direction.
Hold W and S to accelerate the penguin forward and backward. Use A and D to
change heading direction. This allows you to steer the penguin around the
environment.
Use the arrow keys to change the camera's rotation (pitch and yaw) with respect
to the penguin, allowing you to look around while the penguin moves.
# Readme Question
@ -50,3 +52,7 @@ otherwise the velocity would be in terms of units per frame rather than units
per second. By multiplying the velocity by `dt`, it converts the velocity to
units per second, allowing for consistent movement regardless of the frame
rate.
# Extra Credit
The camera moves with the penguin and can be rotated around the penguin using the arrow keys.

View File

@ -7,6 +7,7 @@
#include "raylib.h"
#include <raylib-cpp.hpp>
#include <cmath>
#include <algorithm>
#include <iostream>
#define SKYBOX_IMPLEMENTATION
@ -46,15 +47,30 @@ int main() {
raylib::Model penguin("models/penguin.glb");
// behind and above the penguin (in penguin-local space)
const float CAM_DIST = 512.0f;
const float CAM_HEIGHT = 256.0f;
const float CAM_ANGULAR_VELOCITY = 2.0f;
const float CAM_PITCH_MIN = -0.5f;
const float CAM_PITCH_MAX = 1.5f;
float camYaw = 3.14f; // offset by 90 deg so it faces in the proper direction
float camPitch = 0;
raylib::Camera3D camera(
{ 0, 120, 500 },
{ 0, 0, -1 },
{ 0, CAM_DIST * std::sin(camPitch), CAM_DIST * std::cos(camPitch) },
{ 0, 0, 0 },
{ 0, 1, 0 },
45.0f);
raylib::Model ground = raylib::Mesh::Plane(10000, 10000, 50, 50, 25);
raylib::Texture snowTexture("textures/snow.jpg");
ground.GetMaterials()[0].maps[MATERIAL_MAP_DIFFUSE].texture = snowTexture;
cs381::SkyBox skybox("textures/skybox.png");
// penguin physics
raylib::Vector3 position = { 0, 0, 0 };
raylib::Vector3 velocity = { 0, 0, 0 };
float heading = 0.0f;
@ -76,6 +92,7 @@ int main() {
position += velocity * dt * 0.5f;
// movement for penguin
if (IsKeyDown(KEY_W)) {
speed += ACCELERATION * dt;
}
@ -105,6 +122,35 @@ int main() {
// ds = 1/2 * (v0 + v1) * dt
position += velocity * dt * 0.5f;
// movement for camera
if (IsKeyDown(KEY_LEFT)) {
camYaw += CAM_ANGULAR_VELOCITY * dt;
}
if (IsKeyDown(KEY_RIGHT)) {
camYaw -= CAM_ANGULAR_VELOCITY * dt;
}
if (IsKeyDown(KEY_UP)) {
camPitch += CAM_ANGULAR_VELOCITY * dt;
}
if (IsKeyDown(KEY_DOWN)) {
camPitch -= CAM_ANGULAR_VELOCITY * dt;
}
// clamp the angle between
camPitch = std::clamp(camPitch, CAM_PITCH_MIN, CAM_PITCH_MAX);
// x = cos(pitch) * sin(yaw)
// y = sin(pitch)
// z = cos(pitch) * cos(yaw)
float yaw = camYaw + heading; // follow penguin
raylib::Vector3 camOffset = {
CAM_DIST * std::cos(camPitch) * std::sin(yaw),
CAM_DIST * std::sin(camPitch) + CAM_HEIGHT,
CAM_DIST * std::cos(camPitch) * std::cos(yaw)
};
camera.SetPosition(position + camOffset);
camera.SetTarget(position);
camera.BeginMode();
skybox.Draw();