improved inventory rendering

This commit is contained in:
MasterGordon 2023-01-02 01:09:11 +01:00
parent 7f94a2eb20
commit cf9e6eb072
27 changed files with 285 additions and 194 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 797 B

After

Width:  |  Height:  |  Size: 812 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

View File

@ -57,7 +57,6 @@ public class Publisher
this.subscribers[attribute.Type].Add(method);
Console.WriteLine("Subscribed!");
}
});
}

View File

@ -37,9 +37,10 @@ public class Breaking
var tileId = tile.Id;
if (tileId != 0)
{
player.MiningCooldown = 10;
var tileRegistry = ctx.TileRegistry;
var hardness = tileRegistry.GetTile(tileId).Hardness;
var hardnessBonus = Math.Min(1, player.GetHarvestLevel() / hardness);
player.MiningCooldown = 50 - (player.GetMiningSpeed() * hardnessBonus);
if(tile.Hits == 0) {
ctx.GameState.World.Cracks.Enqueue(new CrackQueueEntry
{

View File

@ -1,17 +1,13 @@
using Mine2d.engine.system.annotations;
using Mine2d.game.backend.network.packets;
using Mine2d.game.core;
using Mine2d.game.core.data;
using Mine2d.game.core.tiles;
using Mine2d.game.frontend.inventory;
namespace Mine2d.game.backend.interactor;
[Interactor]
public class Place
public class PlayerInteract
{
[Interaction(InteractorKind.Server, PacketType.Place)]
public static void PlaceServer(PlacePacket packet)
[Interaction(InteractorKind.Server, PacketType.PlayerInteract)]
public static void InteractServer(PlayerInteractPacket packet)
{
var ctx = Context.Get();
var player = ctx.GameState.Players.Find(p => p.Id == packet.PlayerGuid);

View File

@ -10,7 +10,7 @@ public enum PacketType
Break,
PlayerMoved,
BlockBroken,
Place,
PlayerInteract,
Jump,
DebugCommand
}

View File

@ -1,8 +1,8 @@
namespace Mine2d.game.backend.network.packets;
public class PlacePacket : Packet
public class PlayerInteractPacket : Packet
{
public override PacketType Type => PacketType.Place;
public override PacketType Type => PacketType.PlayerInteract;
public Guid PlayerGuid { get; init; }
public Vector2 Target { get; init; }

View File

@ -8,7 +8,7 @@ public static class InventoryUtils
{
for (var i = 0; i < inventory.Length; i++)
{
if (inventory[i] != null && inventory[i].Id == id)
if (inventory[i] != null && inventory[i].Id == id && inventory[i].IsStackable())
{
return i;
}

View File

@ -16,4 +16,5 @@ public enum ItemId
RawTungsten = 115,
RawUranium = 116,
Diamond = 117,
PickaxeBasic = 200,
}

View File

@ -1,3 +1,5 @@
using Mine2d.game.core.items;
namespace Mine2d.game.core.data;
public class ItemStack
@ -24,4 +26,14 @@ public class ItemStack
{
return Context.Get().ItemRegistry.GetItem(this.Id).Name;
}
public bool IsStackable()
{
return Context.Get().ItemRegistry.GetItem(this.Id).GetKind() == ItemKind.Default;
}
public ItemKind GetKind()
{
return Context.Get().ItemRegistry.GetItem(this.Id).GetKind();
}
}

View File

@ -40,4 +40,9 @@ public class Item
public virtual void Interact(ItemStack stack, Vector2 position, Player player) {
}
public virtual ItemKind GetKind()
{
return ItemKind.Default;
}
}

View File

@ -2,6 +2,15 @@ using Mine2d.game.core.data;
namespace Mine2d.game.core.items;
public enum ItemKind
{
Default,
Pickaxe,
Helmet,
Chestplate,
Leggings,
}
public class ItemRegistry
{
private readonly Dictionary<ItemId, Item> items = new();
@ -21,6 +30,7 @@ public class ItemRegistry
this.Register(ItemId.RawTungsten, new Item(ItemId.RawTungsten, "Raw Tungsten", "items.raw-tungsten" ));
this.Register(ItemId.RawUranium, new Item(ItemId.RawUranium, "Raw Uranium", "items.raw-uranium" ));
this.Register(ItemId.Diamond, new Item(ItemId.Diamond, "Diamond", "items.diamond" ));
this.Register(ItemId.PickaxeBasic, new PickaxeItem(ItemId.PickaxeBasic, "Basic Pickaxe", "items.pickaxe-basic"));
}
public void Register(ItemId id, Item item)

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Mine2d.game.core.data;
namespace Mine2d.game.core.items;
public class PickaxeItem : Item
{
public PickaxeItem(ItemId id, string name, string textureName) : base(id, name, textureName)
{
}
public override ItemKind GetKind()
{
return ItemKind.Pickaxe;
}
}

View File

@ -1,7 +1,7 @@
using Mine2d.game.core.data;
namespace Mine2d.game.core.tiles
{
namespace Mine2d.game.core.tiles;
public class Workbench : Tile
{
public Workbench(string name, string texturePath, int hardness) : base(name, texturePath, hardness, ItemId.Workbench)
@ -13,4 +13,3 @@ namespace Mine2d.game.core.tiles
return false;
}
}
}

View File

@ -21,6 +21,7 @@ public class ChunkGenerator
}
public static readonly OpenSimplexNoise Noise = new();
public static readonly OpenSimplexNoise Noise2 = new();
public static Chunk CreateChunk(int x, int y)
{
var fill = new STile
@ -33,8 +34,9 @@ public class ChunkGenerator
for (var j = 0; j < Constants.ChunkSize; j++)
{
var n = (Noise.coherentNoise(i + (x * 32), j + (y * 32), 0, 1, 25, 0.5f, 0.9f));
var n2 = (Noise2.coherentNoise(i + (x * 32), j + (y * 32), 0, 1, 25, 0.5f, 0.9f));
// Console.WriteLine(i * (x * 32) + " "+ j * (y * 32));
if (n > 0.08) continue;
if (n > 0.08 || n2 > 0.08) continue;
chunk.SetTile(i, j, fill);
}
}

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Mine2d.game.core.data;
namespace Mine2d.game.frontend;
public static class ItemRenderer
{
private static readonly Dictionary<int, (IntPtr, int, int)> Textures = new();
public static void RenderItemStack(ItemStack stack, Vector2 position, bool renderTooltip = true)
{
var texture = stack.GetTexture();
var renderer = Context.Get().Renderer;
var uiScale = Context.Get().FrontendGameState.Settings.UiScale;
renderer.DrawTexture(texture, (int)position.X, (int)position.Y, 16 * uiScale, 16 * uiScale);
if (stack.Count > 1)
{
var (textTexture, width, height) = GetCountTexture(stack.Count);
renderer.DrawTexture(
textTexture,
(int)position.X + (16 * uiScale) - width - (1 * uiScale),
(int)position.Y + (16 * uiScale) - height + (1 * uiScale),
width,
height
);
}
if (renderTooltip)
{
var cursorPosition = Context.Get().FrontendGameState.CursorPosition;
if (cursorPosition.X >= position.X
&& cursorPosition.X <= position.X + (16 * uiScale)
&& cursorPosition.Y >= position.Y
&& cursorPosition.Y <= position.Y + (16 * uiScale)
)
{
Context.Get().FrontendGameState.Tooltip = stack.GetName();
}
}
}
public static (IntPtr, int, int) GetCountTexture(int count)
{
if (Textures.TryGetValue(count, out var value))
{
return value;
}
var (textTexture, width, height, _) = Context.Get().Renderer.CreateTextTexture("" + count);
Textures.Add(count, (textTexture, width, height));
return (textTexture, width, height);
}
}

View File

@ -65,7 +65,7 @@ public class InventoryInput
}
[EventListener(EventType.KeyUp, EventPriority.Highest)]
public static void OnKeyUpOpenInventory(SDL_Event e)
public static void OnKeyUpOpenInventory(SDL_Event _)
{
var frontendGameState = Context.Get().FrontendGameState;
if(frontendGameState.OpenInventory != InventoryKind.None)

View File

@ -6,8 +6,8 @@ using Mine2d.engine.system;
using Mine2d.engine.system.annotations;
using Mine2d.game.backend.network.packets;
namespace Mine2d.game.frontend.events
{
namespace Mine2d.game.frontend.events;
public class PlayerMovementInput
{
[EventListener(EventType.KeyDown)]
@ -20,4 +20,3 @@ namespace Mine2d.game.frontend.events
}
}
}
}

View File

@ -4,7 +4,7 @@ using Mine2d.game.backend.network.packets;
namespace Mine2d.game.frontend.events;
public class PlayerPlaceInput
public class PlayerInteractInput
{
[EventListener(EventType.MouseButtonDown)]
public static void OnMouseDown(SDL_Event e)
@ -15,11 +15,11 @@ public class PlayerPlaceInput
}
var ctx = Context.Get();
var amp = ctx.FrontendGameState.CursorPosition
/ ctx.FrontendGameState.Settings.GameScale
var amp = (ctx.FrontendGameState.CursorPosition
/ ctx.FrontendGameState.Settings.GameScale)
+ ctx.FrontendGameState.Camera.Position;
ctx.Backend.ProcessPacket(new PlacePacket
ctx.Backend.ProcessPacket(new PlayerInteractPacket
{
PlayerGuid = ctx.FrontendGameState.PlayerGuid,
Target = amp,

View File

@ -1,7 +1,6 @@
using Mine2d.game.core;
namespace Mine2d.game.frontend.inventory
{
namespace Mine2d.game.frontend.inventory;
public class PlayerInventoryRenderer : Inventory
{
@ -28,7 +27,6 @@ namespace Mine2d.game.frontend.inventory
var player = PlayerEntity.GetSelf();
var inventory = player.Inventory.Inventory;
var hotbar = player.Inventory.Hotbar;
var cursorPosition = Context.Get().FrontendGameState.CursorPosition;
for (var i = 0; i < hotbar.Length; i++)
{
var stack = hotbar[i];
@ -36,29 +34,7 @@ namespace Mine2d.game.frontend.inventory
{
continue;
}
var itemTexture = stack.GetTexture();
ctx.Renderer.DrawTexture(
itemTexture,
((4 + (i * 21)) * uiScale) + this.x,
(4 * uiScale) + this.y,
16 * uiScale,
16 * uiScale
);
ctx.Renderer.DrawText(
"" + stack.Count,
((4 + (i * 21)) * uiScale) + this.x,
(14 * uiScale) + this.y
);
if (player.Inventory.Cursor == null &&
cursorPosition.X >= ((4 + (i * 21)) * uiScale) + this.x
&& cursorPosition.X <= ((4 + (i * 21)) * uiScale) + this.x + (16 * uiScale)
&& cursorPosition.Y >= (4 * uiScale) + this.y
&& cursorPosition.Y <= (4 * uiScale) + this.y + (16 * uiScale)
)
{
Context.Get().FrontendGameState.Tooltip = stack.GetName();
}
ItemRenderer.RenderItemStack(stack, new Vector2(((4 + (i * 21)) * uiScale) + this.x, (4 * uiScale) + this.y), player.Inventory.Cursor == null);
}
for (var i = 0; i < inventory.Length; i++)
{
@ -68,34 +44,19 @@ namespace Mine2d.game.frontend.inventory
continue;
}
var itemTexture = stack.GetTexture();
ctx.Renderer.DrawTexture(
itemTexture,
((4 + ((i % 9) * 21)) * uiScale) + this.x,
((4 + 21 + ((i / 9) * 21)) * uiScale) + this.y,
16 * uiScale,
16 * uiScale
);
ctx.Renderer.DrawText(
"" + stack.Count,
((4 + ((i % 9) * 21)) * uiScale) + this.x,
((14 + 21 + ((i / 9) * 21)) * uiScale) + this.y
);
if (player.Inventory.Cursor == null &&
cursorPosition.X >= ((4 + ((i % 9) * 21)) * uiScale) + this.x
&& cursorPosition.X <= ((4 + ((i % 9) * 21)) * uiScale) + this.x + (16 * uiScale)
&& cursorPosition.Y >= ((4 + 21 + ((i / 9) * 21)) * uiScale) + this.y
&& cursorPosition.Y <= ((4 + 21 + ((i / 9) * 21)) * uiScale) + this.y + (16 * uiScale)
)
{
Context.Get().FrontendGameState.Tooltip = stack.GetName();
ItemRenderer.RenderItemStack(stack, new Vector2(((4 + ((i % 9) * 21)) * uiScale) + this.x, ((4 + 21 + ((i / 9) * 21)) * uiScale) + this.y), player.Inventory.Cursor == null);
}
var pickaxe = player.Inventory.Pickaxe;
if (pickaxe != null)
{
ItemRenderer.RenderItemStack(pickaxe, new Vector2(((4 + (9 * 21)) * uiScale) + this.x, (((5 * 21) + 4) * uiScale) + this.y), player.Inventory.Cursor == null);
}
}
public override void OnClick(SDL_Event e)
{
var cursorPosition = Context.Get().FrontendGameState.CursorPosition;
var player = PlayerEntity.GetSelf();
// is hotbar
if (cursorPosition.X >= this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.X <= this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * 9 * Context.Get().FrontendGameState.Settings.UiScale)
@ -103,7 +64,6 @@ namespace Mine2d.game.frontend.inventory
&& cursorPosition.Y <= this.y + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * Context.Get().FrontendGameState.Settings.UiScale)
)
{
var player = PlayerEntity.GetSelf();
var hotbar = player.Inventory.Hotbar;
var index = (int)((cursorPosition.X - (this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale))) / (21 * Context.Get().FrontendGameState.Settings.UiScale));
if (e.button.button == SDL_BUTTON_LEFT)
@ -122,14 +82,12 @@ namespace Mine2d.game.frontend.inventory
}
}
}
// is inventory
if (cursorPosition.X >= this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.X <= this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * 9 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.Y >= this.y + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * Context.Get().FrontendGameState.Settings.UiScale)
&& cursorPosition.Y <= this.y + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * 6 * Context.Get().FrontendGameState.Settings.UiScale)
)
{
var player = PlayerEntity.GetSelf();
var inventory = player.Inventory.Inventory;
var index = (int)((cursorPosition.X - (this.x + (4 * Context.Get().FrontendGameState.Settings.UiScale))) / (21 * Context.Get().FrontendGameState.Settings.UiScale))
+ ((int)((cursorPosition.Y - (this.y + (4 * Context.Get().FrontendGameState.Settings.UiScale) + (21 * Context.Get().FrontendGameState.Settings.UiScale))) / (21 * Context.Get().FrontendGameState.Settings.UiScale)) * 9);
@ -149,6 +107,27 @@ namespace Mine2d.game.frontend.inventory
}
}
}
if (IsCursorOnSlot(((4 + (9 * 21)) * Context.Get().FrontendGameState.Settings.UiScale) + this.x, (((5 * 21) + 4) * Context.Get().FrontendGameState.Settings.UiScale) + this.y))
{
if (e.button.button == SDL_BUTTON_LEFT)
{
player.Inventory.SwapPickaxeWithCursor();
}
if (e.button.button == SDL_BUTTON_RIGHT)
{
player.Inventory.SwapPickaxeWithCursor();
}
}
}
private static bool IsCursorOnSlot(int x, int y)
{
var cursorPosition = Context.Get().FrontendGameState.CursorPosition;
var width = 21 * Context.Get().FrontendGameState.Settings.UiScale;
var height = 21 * Context.Get().FrontendGameState.Settings.UiScale;
return cursorPosition.X >= x
&& cursorPosition.X <= x + width
&& cursorPosition.Y >= y
&& cursorPosition.Y <= y + height;
}
}

