130 lines
3.5 KiB
C#
130 lines
3.5 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|