added shadow, render layering and ores
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<PublishTrimmed>true</PublishTrimmed>
|
<PublishTrimmed>true</PublishTrimmed>
|
||||||
<TrimmerDefaultAction>link</TrimmerDefaultAction>
|
<TrimmerDefaultAction>link</TrimmerDefaultAction>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 298 B After Width: | Height: | Size: 338 B |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 277 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 190 B |
|
After Width: | Height: | Size: 254 B |
|
Before Width: | Height: | Size: 454 B After Width: | Height: | Size: 431 B |
|
|
@ -1,4 +1,5 @@
|
||||||
using Mine2d.backend.data;
|
using Mine2d.backend.data;
|
||||||
|
using Mine2d.core;
|
||||||
using Mine2d.core.data;
|
using Mine2d.core.data;
|
||||||
using Mine2d.engine.system.annotations;
|
using Mine2d.engine.system.annotations;
|
||||||
|
|
||||||
|
|
@ -11,28 +12,42 @@ public class Breaking
|
||||||
public static void TickHybrid()
|
public static void TickHybrid()
|
||||||
{
|
{
|
||||||
var ctx = Context.Get();
|
var ctx = Context.Get();
|
||||||
ctx.GameState.Players.ForEach(player =>
|
foreach (var player in ctx.GameState.Players)
|
||||||
|
{
|
||||||
|
player.MiningCooldown = Math.Max(0, player.MiningCooldown - 1);
|
||||||
|
if (player.Mining == Vector2.Zero)
|
||||||
{
|
{
|
||||||
player.MiningCooldown = Math.Max(0, player.MiningCooldown - 1);
|
continue;
|
||||||
if (player.Mining != Vector2.Zero && player.MiningCooldown == 0 && ctx.GameState.World.HasChunkAt(player.Mining))
|
}
|
||||||
|
|
||||||
|
if (player.MiningCooldown > 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((player.GetCenter() - player.Mining).LengthSquared() > Constants.BreakDistance * Constants.BreakDistance)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.GameState.World.HasChunkAt(player.Mining))
|
||||||
|
{
|
||||||
|
var chunk = ctx.GameState.World.GetChunkAt(player.Mining);
|
||||||
|
var tile = chunk.GetTileAt(player.Mining);
|
||||||
|
var tileId = tile.Id;
|
||||||
|
if (tileId != 0)
|
||||||
{
|
{
|
||||||
var chunk = ctx.GameState.World.GetChunkAt(player.Mining);
|
player.MiningCooldown = 10;
|
||||||
var tile = chunk.GetTileAt(player.Mining);
|
var tileRegistry = ctx.TileRegistry;
|
||||||
var tileId = tile.Id;
|
var hardness = tileRegistry.GetTile(tileId).Hardness;
|
||||||
if (tileId != 0)
|
chunk.SetTileAt(player.Mining, tile with { Hits = tile.Hits + 1 });
|
||||||
|
if (tile.Hits >= hardness)
|
||||||
{
|
{
|
||||||
player.MiningCooldown = 10;
|
chunk.SetTileAt(player.Mining, STile.From(0));
|
||||||
var tileRegistry = ctx.TileRegistry;
|
|
||||||
var hardness = tileRegistry.GetTile(tileId).Hardness;
|
|
||||||
chunk.SetTileAt(player.Mining, tile with { Hits = tile.Hits + 1 });
|
|
||||||
if (tile.Hits >= hardness)
|
|
||||||
{
|
|
||||||
chunk.SetTileAt(player.Mining, STile.From(0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Interaction(InteractorKind.Server, "break")]
|
[Interaction(InteractorKind.Server, "break")]
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public class Connect
|
||||||
{
|
{
|
||||||
Name = packet.PlayerName,
|
Name = packet.PlayerName,
|
||||||
Id = packet.PlayerGuid,
|
Id = packet.PlayerGuid,
|
||||||
Position = new Vector2(32 * 16 * 1000 + 16 * 14.5f, 32 * 16 * 10 + 16 * 14.5f),
|
Position = new Vector2(512244, 5390),
|
||||||
Movement = new Vector2(0, 0)
|
Movement = new Vector2(0, 0)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,11 @@ public class WorldGeneration
|
||||||
new Vector2(0, 1),
|
new Vector2(0, 1),
|
||||||
new Vector2(1, 0),
|
new Vector2(1, 0),
|
||||||
new Vector2(0, -1),
|
new Vector2(0, -1),
|
||||||
new Vector2(-1, 0)
|
new Vector2(-1, 0),
|
||||||
|
new Vector2(1, 1),
|
||||||
|
new Vector2(1, -1),
|
||||||
|
new Vector2(-1, -1),
|
||||||
|
new Vector2(-1, 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
[Interaction(InteractorKind.Server, "playerMoved")]
|
[Interaction(InteractorKind.Server, "playerMoved")]
|
||||||
|
|
@ -30,7 +34,7 @@ public class WorldGeneration
|
||||||
if (!hasChunkGenerated)
|
if (!hasChunkGenerated)
|
||||||
{
|
{
|
||||||
var chunkPos = World.ToChunkPos(generationTarget);
|
var chunkPos = World.ToChunkPos(generationTarget);
|
||||||
world.AddChunk(ChunkGenerator.CreateFilledChunk((int)chunkPos.X, (int)chunkPos.Y, STile.From(Tiles.Stone)));
|
world.AddChunk(ChunkGenerator.CreateChunk((int)chunkPos.X, (int)chunkPos.Y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,6 @@ public class Constants
|
||||||
{
|
{
|
||||||
public const int ChunkSize = 32;
|
public const int ChunkSize = 32;
|
||||||
public const int TileSize = 16;
|
public const int TileSize = 16;
|
||||||
|
public const int BreakDistance = 64;
|
||||||
public static Vector2 Gravity = new(0, 0.1f);
|
public static Vector2 Gravity = new(0, 0.1f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,10 @@ public class PlayerEntity
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var pL = p.Position + new Vector2(0, -8);
|
var pL = p.Position + new Vector2(0, -8);
|
||||||
|
var pL2 = p.Position + new Vector2(0, -24);
|
||||||
hasCollision =
|
hasCollision =
|
||||||
world.HasChunkAt(pL) && world.GetChunkAt(pL).HasTileAt(pL);
|
world.HasChunkAt(pL) && world.GetChunkAt(pL).HasTileAt(pL)
|
||||||
|
|| world.HasChunkAt(pL2) && world.GetChunkAt(pL2).HasTileAt(pL2);
|
||||||
if (hasCollision)
|
if (hasCollision)
|
||||||
{
|
{
|
||||||
p.Movement = p.Movement with { X = 0 };
|
p.Movement = p.Movement with { X = 0 };
|
||||||
|
|
@ -41,9 +43,11 @@ public class PlayerEntity
|
||||||
} while (hasCollision);
|
} while (hasCollision);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var pR = p.Position + new Vector2(16, -8);
|
var pR = p.Position + new Vector2(14, -8);
|
||||||
|
var pR2 = p.Position + new Vector2(14, -24);
|
||||||
hasCollision =
|
hasCollision =
|
||||||
world.HasChunkAt(pR) && world.GetChunkAt(pR).HasTileAt(pR);
|
world.HasChunkAt(pR) && world.GetChunkAt(pR).HasTileAt(pR)
|
||||||
|
|| world.HasChunkAt(pR2) && world.GetChunkAt(pR2).HasTileAt(pR2);
|
||||||
if (hasCollision)
|
if (hasCollision)
|
||||||
{
|
{
|
||||||
p.Movement = p.Movement with { X = 0 };
|
p.Movement = p.Movement with { X = 0 };
|
||||||
|
|
@ -52,8 +56,8 @@ public class PlayerEntity
|
||||||
} while (hasCollision);
|
} while (hasCollision);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var pL = p.Position;
|
var pL = p.Position + new Vector2(0, 0);
|
||||||
var pR = p.Position + new Vector2(16, 0);
|
var pR = p.Position + new Vector2(14, 0);
|
||||||
hasCollision =
|
hasCollision =
|
||||||
world.HasChunkAt(pL) && world.GetChunkAt(pL).HasTileAt(pL)
|
world.HasChunkAt(pL) && world.GetChunkAt(pL).HasTileAt(pL)
|
||||||
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).HasTileAt(pR);
|
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).HasTileAt(pR);
|
||||||
|
|
@ -65,8 +69,8 @@ public class PlayerEntity
|
||||||
} while (hasCollision);
|
} while (hasCollision);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var pL = p.Position + new Vector2(0, -32);
|
var pL = p.Position + new Vector2(0, -28);
|
||||||
var pR = p.Position + new Vector2(16, -32);
|
var pR = p.Position + new Vector2(14, -28);
|
||||||
hasCollision =
|
hasCollision =
|
||||||
world.HasChunkAt(pL) && world.GetChunkAt(pL).HasTileAt(pL)
|
world.HasChunkAt(pL) && world.GetChunkAt(pL).HasTileAt(pL)
|
||||||
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).HasTileAt(pR);
|
|| world.HasChunkAt(pR) && world.GetChunkAt(pR).HasTileAt(pR);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
using Mine2d.engine;
|
||||||
|
|
||||||
|
namespace Mine2d.core.tiles;
|
||||||
|
|
||||||
|
public class OreTile : Tile
|
||||||
|
{
|
||||||
|
public OreTile(string name, string[] texturePath, int hardness) : base(name, new TextureFactory().CreateTexture(texturePath), hardness)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Mine2d.core.data;
|
using Mine2d.core.data;
|
||||||
|
using Mine2d.engine;
|
||||||
|
|
||||||
namespace Mine2d.core.tiles;
|
namespace Mine2d.core.tiles;
|
||||||
|
|
||||||
|
|
@ -26,6 +27,13 @@ public class Tile
|
||||||
SDL_FreeSurface(surface);
|
SDL_FreeSurface(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Tile(string name, IntPtr texture, int hardness)
|
||||||
|
{
|
||||||
|
this.Name = name;
|
||||||
|
this.Hardness = hardness;
|
||||||
|
this.texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
~Tile()
|
~Tile()
|
||||||
{
|
{
|
||||||
SDL_DestroyTexture(this.texture);
|
SDL_DestroyTexture(this.texture);
|
||||||
|
|
@ -36,6 +44,7 @@ public class Tile
|
||||||
var renderer = Context.Get().Renderer;
|
var renderer = Context.Get().Renderer;
|
||||||
var scale = Context.Get().FrontendGameState.Settings.GameScale;
|
var scale = Context.Get().FrontendGameState.Settings.GameScale;
|
||||||
var camera = Context.Get().FrontendGameState.Camera;
|
var camera = Context.Get().FrontendGameState.Camera;
|
||||||
|
Renderer.SetTextureColorModulate(this.texture, 255);
|
||||||
renderer.DrawTexture(
|
renderer.DrawTexture(
|
||||||
this.texture,
|
this.texture,
|
||||||
(x - (int)camera.Position.X) * scale,
|
(x - (int)camera.Position.X) * scale,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ namespace Mine2d.core.tiles;
|
||||||
public enum Tiles
|
public enum Tiles
|
||||||
{
|
{
|
||||||
Stone = 1,
|
Stone = 1,
|
||||||
|
Ore1 = 2,
|
||||||
|
Ore2 = 3,
|
||||||
|
Ore3 = 4,
|
||||||
|
Ore4 = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TileRegistry
|
public class TileRegistry
|
||||||
|
|
@ -12,6 +16,10 @@ public class TileRegistry
|
||||||
public void RegisterTile()
|
public void RegisterTile()
|
||||||
{
|
{
|
||||||
this.Tiles.Add(1, new Tile("stone", "stone", 5));
|
this.Tiles.Add(1, new Tile("stone", "stone", 5));
|
||||||
|
this.Tiles.Add(2, new OreTile("ore1", new string[] { "stone", "ore1" }, 5));
|
||||||
|
this.Tiles.Add(3, new OreTile("ore2", new string[] { "stone", "ore2" }, 7));
|
||||||
|
this.Tiles.Add(4, new OreTile("ore3", new string[] { "stone", "ore3" }, 8));
|
||||||
|
this.Tiles.Add(5, new OreTile("ore4", new string[] { "stone", "ore4" }, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile GetTile(int id)
|
public Tile GetTile(int id)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,43 @@ public class ChunkGenerator
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Chunk CreateChunk(int x, int y)
|
||||||
|
{
|
||||||
|
var fill = new STile
|
||||||
|
{
|
||||||
|
Id = (int)Tiles.Stone,
|
||||||
|
};
|
||||||
|
var chunk = new Chunk(x, y);
|
||||||
|
for (var i = 0; i < Constants.ChunkSize; i++)
|
||||||
|
{
|
||||||
|
for (var j = 0; j < Constants.ChunkSize; j++)
|
||||||
|
{
|
||||||
|
if (new Random().Next(0, 100) < 10)
|
||||||
|
{
|
||||||
|
fill.Id = (int)Tiles.Ore1;
|
||||||
|
}
|
||||||
|
else if (new Random().Next(0, 100) < 10)
|
||||||
|
{
|
||||||
|
fill.Id = (int)Tiles.Ore2;
|
||||||
|
}
|
||||||
|
else if (new Random().Next(0, 100) < 10)
|
||||||
|
{
|
||||||
|
fill.Id = (int)Tiles.Ore3;
|
||||||
|
}
|
||||||
|
else if (new Random().Next(0, 100) < 10)
|
||||||
|
{
|
||||||
|
fill.Id = (int)Tiles.Ore4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fill.Id = (int)Tiles.Stone;
|
||||||
|
}
|
||||||
|
chunk.SetTile(i, j, fill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
public static Chunk CreateSpawnChunk(int x, int y)
|
public static Chunk CreateSpawnChunk(int x, int y)
|
||||||
{
|
{
|
||||||
var chunk = new Chunk(x, y);
|
var chunk = new Chunk(x, y);
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,16 @@ public class Renderer
|
||||||
ProcessStatus(SDL_RenderCopy(this.renderer, texture, ref srcRect, ref rect));
|
ProcessStatus(SDL_RenderCopy(this.renderer, texture, ref srcRect, ref rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetTextureColorModulate(IntPtr texture, int r, int g, int b)
|
||||||
|
{
|
||||||
|
ProcessStatus(SDL_SetTextureColorMod(texture, (byte)r, (byte)g, (byte)b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetTextureColorModulate(IntPtr texture, int a)
|
||||||
|
{
|
||||||
|
SetTextureColorModulate(texture, a, a, a);
|
||||||
|
}
|
||||||
|
|
||||||
public static void ProcessStatus(int status)
|
public static void ProcessStatus(int status)
|
||||||
{
|
{
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
|
|
@ -166,4 +176,10 @@ public class Renderer
|
||||||
throw new SDLException(SDL_GetError());
|
throw new SDLException(SDL_GetError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal (int srcW, int srcH) GetTextureSize(IntPtr src)
|
||||||
|
{
|
||||||
|
ProcessStatus(SDL_QueryTexture(src, out _, out _, out var srcW, out var srcH));
|
||||||
|
return (srcW, srcH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
namespace Mine2d.engine;
|
||||||
|
|
||||||
|
public class TextureFactory
|
||||||
|
{
|
||||||
|
private readonly ResourceLoader resourceLoader;
|
||||||
|
private readonly Renderer renderer;
|
||||||
|
private readonly Dictionary<string, IntPtr> textureCache = new();
|
||||||
|
|
||||||
|
public TextureFactory()
|
||||||
|
{
|
||||||
|
this.resourceLoader = Context.Get().ResourceLoader;
|
||||||
|
this.renderer = Context.Get().Renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr CreateTexture(string[] path)
|
||||||
|
{
|
||||||
|
var target = this.loadTexture(path[0]);
|
||||||
|
for (var i = 1; i < path.Length; i++)
|
||||||
|
{
|
||||||
|
var t = this.loadTexture(path[i]);
|
||||||
|
target = this.mergeTextures(target, t);
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntPtr mergeTextures(IntPtr t1, IntPtr t2)
|
||||||
|
{
|
||||||
|
var (w, h) = this.renderer.GetTextureSize(t1);
|
||||||
|
var target = SDL_CreateTexture(this.renderer.GetRaw(), SDL_PIXELFORMAT_RGBA8888, (int)SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET, w, h);
|
||||||
|
Renderer.ProcessStatus(SDL_SetRenderTarget(this.renderer.GetRaw(), target));
|
||||||
|
Renderer.ProcessStatus(SDL_SetTextureBlendMode(target, SDL_BlendMode.SDL_BLENDMODE_BLEND));
|
||||||
|
this.renderer.DrawTexture(t1, 0, 0, w, h);
|
||||||
|
this.renderer.DrawTexture(t2, 0, 0, w, h);
|
||||||
|
Renderer.ProcessStatus(SDL_SetRenderTarget(this.renderer.GetRaw(), IntPtr.Zero));
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntPtr loadTexture(string path)
|
||||||
|
{
|
||||||
|
if (this.textureCache.TryGetValue(path, out var value))
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
var (ptr, size) = this.resourceLoader.LoadToIntPtr("assets." + path + ".png");
|
||||||
|
var sdlBuffer = SDL_RWFromMem(ptr, size);
|
||||||
|
var surface = IMG_Load_RW(sdlBuffer, 1);
|
||||||
|
var texture = this.renderer.CreateTextureFromSurface(surface);
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
this.textureCache.Add(path, texture);
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ public class Window
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
w,
|
w,
|
||||||
h,
|
h,
|
||||||
SDL_WindowFlags.SDL_WINDOW_VULKAN | SDL_WindowFlags.SDL_WINDOW_RESIZABLE
|
SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL_WindowFlags.SDL_WINDOW_RESIZABLE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
namespace Mine2d.frontend.renderer;
|
||||||
|
|
||||||
|
public class BackgroundRenderer : IRenderer
|
||||||
|
{
|
||||||
|
private readonly IntPtr texture;
|
||||||
|
|
||||||
|
public BackgroundRenderer()
|
||||||
|
{
|
||||||
|
var rl = Context.Get().ResourceLoader;
|
||||||
|
var (ptr, size) = rl.LoadToIntPtr("assets.background.png");
|
||||||
|
var sdlBuffer = SDL_RWFromMem(ptr, size);
|
||||||
|
var surface = IMG_Load_RW(sdlBuffer, 1);
|
||||||
|
this.texture = Context.Get().Renderer.CreateTextureFromSurface(surface);
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
~BackgroundRenderer()
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(this.texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Render()
|
||||||
|
{
|
||||||
|
var ctx = Context.Get();
|
||||||
|
var camera = ctx.FrontendGameState.Camera;
|
||||||
|
var scale = ctx.FrontendGameState.Settings.GameScale;
|
||||||
|
var renderer = ctx.Renderer;
|
||||||
|
var (w, h) = ctx.Window.GetSize();
|
||||||
|
var offsetX = camera.Position.X / scale % 16;
|
||||||
|
var offsetY = camera.Position.Y / scale % 16;
|
||||||
|
w /= scale;
|
||||||
|
h /= scale;
|
||||||
|
|
||||||
|
for (var x = -16; x < w + 16; x += 16)
|
||||||
|
{
|
||||||
|
for (var y = -16; y < h + 16; y += 16)
|
||||||
|
{
|
||||||
|
var rx = (x - (int)offsetX) * scale;
|
||||||
|
var ry = (y - (int)offsetY) * scale;
|
||||||
|
var rw = 16 * scale;
|
||||||
|
var rh = 16 * scale;
|
||||||
|
renderer.DrawTexture(this.texture, rx, ry, rw, rh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ public class GameRenderer : IRenderer
|
||||||
|
|
||||||
public GameRenderer()
|
public GameRenderer()
|
||||||
{
|
{
|
||||||
|
this.renderers.Add(new BackgroundRenderer());
|
||||||
this.renderers.Add(new WorldRenderer());
|
this.renderers.Add(new WorldRenderer());
|
||||||
this.renderers.Add(new PlayerRenderer());
|
this.renderers.Add(new PlayerRenderer());
|
||||||
this.renderers.Add(new WorldCursorRenderer());
|
this.renderers.Add(new WorldCursorRenderer());
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ public class PlayerRenderer : IRenderer
|
||||||
|
|
||||||
ctx.Renderer.DrawRect(
|
ctx.Renderer.DrawRect(
|
||||||
(player.Position.X - (int)camera.Position.X) * scale,
|
(player.Position.X - (int)camera.Position.X) * scale,
|
||||||
(player.Position.Y - (int)camera.Position.Y) * scale - 32 * scale,
|
(player.Position.Y - (int)camera.Position.Y) * scale - 28 * scale,
|
||||||
16 * scale,
|
14 * scale,
|
||||||
32 * scale
|
28 * scale
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,11 @@ public class WorldCursorRenderer : IRenderer
|
||||||
var scale = ctx.FrontendGameState.Settings.GameScale;
|
var scale = ctx.FrontendGameState.Settings.GameScale;
|
||||||
var camera = ctx.FrontendGameState.Camera;
|
var camera = ctx.FrontendGameState.Camera;
|
||||||
var absoluteMousePos = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + camera.Position;
|
var absoluteMousePos = ctx.FrontendGameState.MousePosition / ctx.FrontendGameState.Settings.GameScale + camera.Position;
|
||||||
|
if (PlayerEntity.GetSelf() == null || (absoluteMousePos - PlayerEntity.GetSelf().GetCenter()).LengthSquared() > Constants.BreakDistance * Constants.BreakDistance)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx.GameState.World.HasTileAt((int)absoluteMousePos.X, (int)absoluteMousePos.Y))
|
if (ctx.GameState.World.HasTileAt((int)absoluteMousePos.X, (int)absoluteMousePos.Y))
|
||||||
{
|
{
|
||||||
var ts = Constants.TileSize;
|
var ts = Constants.TileSize;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,46 @@
|
||||||
using Mine2d.core;
|
using Mine2d.core;
|
||||||
|
using Mine2d.engine;
|
||||||
|
|
||||||
namespace Mine2d.frontend.renderer;
|
namespace Mine2d.frontend.renderer;
|
||||||
|
|
||||||
public class WorldRenderer : IRenderer
|
public class WorldRenderer : IRenderer
|
||||||
{
|
{
|
||||||
|
private readonly IntPtr light;
|
||||||
|
private IntPtr overlay;
|
||||||
|
private int overlayWidth, overlayHeight;
|
||||||
|
|
||||||
|
public WorldRenderer()
|
||||||
|
{
|
||||||
|
var rl = Context.Get().ResourceLoader;
|
||||||
|
var (ptr, size) = rl.LoadToIntPtr("assets.light.png");
|
||||||
|
var sdlBuffer = SDL_RWFromMem(ptr, size);
|
||||||
|
var surface = IMG_Load_RW(sdlBuffer, 1);
|
||||||
|
this.light = Context.Get().Renderer.CreateTextureFromSurface(surface);
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
var (w, h) = Context.Get().Window.GetSize();
|
||||||
|
this.overlay = SDL_CreateTexture(Context.Get().Renderer.GetRaw(), SDL_PIXELFORMAT_RGBA8888, (int)SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
public void Render()
|
public void Render()
|
||||||
{
|
{
|
||||||
var ctx = Context.Get();
|
var ctx = Context.Get();
|
||||||
var world = ctx.GameState.World;
|
var world = ctx.GameState.World;
|
||||||
var tileRegistry = ctx.TileRegistry;
|
var tileRegistry = ctx.TileRegistry;
|
||||||
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), this.overlay));
|
||||||
|
var (ww, wh) = ctx.Window.GetSize();
|
||||||
|
if (wh != this.overlayHeight || ww != this.overlayWidth)
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(this.overlay);
|
||||||
|
this.overlay = SDL_CreateTexture(ctx.Renderer.GetRaw(), SDL_PIXELFORMAT_RGBA8888, (int)SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET, ww, wh);
|
||||||
|
this.overlayWidth = ww;
|
||||||
|
this.overlayHeight = wh;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTexture(this.overlay);
|
||||||
|
var renderer = Context.Get().Renderer;
|
||||||
|
var scale = ctx.FrontendGameState.Settings.GameScale;
|
||||||
|
var camera = Context.Get().FrontendGameState.Camera;
|
||||||
|
Renderer.ProcessStatus(SDL_SetTextureBlendMode(this.light, SDL_BlendMode.SDL_BLENDMODE_BLEND));
|
||||||
foreach (var (_, chunk) in world.Chunks)
|
foreach (var (_, chunk) in world.Chunks)
|
||||||
{
|
{
|
||||||
for (var y = 0; y < Constants.ChunkSize; y++)
|
for (var y = 0; y < Constants.ChunkSize; y++)
|
||||||
|
|
@ -16,17 +48,46 @@ public class WorldRenderer : IRenderer
|
||||||
for (var x = 0; x < Constants.ChunkSize; x++)
|
for (var x = 0; x < Constants.ChunkSize; x++)
|
||||||
{
|
{
|
||||||
var stile = chunk.GetTile(x, y);
|
var stile = chunk.GetTile(x, y);
|
||||||
|
var chunkOffsetX = chunk.X * Constants.TileSize * Constants.ChunkSize;
|
||||||
|
var chunkOffsetY = chunk.Y * Constants.TileSize * Constants.ChunkSize;
|
||||||
|
var drawX = x * 16 + chunkOffsetX;
|
||||||
|
var drawY = y * 16 + chunkOffsetY;
|
||||||
if (stile.Id == 0)
|
if (stile.Id == 0)
|
||||||
{
|
{
|
||||||
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), this.overlay));
|
||||||
|
renderer.DrawTexture(
|
||||||
|
this.light,
|
||||||
|
(drawX - (int)camera.Position.X - 40) * scale,
|
||||||
|
(drawY - (int)camera.Position.Y - 40) * scale,
|
||||||
|
96 * scale,
|
||||||
|
96 * scale
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), IntPtr.Zero));
|
||||||
|
}
|
||||||
|
|
||||||
var tile = tileRegistry.GetTile(stile.Id);
|
var tile = tileRegistry.GetTile(stile.Id);
|
||||||
var chunkOffsetX = chunk.X * Constants.TileSize * Constants.ChunkSize;
|
tile.Render(drawX, drawY, stile);
|
||||||
var chunkOffsetY = chunk.Y * Constants.TileSize * Constants.ChunkSize;
|
|
||||||
tile.Render(x * 16 + chunkOffsetX, y * 16 + chunkOffsetY, stile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), IntPtr.Zero));
|
||||||
|
Renderer.ProcessStatus(SDL_SetTextureBlendMode(this.overlay, SDL_BlendMode.SDL_BLENDMODE_MUL));
|
||||||
|
Renderer.ProcessStatus(SDL_RenderCopy(ctx.Renderer.GetRaw(), this.overlay, IntPtr.Zero, IntPtr.Zero));
|
||||||
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), IntPtr.Zero));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearTexture(IntPtr texture)
|
||||||
|
{
|
||||||
|
var ctx = Context.Get();
|
||||||
|
var renderer = ctx.Renderer;
|
||||||
|
var (w, h) = renderer.GetTextureSize(texture);
|
||||||
|
var clearRect = new SDL_Rect { x = 0, y = 0, w = w, h = h };
|
||||||
|
Renderer.ProcessStatus(SDL_SetRenderTarget(ctx.Renderer.GetRaw(), texture));
|
||||||
|
_ = SDL_SetRenderDrawColor(ctx.Renderer.GetRaw(), 0, 0, 0, 255);
|
||||||
|
Renderer.ProcessStatus(SDL_RenderFillRect(ctx.Renderer.GetRaw(), ref clearRect));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
using Mine2d.engine;
|
|
||||||
|
|
||||||
namespace Mine2d.state;
|
namespace Mine2d.state;
|
||||||
|
|
||||||
public class Player
|
public class Player
|
||||||
|
|
@ -11,8 +9,8 @@ public class Player
|
||||||
public Vector2 Mining { get; set; }
|
public Vector2 Mining { get; set; }
|
||||||
public int MiningCooldown { get; set; }
|
public int MiningCooldown { get; set; }
|
||||||
|
|
||||||
public Line GetBottomCollisionLine()
|
public Vector2 GetCenter()
|
||||||
{
|
{
|
||||||
return new Line(this.Position, this.Position + new Vector2(16, 0));
|
return this.Position + new Vector2(7, -14);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||