added block breaking

This commit is contained in:
MasterGordon 2022-11-09 17:50:34 +01:00
parent 03610b157d
commit 2742e0100c
16 changed files with 176 additions and 40 deletions

BIN
assets/breaking.ase Normal file

Binary file not shown.

BIN
assets/breaking.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

View File

@ -0,0 +1,25 @@
[Interactor]
class Breaking
{
[Interaction(InteractorKind.Hybrid, "tick")]
public static void TickHybrid(TickPacket packet)
{
var ctx = Context.Get();
ctx.GameState.Players.ForEach(player =>
{
Math.Max(0, player.MiningCooldown -= 1);
if (player.Mining != null && player.MiningCooldown == 0)
{
var chunk = ctx.GameState.World.GetChunkAt(player.Mining);
// chunk.SetTileAt(player.Mining, tile with { Hits = tile.Hits + 1 });
// var tile = chunk.GetTileAt(amp);
// if (tile.Hits >= hardness)
// {
// chunk.SetTileAt(amp, STile.From(0));
// }
}
}
);
}
}

View File

@ -4,9 +4,8 @@ class Bootstrapper
{
var ctx = Context.Get();
ctx.GameState.World = new World();
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(0, 1, Tiles.stone));
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(-1, 1, Tiles.stone));
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(1, 1, Tiles.stone));
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(1, 0, Tiles.stone));
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(0, 1, STile.From(Tiles.stone)));
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(1, 1, STile.From(Tiles.stone)));
ctx.GameState.World.AddChunk(ChunkGenerator.CreateFilledChunk(1, 0, STile.From(Tiles.stone)));
}
}

View File

@ -9,7 +9,6 @@ class Camera
public void CenterOn(Vector2 target)
{
Console.WriteLine("Centering camera on " + target);
var ctx = Context.Get();
var scale = ctx.FrontendGameState.Settings.GameScale;
var windowWidth = ctx.FrontendGameState.WindowWidth;

View File

@ -53,17 +53,24 @@ class PlayerEntity
hasCollision =
world.HasChunkAt(pL) && world.GetChunkAt(pL).hasTileAt(pL)
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).hasTileAt(pR);
Console.WriteLine(World.ToChunkPos(p.Position));
if (world.HasChunkAt(p.Position))
{
var chunk = world.GetChunkAt(p.Position);
Console.WriteLine($"Chunk: {chunk.X}, {chunk.Y}");
}
if (hasCollision)
{
p.Movement = p.Movement with { Y = 0 };
p.Position += new Vector2(0, -0.1f);
}
} while (hasCollision);
do
{
var pL = p.Position + new Vector2(0, -32);
var pR = p.Position + new Vector2(16, -32);
hasCollision =
world.HasChunkAt(pL) && world.GetChunkAt(pL).hasTileAt(pL)
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).hasTileAt(pR);
if (hasCollision)
{
p.Movement = p.Movement with { Y = 0 };
p.Position += new Vector2(0, 0.1f);
}
} while (hasCollision);
}
}

View File

