Skip to content

Commit

Permalink
Spritesheet rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
hunter2actual committed Apr 3, 2024
1 parent d75688f commit db3300f
Show file tree
Hide file tree
Showing 28 changed files with 151 additions and 199 deletions.
8 changes: 4 additions & 4 deletions DalamudMinesweeper.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"Author": "hunter2_",
"Name": "Minesweeper",
"InternalName": "DalamudMinesweeper",
"AssemblyVersion": "0.0.0.12",
"AssemblyVersion": "0.0.0.13",
"Description": "Logic puzzle in which you find and flag hidden mines. \nLeft click to uncover a square, right click to place a flag. \nClick a number that has the right amount of adjacent flags to reveal adjacent tiles. \nThe game ends when all mines are flagged and all safe squares have been uncovered. \nClick the smiley face to start a new game.",
"ApplicableVersion": "any",
"Tags": [
Expand All @@ -18,9 +18,9 @@
"LoadPriority": 0,
"Punchline": "Classic puzzle game.",
"AcceptsFeedback": true,
"DownloadLinkInstall": "https://github.com/hunter2actual/DalamudMinesweeper/releases/download/0.0.0.12/latest.zip",
"DownloadLinkUpdate": "https://github.com/hunter2actual/DalamudMinesweeper/releases/download/0.0.0.12/latest.zip",
"DownloadLinkInstall": "https://github.com/hunter2actual/DalamudMinesweeper/releases/download/0.0.0.13/latest.zip",
"DownloadLinkUpdate": "https://github.com/hunter2actual/DalamudMinesweeper/releases/download/0.0.0.13/latest.zip",
"IconUrl": "https://raw.githubusercontent.com/hunter2actual/DalamudMinesweeper/master/images/icon.png",
"Changelog": "Draw background and border, add OpenMainUi button from Dalamud"
"Changelog": "Spritesheet rendering to prevent image bleed"
}
]
82 changes: 0 additions & 82 deletions DalamudMinesweeper/ClassicSprites.cs

This file was deleted.

102 changes: 102 additions & 0 deletions DalamudMinesweeper/ClassicSpritesSheet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using Dalamud.Plugin;
using Dalamud.Interface.Internal;
using System.IO;
using System;
using ImGuiNET;
using System.Numerics;
using System.Collections.Generic;
using DalamudMinesweeper.Game;

namespace DalamudMinesweeper;

