player added
This commit is contained in:
41
AABB.cs
Normal file
41
AABB.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using OpenTK.Mathematics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Voxel
|
||||
{
|
||||
public struct AABB
|
||||
{
|
||||
public Vector3 Min;
|
||||
public Vector3 Max;
|
||||
|
||||
public AABB(Vector3 min, Vector3 max)
|
||||
{
|
||||
Min = min;
|
||||
Max = max;
|
||||
}
|
||||
|
||||
public static AABB FromCenter(Vector3 center, float width, float height, float depth)
|
||||
{
|
||||
Vector3 half = new Vector3(width / 2f, 0, depth / 2f);
|
||||
return new AABB(center - half, center + new Vector3(half.X, height, half.Z));
|
||||
}
|
||||
|
||||
public bool Intersects(AABB other)
|
||||
{
|
||||
return (Min.X <= other.Max.X && Max.X >= other.Min.X) &&
|
||||
(Min.Y <= other.Max.Y && Max.Y >= other.Min.Y) &&
|
||||
(Min.Z <= other.Max.Z && Max.Z >= other.Min.Z);
|
||||
}
|
||||
|
||||
public bool Contains(Vector3 point)
|
||||
{
|
||||
return (point.X >= Min.X && point.X <= Max.X) &&
|
||||
(point.Y >= Min.Y && point.Y <= Max.Y) &&
|
||||
(point.Z >= Min.Z && point.Z <= Max.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Camera.cs
30
Camera.cs
@@ -21,39 +21,15 @@ namespace Voxel
|
||||
{
|
||||
get
|
||||
{
|
||||
float yawOffset = Yaw - 90f;
|
||||
Vector3 front;
|
||||
front.X = MathF.Cos(MathHelper.DegreesToRadians(Yaw)) * MathF.Cos(MathHelper.DegreesToRadians(Pitch));
|
||||
front.X = MathF.Cos(MathHelper.DegreesToRadians(yawOffset)) * MathF.Cos(MathHelper.DegreesToRadians(Pitch));
|
||||
front.Y = MathF.Sin(MathHelper.DegreesToRadians(Pitch));
|
||||
front.Z = MathF.Sin(MathHelper.DegreesToRadians(Yaw)) * MathF.Cos(MathHelper.DegreesToRadians(Pitch));
|
||||
front.Z = MathF.Sin(MathHelper.DegreesToRadians(yawOffset)) * MathF.Cos(MathHelper.DegreesToRadians(Pitch));
|
||||
return front.Normalized();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Update(float time)
|
||||
{
|
||||
float moveSpeed = Speed * time;
|
||||
if (Input.GetKey(OpenTK.Windowing.GraphicsLibraryFramework.Keys.LeftShift))
|
||||
{
|
||||
moveSpeed = ShiftSpeed * time;
|
||||
}
|
||||
if (Input.GetKey(OpenTK.Windowing.GraphicsLibraryFramework.Keys.W))
|
||||
{
|
||||
Position += Front * moveSpeed;
|
||||
}
|
||||
if (Input.GetKey(OpenTK.Windowing.GraphicsLibraryFramework.Keys.S))
|
||||
{
|
||||
Position += Front * -moveSpeed;
|
||||
}
|
||||
if (Input.GetKey(OpenTK.Windowing.GraphicsLibraryFramework.Keys.A))
|
||||
{
|
||||
Position += Vector3.Cross(Front, Vector3.UnitY).Normalized() * -moveSpeed;
|
||||
}
|
||||
if (Input.GetKey(OpenTK.Windowing.GraphicsLibraryFramework.Keys.D))
|
||||
{
|
||||
Position += Vector3.Cross(Front, Vector3.UnitY).Normalized() * moveSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateMouse(Vector2 delta)
|
||||
{
|
||||
float sensitivity = 0.1f;
|
||||
|
||||
129
Entity.cs
Normal file
129
Entity.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
13
Game.cs
Normal file
13
Game.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Voxel
|
||||
{
|
||||
public static class Game
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
39
Player.cs
39
Player.cs
@@ -3,24 +3,23 @@ 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
|
||||
public class Player : Entity
|
||||
{
|
||||
public Vector3 Position;
|
||||
|
||||
private World _world;
|
||||
public double lastClick = 0;
|
||||
public readonly float mouseCooldown = 0.2f;
|
||||
private int _blockIndex = 0;
|
||||
private Blocks _selectedBlock = Blocks.Dirt;
|
||||
|
||||
public Player(World world, Vector3 startPos)
|
||||
public Player(Vector3 startPos, World world) : base(startPos, 0.5f, 1.8f, world)
|
||||
{
|
||||
_world = world;
|
||||
|
||||
}
|
||||
|
||||
public void PlaceBlock()
|
||||
@@ -45,7 +44,8 @@ namespace Voxel
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
Camera.Update(deltaTime);
|
||||
Camera.Position = Position + Vector3.UnitY * 0.5f;
|
||||
Rotation = Camera.Yaw;
|
||||
|
||||
if (lastClick > 0)
|
||||
{
|
||||
@@ -71,6 +71,33 @@ namespace Voxel
|
||||
|
||||
BreakBlock();
|
||||
}
|
||||
|
||||
if (Input.GetKey(Keys.W))
|
||||
ApplyLocalVelocity(0, -5 * deltaTime);
|
||||
|
||||
if (Input.GetKey(Keys.Space) && OnGround)
|
||||
{
|
||||
Velocity = new Vector3(Velocity.X, 0.5f, Velocity.Z);
|
||||
OnGround = false;
|
||||
Console.WriteLine("Jump");
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyLocalVelocity(float x, float z)
|
||||
{
|
||||
Vector3 localVelocity = new Vector3(x, 0, z);
|
||||
|
||||
float yaw = MathHelper.DegreesToRadians(Rotation);
|
||||
float cos = MathF.Cos(yaw); // yaw in radians
|
||||
float sin = MathF.Sin(yaw);
|
||||
|
||||
Vector3 worldVelocity = new Vector3(
|
||||
localVelocity.X * cos - localVelocity.Z * sin,
|
||||
Velocity.Y,
|
||||
localVelocity.X * sin + localVelocity.Z * cos
|
||||
);
|
||||
|
||||
Velocity = worldVelocity;
|
||||
}
|
||||
|
||||
public void SwitchBlock(bool inverted)
|
||||
|
||||
13
Program.cs
13
Program.cs
@@ -11,14 +11,11 @@ internal class Program
|
||||
|
||||
World world = new World();
|
||||
Window window = new Window(sizeX, sizeY, title);
|
||||
Player player = new Player(world, Vector3.Zero);
|
||||
|
||||
window.Player = player;
|
||||
|
||||
Console.WriteLine("Generating map...");
|
||||
|
||||
int worldSizeX = 32;
|
||||
int worldSizeY = 32;
|
||||
int worldSizeX = 8;
|
||||
int worldSizeY = 8;
|
||||
|
||||
float maxI = worldSizeX * worldSizeY;
|
||||
int i = 0;
|
||||
@@ -45,6 +42,12 @@ internal class Program
|
||||
|
||||
Renderer.SetWorld(world);
|
||||
|
||||
Vector3 startPos = new Vector3(15, 64, 15);
|
||||
Player player = new Player(startPos, world);
|
||||
|
||||
window.Update += player.Tick;
|
||||
window.Update += player.Update;
|
||||
|
||||
window.Run();
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ namespace Voxel
|
||||
|
||||
_shader.Use();
|
||||
_shader.SetMatrix4("view", Camera.view);
|
||||
_shader.SetVector3("cameraPosition", Camera.Position);
|
||||
_shader.SetMatrix4("projection", Camera.projection);
|
||||
|
||||
if (_buffersDirty)
|
||||
|
||||
11
Shader.cs
11
Shader.cs
@@ -67,6 +67,17 @@ namespace Voxel
|
||||
GL.UniformMatrix4(location, false, ref matrix);
|
||||
}
|
||||
|
||||
public void SetVector3(string name, Vector3 vector3)
|
||||
{
|
||||
int location = GL.GetUniformLocation(_handle, name);
|
||||
if (location == -1)
|
||||
{
|
||||
Console.WriteLine($"Uniform '{name}' not found in shader.");
|
||||
return;
|
||||
}
|
||||
GL.Uniform3(location, ref vector3);
|
||||
}
|
||||
|
||||
public void SetInt(string name, int value)
|
||||
{
|
||||
int location = GL.GetUniformLocation(_handle, name);
|
||||
|
||||
@@ -2,12 +2,24 @@
|
||||
|
||||
out vec4 FragColor;
|
||||
in vec2 fragUV;
|
||||
in vec3 fragPos;
|
||||
in float lighting;
|
||||
|
||||
uniform sampler2D uTexture;
|
||||
uniform vec3 cameraPosition;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texColor = texture(uTexture, fragUV);
|
||||
FragColor = vec4(texColor.rgb * lighting, texColor.a);
|
||||
float fogEnd = 512;
|
||||
float fogStart = 32;
|
||||
|
||||
float dist = length(cameraPosition - fragPos);
|
||||
float fogFactor = (fogEnd - dist) / (fogEnd - fogStart);
|
||||
fogFactor = clamp(fogFactor, 0, 1);
|
||||
|
||||
vec4 fogColor = vec4(0.8,0.8,0.8,1);
|
||||
vec4 texColor = texture(uTexture, fragUV) * lighting;
|
||||
vec4 color = mix(fogColor, texColor, fogFactor);
|
||||
|
||||
FragColor = vec4(color.rgb, texColor.a);
|
||||
}
|
||||
@@ -20,6 +20,7 @@ uniform int chunkY;
|
||||
|
||||
out vec2 fragUV;
|
||||
out float lighting;
|
||||
out vec3 fragPos;
|
||||
|
||||
const float lightMult[6] = float[6](0.6, 0.6, 1.0, 0.5, 0.8, 0.8);
|
||||
|
||||
@@ -111,5 +112,6 @@ void main()
|
||||
fragUV = uv;
|
||||
lighting = lightMult[facing];
|
||||
|
||||
fragPos = vec3(worldPos.x, worldPos.y, worldPos.z);
|
||||
gl_Position = projection * view * worldPos;
|
||||
}
|
||||
12
Window.cs
12
Window.cs
@@ -10,14 +10,16 @@ namespace Voxel
|
||||
{
|
||||
public readonly int Width = width;
|
||||
public readonly int Height = height;
|
||||
public Player Player;
|
||||
public uint frames = 0;
|
||||
public double timeElapsed = 0;
|
||||
public event Action<float> Update;
|
||||
|
||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnUpdateFrame(e);
|
||||
|
||||
float deltaTime = (float)e.Time;
|
||||
|
||||
if (Input.GetKey(Keys.Escape))
|
||||
{
|
||||
Close();
|
||||
@@ -31,10 +33,7 @@ namespace Voxel
|
||||
WindowState = WindowState.Normal;
|
||||
}
|
||||
|
||||
if (Player != null)
|
||||
{
|
||||
Player.Update((float)e.Time);
|
||||
}
|
||||
Update.Invoke(deltaTime);
|
||||
}
|
||||
|
||||
protected override void OnRenderFrame(FrameEventArgs e)
|
||||
@@ -52,7 +51,6 @@ namespace Voxel
|
||||
frames = 0;
|
||||
}
|
||||
|
||||
Camera.Update((float)e.Time);
|
||||
Renderer.Render();
|
||||
|
||||
SwapBuffers();
|
||||
@@ -123,8 +121,6 @@ namespace Voxel
|
||||
|
||||
if (e.OffsetY < 0)
|
||||
inverted = true;
|
||||
|
||||
Player.SwitchBlock(inverted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user