using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace AibisDream { /// /// BlockPuzzle网格组件 /// 实现IBlockPuzzleGrid接口,管理整个游戏网格的状态和操作 /// public class BlockPuzzleGrid : MonoBehaviour, IBlockPuzzleGrid { [Header("编辑器预览设置")] [SerializeField] public int width = 10; [SerializeField] public int height = 10; [SerializeField] public float cellSize = 1f; [SerializeField] private bool showCellStates = true; private GridCellState[,] _grid; private GridCellState[,] _previewGrid; private bool _isInitialized = false; // IBlockPuzzleGrid 接口实现 public int Width { get; private set; } public int Height { get; private set; } public float CellSize { get; private set; } public Vector3 Origin => transform.position; public GridVisualizer GridVisualizer { get; private set; } public Dictionary ShapeDict { get; private set; } public event Action OnShapePlaced; /// /// 初始化编辑器预览 /// public void InitializeInEditor(int newWidth, int newHeight, float newCellSize) { width = newWidth; height = newHeight; cellSize = newCellSize; Width = width; Height = height; CellSize = cellSize; _grid = new GridCellState[width, height]; _isInitialized = true; ShapeDict = new Dictionary(); GridVisualizer = GetComponent(); Debug.Log($"BlockPuzzleGridComponent: 初始化编辑器预览 {Width}x{Height} {CellSize}"); } /// /// 初始化网格 /// public void Initialize(int width, int height, float cellSize) { if (width <= 0 || height <= 0) { Debug.LogError($"BlockPuzzleGridComponent: 无效的网格尺寸 {width}x{height}"); return; } if (cellSize <= 0) { Debug.LogError($"BlockPuzzleGridComponent: 无效的单元格大小 {cellSize}"); return; } Width = width; Height = height; CellSize = cellSize; _grid = new GridCellState[width, height]; _previewGrid = new GridCellState[width, height]; _isInitialized = true; ShapeDict = new Dictionary(); GridVisualizer = GetComponent(); GridVisualizer.Init(this); } public GridCellState GetCellState(int x, int y) { if (!_isInitialized) { Debug.LogWarning("BlockPuzzleGridComponent: 网格未初始化"); return GridCellState.Empty; } if (!IsValidPosition(x, y)) { Debug.LogWarning($"BlockPuzzleGridComponent: 尝试访问无效位置 ({x}, {y})"); return GridCellState.OutOfBounds; } return _grid[x, y]; } public void SetCellState(int x, int y, GridCellState state) { if (!_isInitialized) { Debug.LogWarning("BlockPuzzleGridComponent: 网格未初始化"); return; } if (!IsValidPosition(x, y)) { Debug.LogWarning($"BlockPuzzleGridComponent: 尝试设置无效位置 ({x}, {y})"); return; } _grid[x, y] = state; } public GridCellState GetPreviewCellState(int x, int y) { if (!_isInitialized) { Debug.LogWarning("BlockPuzzleGridComponent: 网格未初始化"); return GridCellState.Empty; } if (!IsValidPosition(x, y)) { Debug.LogWarning($"BlockPuzzleGridComponent: 尝试访问无效位置 ({x}, {y})"); return GridCellState.OutOfBounds; } return _previewGrid[x, y]; } public void SetPreviewCellState(int x, int y, GridCellState state) { if (!_isInitialized) { Debug.LogWarning("BlockPuzzleGridComponent: 网格未初始化"); return; } if (!IsValidPosition(x, y)) { Debug.LogWarning($"BlockPuzzleGridComponent: 尝试设置无效位置 ({x}, {y})"); return; } _previewGrid[x, y] = state; } public void ResetPreviewGrid() { Array.Clear(_previewGrid, 0, _previewGrid.Length); } public bool IsValidPosition(int x, int y) { return _isInitialized && x >= 0 && x < Width && y >= 0 && y < Height; } public bool IsCellEmpty(int x, int y) { return IsValidPosition(x, y) && GetCellState(x, y) == GridCellState.Empty; } public bool CanPlace(Vector2Int[] gridCells) { for (int i = 0; i < gridCells.Length; i++) { // 先验证是否在有效范围内 if (!IsValidPosition(gridCells[i].x, gridCells[i].y)) { return false; } // 再验证是否为空 else if (GetCellState(gridCells[i].x, gridCells[i].y) == GridCellState.Occupied) { return false; } } return true; } public bool WorldToGrid(Vector3 worldPos, out int gridX, out int gridY) { Vector3 localPos = worldPos - Origin; gridX = Mathf.FloorToInt(localPos.x / CellSize); gridY = Mathf.FloorToInt(localPos.y / CellSize); return true; } public Vector3 GridToWorld(int gridX, int gridY) { if (!_isInitialized) { return transform.position; } // 返回单元格中心的世界坐标 float worldX = Origin.x + (gridX + 0.5f) * CellSize; float worldY = Origin.y + (gridY + 0.5f) * CellSize; return new Vector3(worldX, worldY, Origin.z); } public Vector3[] GridVerticesToWorld(int x, int y) { if (!_isInitialized) { return new Vector3[4]; } // 先获取网格中心位置 Vector3 center = GridToWorld(x, y); // 然后获取网格四个顶点位置 Vector3[] vertices = new Vector3[4]; vertices[0] = center + new Vector3(-CellSize / 2, -CellSize / 2, 0); vertices[1] = center + new Vector3(CellSize / 2, -CellSize / 2, 0); vertices[2] = center + new Vector3(CellSize / 2, CellSize / 2, 0); vertices[3] = center + new Vector3(-CellSize / 2, CellSize / 2, 0); return vertices; } public void Clear() { _grid = new GridCellState[Width, Height]; _isInitialized = false; ShapeDict?.Clear(); } public int GetOccupiedCount() { if (!_isInitialized || _grid == null) return 0; int count = 0; for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { if (_grid[x, y] == GridCellState.Occupied) { count++; } } } return count; } public int GetTotalCellCount() { return Width * Height; } /// /// 检查网格是否已初始化 /// public bool IsInitialized() { return _isInitialized; } public List GetShapes() { return ShapeDict.Keys.ToList(); } private void OnDestroy() { OnShapePlaced = null; } } }