public class ClassicSprites : IDisposable {
private DalamudPluginInterface _pluginInterface { get; set; }
private IDalamudTextureWrap Sheet { get; init; }
private record SpriteData(Vector2 topLeftCoord, Vector2 sizePx);
private readonly Dictionary<string, SpriteData> _spriteDict;

public ClassicSprites(DalamudPluginInterface pluginInterface)
{
_pluginInterface = pluginInterface;
Sheet = LoadImage("spritesheet.png");

_spriteDict = new Dictionary<string, SpriteData>
{
{ "0", new SpriteData(new Vector2(40, 88), new Vector2(16, 16)) },
{ "1", new SpriteData(new Vector2(0, 88), new Vector2(16, 16)) },
{ "2", new SpriteData(new Vector2(0, 20), new Vector2(16, 16)) },
{ "3", new SpriteData(new Vector2(40, 0), new Vector2(16, 16)) },
{ "4", new SpriteData(new Vector2(40, 20), new Vector2(16, 16)) },
{ "5", new SpriteData(new Vector2(20, 0), new Vector2(16, 16)) },
{ "6", new SpriteData(new Vector2(60, 88), new Vector2(16, 16)) },
{ "7", new SpriteData(new Vector2(20, 88), new Vector2(16, 16)) },
{ "8", new SpriteData(new Vector2(20, 40), new Vector2(16, 16)) },
{ "Flag", new SpriteData(new Vector2(0, 40), new Vector2(16, 16)) },
{ "Hidden", new SpriteData(new Vector2(20, 20), new Vector2(16, 16)) },
{ "Mine1", new SpriteData(new Vector2(0, 0), new Vector2(16, 16)) },
{ "Mine2", new SpriteData(new Vector2(40, 40), new Vector2(16, 16)) },
{ "Smiley", new SpriteData(new Vector2(60, 0), new Vector2(24, 24)) },
{ "SmileyClicked", new SpriteData(new Vector2(0, 60), new Vector2(24, 24)) },
{ "SmileyDead", new SpriteData(new Vector2(28, 60), new Vector2(24, 24)) },
{ "SmileyShades", new SpriteData(new Vector2(60, 28), new Vector2(24, 24)) },
{ "SmileySoy", new SpriteData(new Vector2(60, 56), new Vector2(24, 24)) }
};
}

public Vector2 TileSize => _spriteDict["0"].sizePx;
public Vector2 SmileySize => _spriteDict["Smiley"].sizePx;

public void DrawTile(ImDrawListPtr drawList, Cell cell, Vector2 cursorPos, int zoom = 1)
=> Draw(drawList, _spriteDict[CellToSpriteName(cell)], cursorPos, zoom);

public void DrawSmiley(ImDrawListPtr drawList, string smileyName, Vector2 cursorPos, int zoom = 1)
=> Draw(drawList, _spriteDict[smileyName], cursorPos, zoom);

private void Draw(ImDrawListPtr drawList, SpriteData sprite, Vector2 cursorPos, int zoom)
{
var uvMin = sprite.topLeftCoord / Sheet.Size;
var uvMax = (sprite.topLeftCoord + sprite.sizePx) / Sheet.Size;

drawList.AddImage(
Sheet.ImGuiHandle,
cursorPos,
cursorPos + sprite.sizePx * zoom,
uvMin,
uvMax);
}

private static string CellToSpriteName(Cell cell)
{
if (!cell.isRevealed)
{
if (cell.isFlagged)
{
return "Flag";
}
return "Hidden";
}
return cell.contents switch
{
CellContents.Clear => "0",
CellContents.Mine => "Mine1",
CellContents.ExplodedMine => "Mine2",
CellContents.Number => cell.numNeighbouringMines switch {
< 1 or > 8 => throw new("Invalid number of mines in cell " + cell.numNeighbouringMines),
_ => cell.numNeighbouringMines.ToString()
},
_ => throw new("Unknown cell contents.")
};
}

public void Dispose()
{
Sheet.Dispose();
}

private IDalamudTextureWrap LoadImage(string path)
{
var fullPath = Path.Combine(_pluginInterface.AssemblyLocation.Directory?.FullName!, path);
return _pluginInterface.UiBuilder.LoadImage(fullPath);
}

}
62 changes: 31 additions & 31 deletions DalamudMinesweeper/Components/GameBoard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ public void Draw(Vector2 start)
var mousePos = ImGui.GetMousePos();
var drawList = ImGui.GetWindowDrawList();

var gridSquareSizePx = _classicSprites.Tile0.Width * _configuration.Zoom;
var gridSquareSizePx = (int) _classicSprites.TileSize.X * _configuration.Zoom;
_gridSquareSizePxVec2.X = _gridSquareSizePxVec2.Y = gridSquareSizePx;

