using OpenTK.Mathematics; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Voxel { public class Entity { public Vector3 Position; public Vector3 Velocity; public bool OnGround; public float Rotation; public float Width; public float Height; private float _airDrag = 2f; private float _groundDrag = 8f; private World _world; public Entity(Vector3 position, float width, float height, World world) { Position = position; Width = width; Height = height; _world = world; } public void Tick(float deltaTime) { Console.WriteLine(OnGround); if (!OnGround) { Console.WriteLine("Velocity: " + Velocity.Y.ToString()); Velocity -= new Vector3( Velocity.X * _airDrag * deltaTime, 1.6f * deltaTime, Velocity.Z * _airDrag * deltaTime); } else { Velocity = new Vector3(Velocity.X, 0, Velocity.Z); Velocity -= new Vector3( Velocity.X * _groundDrag * deltaTime, 0, Velocity.Z * _groundDrag * deltaTime); } UpdateOnGround(); Position += Velocity; Console.WriteLine("Position: " + Position.Y.ToString()); } public AABB GetBoundingBox() { float halfWidth = Width / 2; Vector3 min = new Vector3( Position.X - halfWidth, Position.Y - Height, Position.Z - halfWidth ); Vector3 max = new Vector3( Position.X + halfWidth, Position.Y + Height, Position.Z + halfWidth ); return new AABB(min, max); } private bool IsCollidingSide(Vector3 direction) { AABB box = GetBoundingBox(); // Determine which axis we’re checking int checkX = direction.X > 0 ? (int)MathF.Floor(box.Max.X) : (int)MathF.Floor(box.Min.X); int checkZ = direction.Z > 0 ? (int)MathF.Floor(box.Max.Z) : (int)MathF.Floor(box.Min.Z); int minY = (int)MathF.Floor(box.Min.Y); int maxY = (int)MathF.Floor(box.Max.Y); // Sweep along vertical range for (int y = minY; y <= maxY; y++) { if (_world.GetBlock(checkX, y, checkZ) != Blocks.Air) return true; } return false; } public void UpdateOnGround() { AABB box = GetBoundingBox(); float yCheck = box.Min.Y - 0.05f; int minX = (int)MathF.Floor(box.Min.X); int maxX = (int)MathF.Floor(box.Max.X); int minZ = (int)MathF.Floor(box.Min.Z); int maxZ = (int)MathF.Floor(box.Max.Z); OnGround = false; for (int x = minX; x <= maxX; x++) { for (int z = minZ; z <= maxZ; z++) { Blocks block = _world.GetBlock(x, (int)MathF.Floor(yCheck), z); if (block != Blocks.Air) { OnGround = true; return; } } } } } }