using OpenTK.Mathematics; using OpenTK.Windowing.Common; using OpenTK.Windowing.GraphicsLibraryFramework; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace Voxel { public class Player : Entity { public double lastClick = 0; public readonly float mouseCooldown = 0.2f; private int _blockIndex = 0; private double _tickTime = 0; 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() { var (success, hit, x, y, z, normal) = _world.Raycast(Camera.Position, Camera.Front.Normalized(), 8); if (!success) return; x += normal.X; y += normal.Y; z += normal.Z; _world.SetBlock(x, y, z, _selectedBlock); } public void BreakBlock() { var (success, hit, x, y, z, normal) = _world.Raycast(Camera.Position, Camera.Front.Normalized(), 8); if (!success) return; _world.SetBlock(x, y, z, Blocks.Air); } public new void Tick() { previousPosition = Position; float forwards = 0; float sidewards = 0; if (Input.GetKey(Keys.W)) forwards = -1; if (Input.GetKey(Keys.S)) forwards = 1; if (Input.GetKey(Keys.A)) sidewards = -1; if (Input.GetKey(Keys.D)) 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) { lastClick = mouseCooldown; PlaceBlock(); } if (Input.GetMouseButton(MouseButton.Left) && lastClick == 0) { lastClick = mouseCooldown; BreakBlock(); } ApplyWalkSpeed(sidewards, forwards); base.Tick(); Console.WriteLine(Velocity.X.ToString() + ", " + Velocity.Y.ToString() + ", " + Velocity.Z.ToString()); } public void Update(float deltaTime, float alpha) { 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; if (lastClick < 0) lastClick = 0; } if (!Input.GetMouseButton(MouseButton.Right) && !Input.GetMouseButton(MouseButton.Left)) { lastClick = 0; } } public void ApplyWalkSpeed(float x, float z) { Vector3 inputDir = new Vector3(x, 0, z); if (inputDir.LengthSquared > 0) inputDir = Vector3.Normalize(inputDir); float yawRad = MathHelper.DegreesToRadians(Rotation); float cos = MathF.Cos(yawRad); float sin = MathF.Sin(yawRad); Vector3 worldDir = new Vector3( inputDir.X * cos - inputDir.Z * sin, 0, inputDir.X * sin + inputDir.Z * cos ); float M_t = _isSprinting ? 1.3f : 1f; float groundMultiplier = 0.6f; 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(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; else _blockIndex -= 1; else _blockIndex += 1; _blockIndex = _blockIndex % keys.Count; _selectedBlock = keys[_blockIndex]; Console.WriteLine(_selectedBlock); } } }