View File

@ -11,7 +11,7 @@ public class GameRenderer : IRenderer
this.renderers.Add(new BackgroundRenderer());
this.renderers.Add(new WorldRenderer());
this.renderers.Add(new PlayerRenderer());
this.renderers.Add(new ItemRenderer());
this.renderers.Add(new ItemEnitityRenderer());
this.renderers.Add(new WorldCursorRenderer());
this.renderers.Add(new HudRenderer());
this.renderers.Add(new InventoryRenderer());

View File

@ -37,13 +37,10 @@ public class HudRenderer : IRenderer
var renderer = Context.Get().Renderer;
var uiScale = Context.Get().FrontendGameState.Settings.UiScale;
var activeSlot = Context.Get().FrontendGameState.HotbarIndex;
// var window = Context.Get().Window;
// var (width, height) = window.GetSize();
var (hotbarWidth, hotbarHeight) = renderer.GetTextureSize(this.hotbarTexture);
var player = PlayerEntity.GetSelf();
renderer.DrawTexture(this.hotbarTexture, 0, 0, hotbarWidth * uiScale, hotbarHeight * uiScale);
renderer.DrawTexture(this.hotbarActiveTexture, activeSlot * 24 * uiScale, 0, 24 * uiScale, 24 * uiScale);
var cursorPosition = Context.Get().FrontendGameState.CursorPosition;
for (var i = 0; i < player?.Inventory.Hotbar.Length; i++)
{
var stack = player.Inventory.Hotbar[i];
@ -52,13 +49,7 @@ public class HudRenderer : IRenderer
continue;
}
var texture = stack.GetTexture();
renderer.DrawTexture(texture, (4 + (i * 24)) * uiScale, 4 * uiScale, 16 * uiScale, 16 * uiScale);
renderer.DrawText("" + stack.Count, (4 + (i * 24)) * uiScale, 14 * uiScale);
if (cursorPosition.X >= (4 + (i * 24)) * uiScale && cursorPosition.X <= (4 + (i * 24) + 16) * uiScale && cursorPosition.Y >= 4 * uiScale && cursorPosition.Y <= (4 + 16) * uiScale)
{
Context.Get().FrontendGameState.Tooltip = stack.GetName();
}
ItemRenderer.RenderItemStack(stack, new Vector2((4 + (i * 24)) * uiScale, 4 * uiScale));
}
}
}

