[Add] Resize board
This commit is contained in:
@@ -11,6 +11,9 @@ namespace Minesweeper.Presentation.Views
|
||||
{
|
||||
public sealed class GameView : MonoBehaviour, IGameView
|
||||
{
|
||||
private const float ResizeRefreshDelaySeconds = 0.5f;
|
||||
private const float ResizeSizeEpsilon = 0.5f;
|
||||
|
||||
[SerializeField] private GameObject gameRoot;
|
||||
[SerializeField] private GameObject pauseRoot;
|
||||
[SerializeField] private GameObject resultRoot;
|
||||
@@ -28,8 +31,15 @@ namespace Minesweeper.Presentation.Views
|
||||
[SerializeField] private MinesweeperUiConfig uiConfig;
|
||||
|
||||
private readonly Dictionary<int, CellView> cellsByCoordinate = new Dictionary<int, CellView>();
|
||||
private IReadOnlyList<BoardCellData> currentCells;
|
||||
private bool boardInputEnabled = true;
|
||||
private bool currentRevealUnflaggedMines;
|
||||
private bool resizeRefreshPending;
|
||||
private int currentBoardWidth;
|
||||
private int currentBoardHeight;
|
||||
private float currentPixelsPerUnitMultiplier = 1f;
|
||||
private float resizeStableAt;
|
||||
private Vector2 lastObservedLayoutSize;
|
||||
|
||||
public event Action RestartRequested;
|
||||
public event Action GoToMenuRequested;
|
||||
@@ -58,6 +68,11 @@ namespace Minesweeper.Presentation.Views
|
||||
RemoveButtonListeners();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
TrackBoardResize();
|
||||
}
|
||||
|
||||
public void ShowGame()
|
||||
{
|
||||
gameRoot.SetActive(true);
|
||||
@@ -128,9 +143,13 @@ namespace Minesweeper.Presentation.Views
|
||||
uiConfig = config;
|
||||
}
|
||||
|
||||
public void RebuildBoard(IReadOnlyList<BoardCellData> cells, int width, int height, ICellViewFactory cellViewFactory)
|
||||
public void RebuildBoard(IReadOnlyList<BoardCellData> cells, int width, int height, ICellViewFactory cellViewFactory, bool revealUnflaggedMines)
|
||||
{
|
||||
ClearBoard();
|
||||
currentBoardWidth = width;
|
||||
currentBoardHeight = height;
|
||||
currentCells = cells;
|
||||
currentRevealUnflaggedMines = revealUnflaggedMines;
|
||||
ConfigureGrid(width, height);
|
||||
|
||||
for (var i = 0; i < cells.Count; i++)
|
||||
@@ -138,17 +157,20 @@ namespace Minesweeper.Presentation.Views
|
||||
CreateCell(cells[i], cellViewFactory);
|
||||
}
|
||||
|
||||
RefreshBoard(cells);
|
||||
RefreshBoard(cells, revealUnflaggedMines);
|
||||
}
|
||||
|
||||
public void RefreshBoard(IReadOnlyList<BoardCellData> cells)
|
||||
public void RefreshBoard(IReadOnlyList<BoardCellData> cells, bool revealUnflaggedMines)
|
||||
{
|
||||
currentCells = cells;
|
||||
currentRevealUnflaggedMines = revealUnflaggedMines;
|
||||
|
||||
for (var i = 0; i < cells.Count; i++)
|
||||
{
|
||||
var cell = cells[i];
|
||||
if (cellsByCoordinate.TryGetValue(ToKey(cell.X, cell.Y), out var view))
|
||||
{
|
||||
view.Render(cell, uiConfig, currentPixelsPerUnitMultiplier);
|
||||
view.Render(cell, uiConfig, currentPixelsPerUnitMultiplier, revealUnflaggedMines);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,6 +256,45 @@ namespace Minesweeper.Presentation.Views
|
||||
{
|
||||
boardPanel.gameObject.SetActive(active);
|
||||
}
|
||||
|
||||
if (active)
|
||||
{
|
||||
ResetResizeTracking();
|
||||
}
|
||||
}
|
||||
|
||||
private void TrackBoardResize()
|
||||
{
|
||||
if (boardPanel == null || !boardPanel.gameObject.activeInHierarchy || currentCells == null || currentBoardWidth <= 0 || currentBoardHeight <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var layoutSize = GetLayoutSourceSize();
|
||||
if (layoutSize.x <= 0f || layoutSize.y <= 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasSizeChanged(layoutSize, lastObservedLayoutSize))
|
||||
{
|
||||
lastObservedLayoutSize = layoutSize;
|
||||
resizeStableAt = Time.unscaledTime + ResizeRefreshDelaySeconds;
|
||||
resizeRefreshPending = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (resizeRefreshPending && Time.unscaledTime >= resizeStableAt)
|
||||
{
|
||||
resizeRefreshPending = false;
|
||||
RefreshBoardLayout();
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshBoardLayout()
|
||||
{
|
||||
ConfigureGrid(currentBoardWidth, currentBoardHeight);
|
||||
RefreshBoard(currentCells, currentRevealUnflaggedMines);
|
||||
}
|
||||
|
||||
private void ConfigureGrid(int width, int height)
|
||||
@@ -245,10 +306,9 @@ namespace Minesweeper.Presentation.Views
|
||||
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
var parentRect = boardPanel.parent as RectTransform;
|
||||
var rect = parentRect != null ? parentRect.rect : boardPanel.rect;
|
||||
var panelWidth = rect.width > 0f ? rect.width : uiConfig.ReferenceCellSize * width;
|
||||
var panelHeight = rect.height > 0f ? rect.height : uiConfig.ReferenceCellSize * height;
|
||||
var layoutSize = GetLayoutSourceSize();
|
||||
var panelWidth = layoutSize.x > 0f ? layoutSize.x : uiConfig.ReferenceCellSize * width;
|
||||
var panelHeight = layoutSize.y > 0f ? layoutSize.y : uiConfig.ReferenceCellSize * height;
|
||||
var cellSize = CalculateCellSize(panelWidth, panelHeight, width, height);
|
||||
var padding = cellSize * uiConfig.BoardPaddingRatio;
|
||||
var spacing = cellSize * uiConfig.GridSpacingRatio;
|
||||
@@ -264,6 +324,28 @@ namespace Minesweeper.Presentation.Views
|
||||
gridLayoutGroup.spacing = new Vector2(spacing, spacing);
|
||||
gridLayoutGroup.cellSize = new Vector2(cellSize, cellSize);
|
||||
currentPixelsPerUnitMultiplier = uiConfig.ReferenceCellSize / cellSize;
|
||||
lastObservedLayoutSize = layoutSize;
|
||||
}
|
||||
|
||||
private Vector2 GetLayoutSourceSize()
|
||||
{
|
||||
var parentRect = boardPanel.parent as RectTransform;
|
||||
var rect = parentRect != null ? parentRect.rect : boardPanel.rect;
|
||||
return rect.size;
|
||||
}
|
||||
|
||||
private void ResetResizeTracking()
|
||||
{
|
||||
resizeRefreshPending = false;
|
||||
if (boardPanel != null)
|
||||
{
|
||||
lastObservedLayoutSize = GetLayoutSourceSize();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasSizeChanged(Vector2 current, Vector2 previous)
|
||||
{
|
||||
return Mathf.Abs(current.x - previous.x) > ResizeSizeEpsilon || Mathf.Abs(current.y - previous.y) > ResizeSizeEpsilon;
|
||||
}
|
||||
|
||||
private float CalculateCellSize(float panelWidth, float panelHeight, int width, int height)
|
||||
|
||||
Reference in New Issue
Block a user