diff --git a/Mine2d/assets/hud/player-inventory.png b/Mine2d/assets/hud/player-inventory.png new file mode 100644 index 0000000..a42212e Binary files /dev/null and b/Mine2d/assets/hud/player-inventory.png differ diff --git a/Mine2d/engine/Renderer.cs b/Mine2d/engine/Renderer.cs index 1b008b0..711cca6 100644 --- a/Mine2d/engine/Renderer.cs +++ b/Mine2d/engine/Renderer.cs @@ -102,7 +102,7 @@ public class Renderer public void DrawText(string text, int x, int y, bool center = false) { - var (texture, width, height, surfaceMessage) = CreateTextTexture(text); + var (texture, width, height, surfaceMessage) = this.CreateTextTexture(text); var rect = new SDL_Rect { @@ -144,7 +144,7 @@ public class Renderer }; ProcessStatus(SDL_RenderCopy(this.renderer, texture, IntPtr.Zero, ref rect)); } -public void DrawTexture(IntPtr texture, int x, int y, int w, int h, int srcX, int srcY, int srcWidth, int srcHeight) + public void DrawTexture(IntPtr texture, int x, int y, int w, int h, int srcX, int srcY, int srcWidth, int srcHeight) { SDL_Rect rect = new() { @@ -200,9 +200,14 @@ public void DrawTexture(IntPtr texture, int x, int y, int w, int h, int srcX, in } } - internal (int srcW, int srcH) GetTextureSize(IntPtr src) + public (int srcW, int srcH) GetTextureSize(IntPtr src) { ProcessStatus(SDL_QueryTexture(src, out _, out _, out var srcW, out var srcH)); return (srcW, srcH); } + + public void SetDrawBlendMode(SDL_BlendMode blendMode) + { + ProcessStatus(SDL_SetRenderDrawBlendMode(this.renderer, blendMode)); + } } diff --git a/Mine2d/engine/TextureFactory.cs b/Mine2d/engine/TextureFactory.cs index 617229d..2bdae67 100644 --- a/Mine2d/engine/TextureFactory.cs +++ b/Mine2d/engine/TextureFactory.cs @@ -35,7 +35,7 @@ public class TextureFactory return target; } - private IntPtr LoadTexture(string path) + public IntPtr LoadTexture(string path) { if (this.textureCache.TryGetValue(path, out var value)) { diff --git a/Mine2d/game/Context.cs b/Mine2d/game/Context.cs index 0ea03e7..d6460a2 100644 --- a/Mine2d/game/Context.cs +++ b/Mine2d/game/Context.cs @@ -3,6 +3,7 @@ using Mine2d.engine.networking; using Mine2d.game.core.items; using Mine2d.game.core.tiles; using Mine2d.game.frontend; +using Mine2d.game.frontend.inventory; using Mine2d.game.state; namespace Mine2d.game; @@ -21,6 +22,7 @@ public class Context public ResourceLoader ResourceLoader { get; set; } public TextureFactory TextureFactory { get; set; } public GameAudio GameAudio { get; set; } + public InventoryRegistry InventoryRegistry { get; set; } public static Context Instance { get; set; } public Context( @@ -45,6 +47,7 @@ public class Context this.TileRegistry = new TileRegistry(); this.ItemRegistry = new ItemRegistry(); this.GameAudio = new GameAudio(); + this.InventoryRegistry = new InventoryRegistry(); Instance = this; } diff --git a/Mine2d/game/frontend/events/InventoryInput.cs b/Mine2d/game/frontend/events/InventoryInput.cs index 4a7bcb0..31302a8 100644 --- a/Mine2d/game/frontend/events/InventoryInput.cs +++ b/Mine2d/game/frontend/events/InventoryInput.cs @@ -1,12 +1,13 @@ using Mine2d.engine.system; using Mine2d.engine.system.annotations; +using Mine2d.game.state; namespace Mine2d.game.frontend.events; public class InventoryInput { [EventListener(EventType.KeyDown)] - public static void OnKeyDown(SDL_Event e) + public static void OnKeyDownSwitchHotbar(SDL_Event e) { var frontendGameState = Context.Get().FrontendGameState; frontendGameState.HotbarIndex = e.key.keysym.sym switch @@ -38,4 +39,18 @@ public class InventoryInput frontendGameState.HotbarIndex = 0; } } + + [EventListener(EventType.KeyDown)] + public static void OnKeyDownOpenInventory(SDL_Event e) + { + var frontendGameState = Context.Get().FrontendGameState; + if(e.key.keysym.sym == SDL_Keycode.SDLK_TAB) + { + if(frontendGameState.OpenInventory != Inventory.Player) { + frontendGameState.OpenInventory = Inventory.Player; + } else { + frontendGameState.OpenInventory = Inventory.None; + } + } + } } diff --git a/Mine2d/game/frontend/inventory/InventoryConstants.cs b/Mine2d/game/frontend/inventory/InventoryConstants.cs new file mode 100644 index 0000000..42920a9 --- /dev/null +++ b/Mine2d/game/frontend/inventory/InventoryConstants.cs @@ -0,0 +1,6 @@ +namespace Mine2d.game.frontend.inventory; + +public static class InventoryConstants +{ + public static readonly int ExtraSlotsWidth = 21; +} \ No newline at end of file diff --git a/Mine2d/game/frontend/inventory/InventoryRegistry.cs b/Mine2d/game/frontend/inventory/InventoryRegistry.cs new file mode 100644 index 0000000..c484ae4 --- /dev/null +++ b/Mine2d/game/frontend/inventory/InventoryRegistry.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Mine2d.game.state; + +namespace Mine2d.game.frontend.inventory; + +public class InventoryRegistry +{ + private readonly Dictionary inventoryRenderers = new(); + + public InventoryRegistry() + { + this.inventoryRenderers.Add(Inventory.Player, new PlayerInventoryRenderer()); + } + + public IInventoryRenderer GetRenderer(Inventory inventory) + { + return this.inventoryRenderers[inventory]; + } +} diff --git a/Mine2d/game/frontend/inventory/InventoryRenderer.cs b/Mine2d/game/frontend/inventory/InventoryRenderer.cs new file mode 100644 index 0000000..27df789 --- /dev/null +++ b/Mine2d/game/frontend/inventory/InventoryRenderer.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Mine2d.engine; + +namespace Mine2d.game.frontend.inventory; + +public interface IInventoryRenderer : IRenderer +{ +} \ No newline at end of file diff --git a/Mine2d/game/frontend/inventory/PlayerInventoryRenderer.cs b/Mine2d/game/frontend/inventory/PlayerInventoryRenderer.cs new file mode 100644 index 0000000..4f4a487 --- /dev/null +++ b/Mine2d/game/frontend/inventory/PlayerInventoryRenderer.cs @@ -0,0 +1,23 @@ +namespace Mine2d.game.frontend.inventory +{ + public class PlayerInventoryRenderer : IInventoryRenderer + { + private IntPtr texture = IntPtr.Zero; + + public void Render() + { + var ctx = Context.Get(); + if(this.texture == IntPtr.Zero) { + this.texture = ctx.TextureFactory.LoadTexture("hud.player-inventory"); + } + var (width, height) = ctx.Renderer.GetTextureSize(this.texture); + width *= ctx.FrontendGameState.Settings.UiScale; + height *= ctx.FrontendGameState.Settings.UiScale; + var extraSlotsWidth = InventoryConstants.ExtraSlotsWidth * ctx.FrontendGameState.Settings.UiScale; + var (windowWidth, windowHeight) = (ctx.FrontendGameState.WindowWidth, ctx.FrontendGameState.WindowHeight); + var x = (windowWidth - (width - extraSlotsWidth)) / 2; + var y = (windowHeight - height) / 2; + ctx.Renderer.DrawTexture(this.texture, x, y, width, height); + } + } +} \ No newline at end of file diff --git a/Mine2d/game/frontend/renderer/GameRenderer.cs b/Mine2d/game/frontend/renderer/GameRenderer.cs index c607db4..cb60643 100644 --- a/Mine2d/game/frontend/renderer/GameRenderer.cs +++ b/Mine2d/game/frontend/renderer/GameRenderer.cs @@ -14,6 +14,7 @@ public class GameRenderer : IRenderer this.renderers.Add(new ItemRenderer()); this.renderers.Add(new WorldCursorRenderer()); this.renderers.Add(new HudRenderer()); + this.renderers.Add(new InventoryRenderer()); this.renderers.Add(new TooltipRenderer()); } diff --git a/Mine2d/game/frontend/renderer/InventoryRenderer.cs b/Mine2d/game/frontend/renderer/InventoryRenderer.cs new file mode 100644 index 0000000..789cb95 --- /dev/null +++ b/Mine2d/game/frontend/renderer/InventoryRenderer.cs @@ -0,0 +1,19 @@ +using Mine2d.engine; +using Mine2d.game.state; + +namespace Mine2d.game.frontend.renderer +{ + public class InventoryRenderer : IRenderer + { + public void Render() { + var ctx = Context.Get(); + var inventory = ctx.FrontendGameState.OpenInventory; + if(inventory == Inventory.None) return; + ctx.Renderer.SetColor(0, 0, 0, 200); + ctx.Renderer.SetDrawBlendMode(SDL_BlendMode.SDL_BLENDMODE_BLEND); + ctx.Renderer.DrawRect(0, 0, ctx.FrontendGameState.WindowWidth, ctx.FrontendGameState.WindowHeight); + var inventoryRenderer = ctx.InventoryRegistry.GetRenderer(inventory); + inventoryRenderer.Render(); + } + } +} \ No newline at end of file diff --git a/Mine2d/game/state/FrontendGameState.cs b/Mine2d/game/state/FrontendGameState.cs index 966ca42..07fa2f6 100644 --- a/Mine2d/game/state/FrontendGameState.cs +++ b/Mine2d/game/state/FrontendGameState.cs @@ -2,6 +2,11 @@ using Mine2d.game.core; namespace Mine2d.game.state; +public enum Inventory { + None, + Player +} + public class FrontendGameState { public Vector2 MovementInput { get; set; } @@ -15,6 +20,7 @@ public class FrontendGameState public string PlayerName { get; set; } = "Player"; public int HotbarIndex { get; set; } public string Tooltip { get; set; } = "Test"; + public Inventory OpenInventory { get; set; } = Inventory.None; } public class Settings