@ -1,6 +1,6 @@
class Chunk
{
public int[,] Tiles { get; set; } = new int[Constants.ChunkSize, Constants.ChunkSize];
public STile[,] Tiles { get; set; } = new STile[Constants.ChunkSize, Constants.ChunkSize];
public int X { get; set; }
public int Y { get; set; }
@ -10,12 +10,12 @@ class Chunk
this.Y = y;
}
public void SetTile(int x, int y, int tile)
public void SetTile(int x, int y, STile tile)
{
this.Tiles[x, y] = tile;
}
public int GetTile(int x, int y)
public STile GetTile(int x, int y)
{
return this.Tiles[x, y];
}
@ -33,21 +33,35 @@ class Chunk
return this.hasTile(tileX, tileY);
}
public int GetTileAt(Vector2 pos)
public STile GetTileAt(Vector2 pos)
{
return this.GetTileAt((int)pos.X, (int)pos.Y);
}
public int GetTileAt(int x, int y)
public STile GetTileAt(int x, int y)
{
var tileX = (int)Math.Floor(x / (float)Constants.TileSize);
var tileY = (int)Math.Floor(y / (float)Constants.TileSize);
var posInChunk = this.GetPositionInChunk(new Vector2(x, y));
var tileX = (int)Math.Floor(posInChunk.X / Constants.TileSize);
var tileY = (int)Math.Floor(posInChunk.Y / Constants.TileSize);
return this.GetTile(tileX, tileY);
}
public void SetTileAt(Vector2 pos, STile tile)
{
this.SetTileAt((int)pos.X, (int)pos.Y, tile);
}
public void SetTileAt(int x, int y, STile tile)
{
var posInChunk = this.GetPositionInChunk(new Vector2(x, y));
var tileX = (int)Math.Floor(posInChunk.X / Constants.TileSize);
var tileY = (int)Math.Floor(posInChunk.Y / Constants.TileSize);
this.SetTile(tileX, tileY, tile);
}
public bool hasTile(int x, int y)
{
return x >= 0 && x < this.Tiles.Length && y >= 0 && y < this.Tiles.Length;
return x >= 0 && x < this.Tiles.Length && y >= 0 && y < this.Tiles.Length && this.Tiles[x, y].Id != 0;
}
public bool hasTile(Vector2 pos)

18
src/core/data/STile.cs Normal file
View File

@ -0,0 +1,18 @@
struct STile
{
public int Id { get; set; }
public int Hits { get; set; }
public static STile From(int id)
{
return new STile()
{
Id = id
};
}
public static STile From(Tiles id)
{
return From((int)id);
}
}

View File

@ -63,11 +63,16 @@ class World
return new Vector2((float)chunkX, (float)chunkY);
}
public int GetTileAt(int x, int y)
public STile GetTileAt(int x, int y)
{
return this.GetChunkAt(x, y).GetTileAt(x, y);
}
public void SetTileAt(int x, int y, STile tile)
{
this.GetChunkAt(x, y).SetTileAt(x, y, tile);
}
public bool HasTileAt(int x, int y)
{
return this.HasChunkAt(x, y) && this.GetChunkAt(x, y).hasTileAt(new Vector2(x, y));

View File

View File

@ -1,37 +1,68 @@
class Tile
{
public string Name { get; set; }
public IntPtr Texture { get; set; }
public int Hardness { get; set; }
private readonly IntPtr texture;
private static IntPtr breakingTexture;
public Tile(string name, string textureName)
public Tile(string name, string textureName, int hardness)
{
this.Name = name;
this.Hardness = hardness;
var rl = Context.Get().ResourceLoader;
var (ptr, size) = rl.LoadToIntPtr("assets." + textureName + ".png");
var sdlBuffer = SDL_RWFromMem(ptr, size);
var surface = IMG_Load_RW(sdlBuffer, 1);
var texture = Context.Get().Renderer.CreateTextureFromSurface(surface);
this.Texture = texture;
this.texture = texture;
if (breakingTexture == IntPtr.Zero)
{
loadBreakingTexture();
}
SDL_FreeSurface(surface);
}
~Tile()
{
SDL_DestroyTexture(this.Texture);
SDL_DestroyTexture(this.texture);
}
public void Render(int x, int y)
public void Render(int x, int y, STile tile)
{
var renderer = Context.Get().Renderer;
var scale = Context.Get().FrontendGameState.Settings.GameScale;
var camera = Context.Get().FrontendGameState.Camera;
renderer.DrawTexture(
this.Texture,
this.texture,
(x - (int)camera.position.X) * scale,
(y - (int)camera.position.Y) * scale,
Constants.TileSize * scale,
Constants.TileSize * scale
);
if (tile.Hits > 0)
{
var breakingOffset = (int)((double)tile.Hits / this.Hardness * 4);
renderer.DrawTexture(
breakingTexture,
(x - (int)camera.position.X) * scale,
(y - (int)camera.position.Y) * scale,
Constants.TileSize * scale,
Constants.TileSize * scale,
breakingOffset,
16,
16
);
}
}
private static void loadBreakingTexture()
{
var rl = Context.Get().ResourceLoader;
var (ptr, size) = rl.LoadToIntPtr("assets.breaking.png");
var sdlBuffer = SDL_RWFromMem(ptr, size);
var surface = IMG_Load_RW(sdlBuffer, 1);
breakingTexture = Context.Get().Renderer.CreateTextureFromSurface(surface);
SDL_FreeSurface(surface);
}
}

View File

@ -9,7 +9,7 @@ class TileRegistry
public void RegisterTile()
{
this.Tiles.Add(1, new Tile("stone", "stone"));
this.Tiles.Add(1, new Tile("stone", "stone", 5));
}
public Tile GetTile(int id)

View File

@ -1,6 +1,6 @@
class ChunkGenerator
{
public static Chunk CreateFilledChunk(int x, int y, int fill)
public static Chunk CreateFilledChunk(int x, int y, STile fill)
{
var chunk = new Chunk(x, y);
for (var i = 0; i < Constants.ChunkSize; i++)
@ -12,9 +12,4 @@ class ChunkGenerator
}
return chunk;
}
public static Chunk CreateFilledChunk(int x, int y, Tiles fill)
{
return CreateFilledChunk(x, y, (int)fill);
}
}

