added block breaking
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
Stone,
|
||||
Dirt,
|
||||
OakPlanks,
|
||||
Grass
|
||||
Grass,
|
||||
Bedrock
|
||||
}
|
||||
|
||||
public enum Orientation : uint
|
||||
@@ -60,6 +61,7 @@
|
||||
{ Voxel.Blocks.Stone, new BlockDefinition(Voxel.Blocks.Stone, Voxel.Textures.Stone) },
|
||||
{ Voxel.Blocks.Dirt, new BlockDefinition(Voxel.Blocks.Dirt, Voxel.Textures.Dirt) },
|
||||
{ Voxel.Blocks.OakPlanks, new BlockDefinition(Voxel.Blocks.OakPlanks, Voxel.Textures.OakPlanks) },
|
||||
{ Voxel.Blocks.Bedrock, new BlockDefinition(Voxel.Blocks.Bedrock, Voxel.Textures.Bedrock) },
|
||||
|
||||
{ Voxel.Blocks.Grass, new BlockDefinition(
|
||||
Voxel.Blocks.Grass,
|
||||
|
||||
16
Chunk.cs
16
Chunk.cs
@@ -2,8 +2,8 @@
|
||||
{
|
||||
public class Chunk
|
||||
{
|
||||
public readonly int Size = 16;
|
||||
public readonly int Height = 256;
|
||||
public static int Size = 16;
|
||||
public static int Height = 256;
|
||||
public readonly int PositionX;
|
||||
public readonly int PositionY;
|
||||
|
||||
@@ -45,9 +45,12 @@
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
Random rng = new Random();
|
||||
for (int i = 0; i < Size * Size * 16; i++)
|
||||
_blocks[i] = (Blocks)rng.Next(5);
|
||||
for (int i = 0; i < Size * Size; i++)
|
||||
_blocks[i] = Blocks.Bedrock;
|
||||
for (int i = Size * Size * 1; i < Size * Size * 15; i++)
|
||||
_blocks[i] = Blocks.Stone;
|
||||
for (int i = Size * Size * 15; i < Size * Size * 16; i++)
|
||||
_blocks[i] = Blocks.Grass;
|
||||
}
|
||||
|
||||
// todo
|
||||
@@ -62,6 +65,9 @@
|
||||
|
||||
private int GetBlockIndex(int x, int y, int z)
|
||||
{
|
||||
if (x < 0 || x > 15 || y < 0 || y > 255 || z < 0 || z > 15)
|
||||
return 0;
|
||||
|
||||
return x + z * Size + y * Size * Size;
|
||||
}
|
||||
|
||||
|
||||
40
Player.cs
Normal file
40
Player.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using OpenTK.Mathematics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Voxel
|
||||
{
|
||||
public class Player
|
||||
{
|
||||
public Vector3 Position;
|
||||
|
||||
private World _world;
|
||||
|
||||
public Player(World world, Vector3 startPos)
|
||||
{
|
||||
_world = world;
|
||||
}
|
||||
|
||||
public void BreakBlock()
|
||||
{
|
||||
var (hit, x, y, z) = _world.Raycast(5f); // max 5 blocks
|
||||
if (hit != Blocks.Air)
|
||||
{
|
||||
_world.SetBlock(x, y, z, Blocks.Air);
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
Camera.Update(deltaTime);
|
||||
|
||||
if (Input.GetKey(OpenTK.Windowing.GraphicsLibraryFramework.Keys.Space))
|
||||
{
|
||||
BreakBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Program.cs
11
Program.cs
@@ -1,4 +1,5 @@
|
||||
using Voxel;
|
||||
using OpenTK.Mathematics;
|
||||
using Voxel;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
@@ -8,15 +9,19 @@ internal class Program
|
||||
int sizeY = 600;
|
||||
string title = "Game";
|
||||
|
||||
World world = new World();
|
||||
Window window = new Window(sizeX, sizeY, title);
|
||||
Player player = new Player(world, Vector3.Zero);
|
||||
|
||||
window.Player = player;
|
||||
|
||||
Chunk chunk = new Chunk(0, 0);
|
||||
|
||||
world.AddChunk(chunk);
|
||||
|
||||
ChunkMesh chunkMesh = chunk.GetChunkMesh();
|
||||
Renderer.AddFaces(chunkMesh.Faces);
|
||||
|
||||
window.Chunk = chunk;
|
||||
|
||||
window.Run();
|
||||
}
|
||||
}
|
||||
32
Window.cs
32
Window.cs
@@ -1,5 +1,6 @@
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
using OpenTK.Windowing.Common;
|
||||
using OpenTK.Windowing.Common.Input;
|
||||
using OpenTK.Windowing.Desktop;
|
||||
|
||||
namespace Voxel
|
||||
@@ -8,14 +9,10 @@ namespace Voxel
|
||||
{
|
||||
public readonly int Width = width;
|
||||
public readonly int Height = height;
|
||||
public Player Player;
|
||||
public uint frames = 0;
|
||||
public double timeElapsed = 0;
|
||||
|
||||
// testing
|
||||
public Chunk Chunk;
|
||||
private Dictionary<int, bool> _cache = new Dictionary<int, bool>();
|
||||
private bool chunkEmpty = false;
|
||||
|
||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnUpdateFrame(e);
|
||||
@@ -25,30 +22,10 @@ namespace Voxel
|
||||
Close();
|
||||
}
|
||||
|
||||
RemoveRandomBlocks();
|
||||
}
|
||||
|
||||
private void RemoveRandomBlocks()
|
||||
{
|
||||
if (Chunk != null && !chunkEmpty)
|
||||
if (Player != null)
|
||||
{
|
||||
Random rng = new Random();
|
||||
|
||||
int GetNum()
|
||||
{
|
||||
int max = 4096;
|
||||
int num = rng.Next(max);
|
||||
if (_cache.ContainsKey(num)) return GetNum();
|
||||
_cache[num] = true;
|
||||
if (_cache.Count == max) chunkEmpty = true;
|
||||
return num;
|
||||
}
|
||||
|
||||
Chunk.SetBlockIndex(GetNum(), Blocks.Air);
|
||||
Player.Update((float)e.Time);
|
||||
}
|
||||
|
||||
Renderer.ClearFaces();
|
||||
Renderer.AddFaces(Chunk.GetChunkMesh().Faces);
|
||||
}
|
||||
|
||||
protected override void OnRenderFrame(FrameEventArgs e)
|
||||
@@ -93,6 +70,7 @@ namespace Voxel
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
|
||||
|
||||
CursorState = CursorState.Grabbed;
|
||||
Cursor = MouseCursor.Default;
|
||||
VSync = VSyncMode.On;
|
||||
|
||||
Camera.UpdateProjection(Width, Height);
|
||||
|
||||
104
World.cs
Normal file
104
World.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using OpenTK.Mathematics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Voxel
|
||||
{
|
||||
public class World
|
||||
{
|
||||
private Dictionary<(int, int), Chunk> _chunks;
|
||||
|
||||
public World()
|
||||
{
|
||||
_chunks = new Dictionary<(int, int), Chunk>();
|
||||
}
|
||||
|
||||
// Get a chunk at world coordinates, returns null if not loaded
|
||||
public Chunk GetChunk(int chunkX, int chunkZ)
|
||||
{
|
||||
_chunks.TryGetValue((chunkX, chunkZ), out Chunk chunk);
|
||||
return chunk;
|
||||
}
|
||||
|
||||
// Add a chunk
|
||||
public void AddChunk(Chunk chunk)
|
||||
{
|
||||
_chunks[(chunk.PositionX, chunk.PositionY)] = chunk;
|
||||
}
|
||||
|
||||
// Remove a chunk
|
||||
public void RemoveChunk(int chunkX, int chunkZ)
|
||||
{
|
||||
_chunks.Remove((chunkX, chunkZ));
|
||||
}
|
||||
|
||||
// Iterate over all chunks
|
||||
public IEnumerable<Chunk> GetAllChunks()
|
||||
{
|
||||
return _chunks.Values;
|
||||
}
|
||||
|
||||
// Optional: get a block at world coordinates
|
||||
public Blocks GetBlock(int worldX, int worldY, int worldZ)
|
||||
{
|
||||
int chunkX = worldX / Chunk.Size;
|
||||
int chunkZ = worldZ / Chunk.Size;
|
||||
Chunk chunk = GetChunk(chunkX, chunkZ);
|
||||
if (chunk == null) return 0; // air if chunk not loaded
|
||||
|
||||
int localX = worldX % Chunk.Size;
|
||||
int localZ = worldZ % Chunk.Size;
|
||||
|
||||
return chunk.GetBlock(localX, worldY, localZ);
|
||||
}
|
||||
|
||||
// Optional: set a block at world coordinates
|
||||
public void SetBlock(int worldX, int worldY, int worldZ, Blocks block)
|
||||
{
|
||||
int chunkX = worldX / Chunk.Size;
|
||||
int chunkZ = worldZ / Chunk.Size;
|
||||
Chunk chunk = GetChunk(chunkX, chunkZ);
|
||||
if (chunk == null) return;
|
||||
|
||||
int localX = worldX % Chunk.Size;
|
||||
int localZ = worldZ % Chunk.Size;
|
||||
|
||||
chunk.SetBlock(localX, worldY, localZ, block);
|
||||
Renderer.ClearFaces();
|
||||
ChunkMesh chunkMesh = chunk.GetChunkMesh();
|
||||
Renderer.AddFaces(chunkMesh.Faces);
|
||||
}
|
||||
|
||||
public (Blocks block, int x, int y, int z) Raycast(float length)
|
||||
{
|
||||
Vector3 start = Camera.Position;
|
||||
Vector3 dir = Camera.Front.Normalized();
|
||||
|
||||
float stepSize = 0.01f;
|
||||
float distanceTraveled = 0f;
|
||||
|
||||
while (distanceTraveled < length)
|
||||
{
|
||||
Vector3 point = start + dir * distanceTraveled;
|
||||
|
||||
int bx = (int)MathF.Floor(point.X);
|
||||
int by = (int)MathF.Floor(point.Y);
|
||||
int bz = (int)MathF.Floor(point.Z);
|
||||
|
||||
Blocks block = GetBlock(bx, by, bz);
|
||||
if (block != Blocks.Air)
|
||||
{
|
||||
return (block, bx, by, bz);
|
||||
}
|
||||
|
||||
distanceTraveled += stepSize;
|
||||
}
|
||||
|
||||
return (Blocks.Air, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user