diff --git a/Camera.cs b/Camera.cs index d95383c..dccc0c6 100644 --- a/Camera.cs +++ b/Camera.cs @@ -9,9 +9,14 @@ namespace Voxel public static float Pitch = -22.5f; public static float Yaw = 0f; public static float FOV = 60f; + public static float TargetFOV = FOV; + public static float FOVLerpSpeed = 10f; public static float Speed = 5f; public static float ShiftSpeed = 20f; + private static int _width; + private static int _height; + public static Matrix4 view => Matrix4.LookAt(Position, Position + Front, Vector3.UnitY); @@ -39,14 +44,28 @@ namespace Voxel Pitch = MathHelper.Clamp(Pitch, -89f, 89f); } - public static void UpdateProjection(int width, int height) + public static void UpdateProjection() { float fov = MathHelper.DegreesToRadians(FOV); - float aspectRatio = width / (float)height; + float aspectRatio = _width / (float)_height; float near = 0.1f; float far = 1000f; projection = Matrix4.CreatePerspectiveFieldOfView(fov, aspectRatio, near, far); } + + public static void UpdateSize(int width, int height) + { + _width = width; + _height = height; + UpdateProjection(); + } + + public static void UpdateFOV(float deltaTime, float alpha) + { + float currentFOV = MathHelper.Lerp(FOV, TargetFOV, FOVLerpSpeed * deltaTime); + Camera.FOV = currentFOV; + Camera.UpdateProjection(); + } } } diff --git a/Entity.cs b/Entity.cs index c7e1c3c..3f445b4 100644 --- a/Entity.cs +++ b/Entity.cs @@ -19,8 +19,8 @@ namespace Voxel private float _gravity = 0.08f; private float _terminalVelocity = -3.92f; - private float _airMultiplier = 0.98f; - private float _groundMultiplier = 0.91f; + private float _airMultiplier = 0.91f; + private float _groundMultiplier = 0.6f; private const float COLLISION_EPSILON = 0.01f; @@ -46,7 +46,9 @@ namespace Voxel if (!OnGround) { Vector3 acceleration = new Vector3(0, -_gravity, 0); - Velocity = (Velocity + acceleration) * _airMultiplier; + Velocity += acceleration; + Velocity *= _airMultiplier; + if (Velocity.Y < _terminalVelocity) { @@ -55,11 +57,7 @@ namespace Voxel } else { - Velocity = new Vector3( - Velocity.X * _groundMultiplier, - 0f, - Velocity.Z * _groundMultiplier - ); + Velocity = new Vector3(Velocity.X * _groundMultiplier, 0f, Velocity.Z * _groundMultiplier); } UpdateOnGround(); diff --git a/Input.cs b/Input.cs index cd1c85b..6054e56 100644 --- a/Input.cs +++ b/Input.cs @@ -1,4 +1,5 @@ -using OpenTK.Windowing.GraphicsLibraryFramework; +using OpenTK.Windowing.Common; +using OpenTK.Windowing.GraphicsLibraryFramework; namespace Voxel { @@ -7,6 +8,8 @@ namespace Voxel private static Dictionary _keystates = new Dictionary(); private static Dictionary _mouseButtonStates = new Dictionary(); + public static Action OnMouseWheel; + public static bool GetMouseButton(MouseButton button) { return _mouseButtonStates.TryGetValue(button, out bool pressed) && pressed; @@ -26,5 +29,10 @@ namespace Voxel { _keystates[key] = pressed; } + + public static void MouseWheel(MouseWheelEventArgs e) + { + OnMouseWheel.Invoke(e); + } } } diff --git a/Player.cs b/Player.cs index 8c1a192..ae46cb1 100644 --- a/Player.cs +++ b/Player.cs @@ -1,4 +1,5 @@ using OpenTK.Mathematics; +using OpenTK.Windowing.Common; using OpenTK.Windowing.GraphicsLibraryFramework; using System; using System.Collections.Generic; @@ -16,14 +17,14 @@ namespace Voxel private int _blockIndex = 0; private double _tickTime = 0; - private bool _isJumping = false; + private bool _isSprinting = false; private Blocks _selectedBlock = Blocks.OakPlanks; private Vector3 previousPosition; public Player(Vector3 startPos, World world) : base(startPos, 0.5f, 1.8f, world) { - + Input.OnMouseWheel += SwitchBlock; } public void PlaceBlock() @@ -46,26 +47,36 @@ namespace Voxel _world.SetBlock(x, y, z, Blocks.Air); } - public void Tick() + public new void Tick() { previousPosition = Position; - bool sprinting = Input.GetKey(Keys.LeftControl); + float forwards = 0; + float sidewards = 0; if (Input.GetKey(Keys.W)) - ApplyWalkSpeed(0, -1, sprinting); + forwards = -1; if (Input.GetKey(Keys.S)) - ApplyWalkSpeed(0, 1, sprinting); + forwards = 1; if (Input.GetKey(Keys.A)) - ApplyWalkSpeed(-1, 0, false); + sidewards = -1; if (Input.GetKey(Keys.D)) - ApplyWalkSpeed(1, 0, false); + sidewards = 1; + + _isSprinting = (Input.GetKey(Keys.LeftControl) && forwards != 0); if (Input.GetKey(Keys.Space) && OnGround) { Console.WriteLine("Jump"); Velocity = new Vector3(Velocity.X, 0.42f, Velocity.Z); OnGround = false; + + if (_isSprinting) + { + float yawRad = MathHelper.DegreesToRadians(Rotation); + Velocity.X += 0.2f * MathF.Sin(yawRad); + Velocity.Z += 0.2f * -MathF.Cos(yawRad); + } } if (Input.GetMouseButton(MouseButton.Right) && lastClick == 0) @@ -82,6 +93,7 @@ namespace Voxel BreakBlock(); } + ApplyWalkSpeed(sidewards, forwards); base.Tick(); Console.WriteLine(Velocity.X.ToString() + ", " + Velocity.Y.ToString() + ", " + Velocity.Z.ToString()); @@ -92,6 +104,16 @@ namespace Voxel Camera.Position = Vector3.Lerp(previousPosition, Position, alpha) + Vector3.UnitY * 0.62f; Rotation = Camera.Yaw; + if (_isSprinting) + { + Camera.TargetFOV = 70; + Camera.UpdateProjection(); + } + else + { + Camera.TargetFOV = 60; + } + if (lastClick > 0) { lastClick -= deltaTime; @@ -104,7 +126,7 @@ namespace Voxel } } - public void ApplyWalkSpeed(float x, float z, bool sprinting) + public void ApplyWalkSpeed(float x, float z) { Vector3 inputDir = new Vector3(x, 0, z); if (inputDir.LengthSquared > 0) @@ -120,15 +142,32 @@ namespace Voxel inputDir.X * sin + inputDir.Z * cos ); - float speed = sprinting ? 0.13f : 0.10f; + float M_t = _isSprinting ? 1.3f : 1f; + float groundMultiplier = 0.6f; - Velocity += worldDir * speed; + if (!OnGround) + { + Vector3 airAccel = worldDir * 0.02f * M_t; + Velocity = new Vector3(Velocity.X + airAccel.X, Velocity.Y, Velocity.Z + airAccel.Z); + } + else + { + Vector3 groundAccel = worldDir * 0.1f * M_t; + Velocity = new Vector3(Velocity.X * groundMultiplier + groundAccel.X, + Velocity.Y, + Velocity.Z * groundMultiplier + groundAccel.Z); + } } - public void SwitchBlock(bool inverted) + public void SwitchBlock(MouseWheelEventArgs e) { var keys = BlockDefinitions.Blocks.Keys.ToList(); + bool inverted = false; + + if (e.OffsetY < 0) + inverted = true; + if (inverted) if (_blockIndex == 0) _blockIndex = keys.Count -1; diff --git a/Program.cs b/Program.cs index 7ffa0a7..31ea42d 100644 --- a/Program.cs +++ b/Program.cs @@ -47,6 +47,7 @@ internal class Program window.Tick += player.Tick; window.Update += player.Update; + window.Update += Camera.UpdateFOV; window.Run(); } diff --git a/Window.cs b/Window.cs index fc99a8c..d6440fe 100644 --- a/Window.cs +++ b/Window.cs @@ -73,7 +73,7 @@ namespace Voxel { base.OnFramebufferResize(e); - Camera.UpdateProjection(e.Width, e.Height); + Camera.UpdateSize(e.Width, e.Height); GL.Viewport(0, 0, e.Width, e.Height); } @@ -92,7 +92,7 @@ namespace Voxel CursorState = CursorState.Grabbed; VSync = VSyncMode.On; - Camera.UpdateProjection(Width, Height); + Camera.UpdateSize(Width, Height); } protected override void OnMouseMove(MouseMoveEventArgs e) @@ -129,11 +129,7 @@ namespace Voxel protected override void OnMouseWheel(MouseWheelEventArgs e) { base.OnMouseWheel(e); - - bool inverted = false; - - if (e.OffsetY < 0) - inverted = true; + Input.MouseWheel(e); } } }