for (int y = 0; y < Game.Height; y++) {
for (int x = 0; x < Game.Width; x++) {
drawList.AddImage(GetCellImage(Game.GetCell(x, y)).ImGuiHandle, cursorPos, cursorPos + _gridSquareSizePxVec2);
_classicSprites.DrawTile(drawList, Game.GetCell(x, y), cursorPos, _configuration.Zoom);

if (MouseInSquare(mousePos, cursorPos, gridSquareSizePx) && ImGui.IsWindowFocused()) {
DrawHighlightSquare(drawList, cursorPos);
Expand All @@ -52,35 +52,35 @@ public void Draw(Vector2 start)
}
}

private IDalamudTextureWrap GetCellImage(Cell cell)
{
if (!cell.isRevealed)
{
if (cell.isFlagged)
{
return _classicSprites.TileFlag;
}
return _classicSprites.TileHidden;
}
return cell.contents switch
{
CellContents.Clear => _classicSprites.Tile0,
CellContents.Mine => _classicSprites.TileMine,
CellContents.ExplodedMine => _classicSprites.TileMineBoom,
CellContents.Number => cell.numNeighbouringMines switch {
1 => _classicSprites.Tile1,
2 => _classicSprites.Tile2,
3 => _classicSprites.Tile3,
4 => _classicSprites.Tile4,
5 => _classicSprites.Tile5,
6 => _classicSprites.Tile6,
7 => _classicSprites.Tile7,
8 => _classicSprites.Tile8,
_ => throw new("Invalid number of mines in cell " + cell.numNeighbouringMines)
},
_ => throw new("Unknown cell contents.")
};
}
// private IDalamudTextureWrap GetCellImage(Cell cell)
// {
// if (!cell.isRevealed)
// {
// if (cell.isFlagged)
// {
// return _classicSprites.TileFlag;
// }
// return _classicSprites.TileHidden;
// }
// return cell.contents switch
// {
// CellContents.Clear => _classicSprites.Tile0,
// CellContents.Mine => _classicSprites.TileMine,
// CellContents.ExplodedMine => _classicSprites.TileMineBoom,
// CellContents.Number => cell.numNeighbouringMines switch {
// 1 => _classicSprites.Tile1,
// 2 => _classicSprites.Tile2,
// 3 => _classicSprites.Tile3,
// 4 => _classicSprites.Tile4,
// 5 => _classicSprites.Tile5,
// 6 => _classicSprites.Tile6,
// 7 => _classicSprites.Tile7,
// 8 => _classicSprites.Tile8,
// _ => throw new("Invalid number of mines in cell " + cell.numNeighbouringMines)
// },
// _ => throw new("Unknown cell contents.")
// };
// }

private void DrawHighlightSquare(ImDrawListPtr drawList, Vector2 cursorPos)
{
Expand Down
17 changes: 8 additions & 9 deletions DalamudMinesweeper/Components/Header.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,43 +27,42 @@ public void Draw(Vector2 start, float headerWidth)
var mousePos = ImGui.GetMousePos();
var drawList = ImGui.GetWindowDrawList();

IDalamudTextureWrap smileyToDraw = _classicSprites.Smiley;
var smileySize = smileyToDraw.Size * _configuration.Zoom;
string smileyToDraw = "Smiley";
var smileySize = _classicSprites.SmileySize * _configuration.Zoom;
float leftPadding = (float) ((headerWidth - smileySize.X) * 0.5);
var cursorPos = start + new Vector2(leftPadding, 0);

if (Game.GameState == GameState.Victorious)
{
smileyToDraw = _classicSprites.SmileyShades;
smileyToDraw = "SmileyShades";
}
else if (Game.GameState == GameState.Boom)
{
smileyToDraw = _classicSprites.SmileyDead;
smileyToDraw = "SmileyDead";
}

if (MouseInSquare(mousePos, cursorPos, (int) smileySize.X)
&& ImGui.IsWindowFocused())
{
if (ImGui.IsMouseClicked(ImGuiMouseButton.Left))
{
smileyToDraw = _classicSprites.SmileyClicked;
smileyToDraw = "SmileyClicked";
_smileyClicked = true;
}
else if (ImGui.IsMouseDown(ImGuiMouseButton.Left) && _smileyClicked)
{
smileyToDraw = _classicSprites.SmileyClicked;
smileyToDraw = "SmileyClicked";
}
else if (ImGui.IsMouseReleased(ImGuiMouseButton.Left) && _smileyClicked)
{
smileyToDraw = _classicSprites.Smiley;
smileyToDraw = "Smiley";
_smileyClicked = false;
_initialiseGame();
}
}

// TODO soyface when clicking on game

drawList.AddImage(smileyToDraw.ImGuiHandle, cursorPos, cursorPos + smileySize);
_classicSprites.DrawSmiley(drawList, smileyToDraw, cursorPos, _configuration.Zoom);
}

private bool MouseInSquare(Vector2 mousePos, Vector2 cursorPos, int squareSize)
Expand Down
Loading

0 comments on commit db3300f

Please sign in to comment.