Major refactor and organization, optimizations to chunk, world and renderer
This commit is contained in:
118
Entities/Entity.cs
Normal file
118
Entities/Entity.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using OpenTK.Mathematics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Voxel.Core;
|
||||
using Voxel.Physics;
|
||||
|
||||
namespace Voxel.Entities
|
||||
{
|
||||
public class Entity
|
||||
{
|
||||
public Vector3 Position;
|
||||
public Vector3 Velocity;
|
||||
public bool OnGround;
|
||||
public float Rotation;
|
||||
|
||||
public float Width;
|
||||
public float Height;
|
||||
|
||||
private float _gravity = 0.08f;
|
||||
private float _terminalVelocity = -3.92f;
|
||||
private float _airMultiplier = 0.91f;
|
||||
private float _yMultiplier = 0.98f;
|
||||
private float _groundMultiplier = 0.6f;
|
||||
|
||||
protected World _world;
|
||||
|
||||
public Entity(Vector3 position, float width, float height, World world)
|
||||
{
|
||||
Position = position;
|
||||
Width = width;
|
||||
Height = height;
|
||||
_world = world;
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
Move();
|
||||
|
||||
if (!OnGround)
|
||||
{
|
||||
Vector3 acceleration = new Vector3(0, -_gravity, 0);
|
||||
Velocity += acceleration;
|
||||
Velocity.X *= _airMultiplier;
|
||||
Velocity.Z *= _airMultiplier;
|
||||
Velocity.Y *= _yMultiplier;
|
||||
|
||||
|
||||
if (Velocity.Y < _terminalVelocity)
|
||||
{
|
||||
Velocity.Y = _terminalVelocity;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Velocity = new Vector3(Velocity.X * _groundMultiplier, 0f, Velocity.Z * _groundMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
public void Move()
|
||||
{
|
||||
Vector3 moveVector = Velocity;
|
||||
Vector3 originalVector = moveVector;
|
||||
|
||||
AABB body = AABB.FromCenter(Position, Width, Height, Width);
|
||||
|
||||
List<AABB> collisionChecks = _world.GetColliders(body.Expand(Velocity.X, Velocity.Y, Velocity.Z).Grow(1,1,1));
|
||||
|
||||
foreach (AABB collider in collisionChecks)
|
||||
{
|
||||
moveVector.X = body.GetClipX(collider, moveVector.X);
|
||||
}
|
||||
|
||||
body.Move(moveVector.X, 0, 0);
|
||||
|
||||
foreach (AABB collider in collisionChecks)
|
||||
{
|
||||
moveVector.Y = body.GetClipY(collider, moveVector.Y);
|
||||
}
|
||||
|
||||
body.Move(0, moveVector.Y, 0);
|
||||
|
||||
foreach (AABB collider in collisionChecks)
|
||||
{
|
||||
moveVector.Z = body.GetClipZ(collider, moveVector.Z);
|
||||
}
|
||||
|
||||
body.Move(0, 0, moveVector.Z);
|
||||
|
||||
if (moveVector.X != originalVector.X)
|
||||
{
|
||||
Velocity.X = 0;
|
||||
}
|
||||
|
||||
if (moveVector.Y != originalVector.Y)
|
||||
{
|
||||
Velocity.Y = 0;
|
||||
}
|
||||
|
||||
if (moveVector.Z != originalVector.Z)
|
||||
{
|
||||
Velocity.Z = 0;
|
||||
}
|
||||
|
||||
OnGround = moveVector.Y != originalVector.Y && originalVector.Y < 0;
|
||||
|
||||
Position = body.GetCenter();
|
||||
}
|
||||
|
||||
public void ApplyImpulse(Vector3 force)
|
||||
{
|
||||
Velocity += force;
|
||||
}
|
||||
}
|
||||
}
|
||||
166
Entities/Player.cs
Normal file
166
Entities/Player.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
using OpenTK.Mathematics;
|
||||
using OpenTK.Windowing.Common;
|
||||
using OpenTK.Windowing.GraphicsLibraryFramework;
|
||||
using Voxel.Core;
|
||||
using Voxel.Graphics;
|
||||
|
||||
namespace Voxel.Entities
|
||||
{
|
||||
public class Player : Entity
|
||||
{
|
||||
public double lastClick = 0;
|
||||
public readonly float mouseCooldown = 0.2f;
|
||||
|
||||
private int _blockIndex = 0;
|
||||
private int _jumpTicks = 0;
|
||||
|
||||
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 void Tick()
|
||||
{
|
||||
if (_jumpTicks > 0) _jumpTicks--;
|
||||
|
||||
_world.UpdateChunkLoading(Position);
|
||||
|
||||
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;
|
||||
|
||||
if (Input.GetMouseButton(MouseButton.Right) && lastClick == 0)
|
||||
{
|
||||
lastClick = mouseCooldown;
|
||||
|
||||
PlaceBlock();
|
||||
}
|
||||
|
||||
if (Input.GetMouseButton(MouseButton.Left) && lastClick == 0)
|
||||
{
|
||||
lastClick = mouseCooldown;
|
||||
|
||||
BreakBlock();
|
||||
}
|
||||
|
||||
if (Position.Y < -8)
|
||||
{
|
||||
Position.Y = 64;
|
||||
Velocity.Y = 0;
|
||||
}
|
||||
|
||||
ApplyWalkSpeed(sidewards, forwards);
|
||||
base.Tick();
|
||||
|
||||
if (Input.GetKey(Keys.Space))
|
||||
{
|
||||
if (OnGround && _jumpTicks == 0)
|
||||
{
|
||||
Jump();
|
||||
_jumpTicks = 10;
|
||||
}
|
||||
}
|
||||
else _jumpTicks = 0;
|
||||
}
|
||||
|
||||
public void Jump()
|
||||
{
|
||||
Velocity = new Vector3(Velocity.X, 0.42f, Velocity.Z);
|
||||
OnGround = false;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime, float alpha)
|
||||
{
|
||||
Camera.Position = Vector3.Lerp(previousPosition, Position, alpha) + Vector3.UnitY * 1.62f;
|
||||
Rotation = Camera.Yaw;
|
||||
|
||||
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 = 1.4f;
|
||||
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.13f * M_t;
|
||||
Velocity = new Vector3(Velocity.X * groundMultiplier + groundAccel.X,
|
||||
Velocity.Y,
|
||||
Velocity.Z * groundMultiplier + groundAccel.Z);
|
||||
}
|
||||
}
|
||||
|
||||
public void SwitchBlock(MouseWheelEventArgs e)
|
||||
{
|
||||
int count = BlockDefinitions.CreativeInventory.Length;
|
||||
int direction = e.OffsetY < 0 ? -1 : 1;
|
||||
|
||||
_blockIndex = (_blockIndex + direction + count) % count;
|
||||
_selectedBlock = BlockDefinitions.CreativeInventory[_blockIndex];
|
||||
|
||||
Console.WriteLine(_selectedBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user