View File

@ -20,20 +20,7 @@ public class InventoryRenderer : IRenderer
if (player.Inventory.Cursor != null)
{
var cursorPosition = ctx.FrontendGameState.CursorPosition;
var itemTexture = player.Inventory.Cursor.GetTexture();
var uiScale = ctx.FrontendGameState.Settings.UiScale;
ctx.Renderer.DrawTexture(
itemTexture,
(int)(cursorPosition.X + 2),
(int)(cursorPosition.Y + 2),
16 * uiScale,
16 * uiScale
);
ctx.Renderer.DrawText(
"" + player.Inventory.Cursor.Count,
(int)(cursorPosition.X + 2),
(int)(cursorPosition.Y + (12 * uiScale))
);
ItemRenderer.RenderItemStack(player.Inventory.Cursor, cursorPosition + new Vector2(2, 2));
}
}
}

View File

@ -4,7 +4,7 @@ using Mine2d.game.core.data.entities;
namespace Mine2d.game.frontend.renderer;
public class ItemRenderer : IRenderer
public class ItemEnitityRenderer : IRenderer
{
public void Render()
{

View File

@ -14,4 +14,12 @@ public class Player
{
return this.Position + new Vector2(7, -14);
}
public int GetMiningSpeed() {
return 10;
}
public int GetHarvestLevel() {
return 1;
}
}

View File

@ -1,5 +1,6 @@
using Mine2d.game.core;
using Mine2d.game.core.data;
using Mine2d.game.core.items;
namespace Mine2d.game.state;
@ -7,6 +8,10 @@ public class PlayerInventory
{
public ItemStack[] Hotbar { get; set; } = new ItemStack[9];
public ItemStack[] Inventory { get; set; } = new ItemStack[5 * 9];
public ItemStack Pickaxe { get; set; }
public ItemStack Helmet { get; set; }
public ItemStack Chestplate { get; set; }
public ItemStack Leggings { get; set; }
public ItemStack Cursor { get; set; }
public bool PickupItemStack(ItemStack itemStack)
@ -34,7 +39,7 @@ public class PlayerInventory
public void SwapWithCursor(int slot, ItemStack[] inventory)
{
if (this.Cursor != null && inventory[slot] != null && this.Cursor.Id == inventory[slot].Id)
if (this.Cursor != null && inventory[slot] != null && this.Cursor.Id == inventory[slot].Id && this.Cursor.IsStackable())
{
inventory[slot].Count += this.Cursor.Count;
this.Cursor = null;
@ -65,7 +70,7 @@ public class PlayerInventory
{
inventory[slot] = new ItemStack(this.Cursor.Id, 1);
}
else if (inventory[slot].Id == this.Cursor.Id)
else if (inventory[slot].Id == this.Cursor.Id && this.Cursor.IsStackable())
{
inventory[slot].Count++;
}
@ -79,4 +84,28 @@ public class PlayerInventory
this.Cursor = null;
}
}
public void SwapPickaxeWithCursor()
{
if (this.Cursor != null && this.Cursor?.GetKind() != ItemKind.Pickaxe) return;
(this.Pickaxe, this.Cursor) = (this.Cursor, this.Pickaxe);
}
public void SwapHelmetWithCursor()
{
if (this.Cursor != null && this.Cursor?.GetKind() != ItemKind.Helmet) return;
(this.Helmet, this.Cursor) = (this.Cursor, this.Helmet);
}
public void SwapChestplateWithCursor()
{
if (this.Cursor != null && this.Cursor?.GetKind() != ItemKind.Chestplate) return;
(this.Chestplate, this.Cursor) = (this.Cursor, this.Chestplate);
}
public void SwapLeggingsWithCursor()
{
if (this.Cursor != null && this.Cursor?.GetKind() != ItemKind.Leggings) return;
(this.Leggings, this.Cursor) = (this.Cursor, this.Leggings);
}
}