View File

@ -128,6 +128,25 @@ class Renderer
w = w,
h = h
};
SDL_RenderCopy(renderer, texture, IntPtr.Zero, ref rect);
_ = SDL_RenderCopy(this.renderer, texture, IntPtr.Zero, ref rect);
}
public void DrawTexture(IntPtr texture, int x, int y, int w, int h, int offsetIndex, int srcWidth, int srcHeight)
{
SDL_Rect rect = new()
{
x = x,
y = y,
w = w,
h = h
};
SDL_Rect srcRect = new()
{
x = srcWidth * offsetIndex,
y = 0,
w = srcWidth,
h = srcHeight,
};
_ = SDL_RenderCopy(this.renderer, texture, ref srcRect, ref rect);
}
}

View File

@ -42,6 +42,26 @@ class Frontend : IFrontend
Console.WriteLine($"Mouse moved to {mousePos}");
ctx.FrontendGameState.MousePosition = mousePos;
}
if (e.type == SDL_EventType.SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_LEFT)
{
var amp = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + ctx.FrontendGameState.Camera.position;
if (ctx.GameState.World.HasChunkAt(amp))
{
var chunk = ctx.GameState.World.GetChunkAt(amp);
var tile = chunk.GetTileAt(amp);
var tileId = tile.Id;
if (tile.Id != 0)
{
var tileRegistry = ctx.TileRegistry;
var hardness = tileRegistry.GetTile(tileId).Hardness;
chunk.SetTileAt(amp, tile with { Hits = tile.Hits + 1 });
if (tile.Hits >= hardness)
{
chunk.SetTileAt(amp, STile.From(0));
}
}
}
}
if (e.type == SDL_EventType.SDL_KEYDOWN && e.key.repeat == 0)
{
var movementInput = ctx.FrontendGameState.MovementInput;

View File

@ -4,19 +4,23 @@ class WorldRenderer : IRenderer
{
var ctx = Context.Get();
var world = ctx.GameState.World;
var renderer = ctx.Renderer;
var tileRegistry = ctx.TileRegistry;
foreach (var (_, chunk) in world.Chunks)
{
for (int y = 0; y < Constants.ChunkSize; y++)
for (var y = 0; y < Constants.ChunkSize; y++)
{
for (int x = 0; x < Constants.ChunkSize; x++)
for (var x = 0; x < Constants.ChunkSize; x++)
{
var tileId = chunk.GetTile(x, y);
var tile = tileRegistry.GetTile(tileId);
var stile = chunk.GetTile(x, y);
if (stile.Id == 0)
{
continue;
}
var tile = tileRegistry.GetTile(stile.Id);
var chunkOffsetX = chunk.X * Constants.TileSize * Constants.ChunkSize;
var chunkOffsetY = chunk.Y * Constants.TileSize * Constants.ChunkSize;
tile.Render(x * 16 + chunkOffsetX, y * 16 + chunkOffsetY);
tile.Render(x * 16 + chunkOffsetX, y * 16 + chunkOffsetY, stile);
}
}
}