diff --git a/as3/README.md b/as3/README.md index 54fc145..e47914f 100644 --- a/as3/README.md +++ b/as3/README.md @@ -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. diff --git a/as3/as3.cpp b/as3/as3.cpp index fa52395..c9171f4 100644 --- a/as3/as3.cpp +++ b/as3/as3.cpp @@ -7,6 +7,7 @@ #include "raylib.h" #include #include +#include #include #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();