using System.Collections.Generic; using System.Linq; using Data; using Managers; using UnityEngine; using UnityEngine.Tilemaps; namespace Map { public class DoubleMap : MonoBehaviour { public List> mapData = new List>(); public Tilemap textureLevel; public Vector2Int dataOffset = Vector2Int.zero; // 数据起始点偏移变量 // 初始化地图数据大小 public void InitializeData(int width, int height, int defaultValue = 0) { mapData.Clear(); for (int x = 0; x < width; x++) { List column = new List(); for (int y = 0; y < height; y++) { column.Add(defaultValue); } mapData.Add(column); } } // 设置指定数据坐标的瓦片值并刷新相关瓦片 public void SetTile(int dataX, int dataY, int value) { // 检查坐标是否有效 if (dataX < 0 || dataY < 0 || dataX >= mapData.Count || dataY >= mapData[0].Count) { Debug.LogError($"SetTile: 坐标({dataX},{dataY})超出范围"); return; } // 更新数据 mapData[dataX][dataY] = value; // 刷新受影响的瓦片(当前点作为四个角影响的瓦片) RefreshTile(dataX, dataY); } // 获取指定数据坐标的瓦片值 public int GetTile(int dataX, int dataY) { if (dataX < 0 || dataY < 0 || dataX >= mapData.Count || dataY >= mapData[0].Count) { Debug.LogError($"GetTile: 坐标({dataX},{dataY})超出范围"); return -1; } return mapData[dataX][dataY]; } // 刷新指定数据点影响的瓦片 public void RefreshTile(int dataX, int dataY) { // 计算该数据点影响的四个瓦片位置(该点作为四个角) Vector2Int[] affectedTiles = new Vector2Int[] { new Vector2Int(dataX - 1, dataY - 1), // 作为右下角 new Vector2Int(dataX - 1, dataY), // 作为右上角 new Vector2Int(dataX, dataY - 1), // 作为左下角 new Vector2Int(dataX, dataY) // 作为左上角 }; foreach (var tilePos in affectedTiles) { UpdateTileAtTilemapPosition(tilePos.x, tilePos.y); } } // 刷新整个瓦片地图 public void RefreshAllTiles() { if (mapData.Count == 0 || mapData[0].Count == 0) return; // 计算瓦片地图的有效范围(考虑偏移) int startX = dataOffset.x; int startY = dataOffset.y; int endX = startX + mapData.Count - 1; int endY = startY + mapData[0].Count - 1; // 遍历所有瓦片位置 for (int x = startX; x <= endX; x++) { for (int y = startY; y <= endY; y++) { UpdateTileAtTilemapPosition(x, y); } } } // 更新指定瓦片位置的显示 private void UpdateTileAtTilemapPosition(int tileX, int tileY) { // 计算对应的数据坐标(考虑偏移) int dataX = tileX - dataOffset.x; int dataY = tileY - dataOffset.y; // 获取四个角的数据坐标 int topLeftX = dataX; int topLeftY = dataY; int topRightX = dataX + 1; int topRightY = dataY; int bottomLeftX = dataX; int bottomLeftY = dataY + 1; int bottomRightX = dataX + 1; int bottomRightY = dataY + 1; // 检查边界并获取值 int topLeft = GetDataValue(topLeftX, topLeftY); int topRight = GetDataValue(topRightX, topRightY); int bottomLeft = GetDataValue(bottomLeftX, bottomLeftY); int bottomRight = GetDataValue(bottomRightX, bottomRightY); // 获取对应的瓦片 TileBase tile = GetTileFromManager(topLeft, topRight, bottomLeft, bottomRight); // 设置到瓦片地图 Vector3Int position = new Vector3Int(tileX, tileY, 0); textureLevel.SetTile(position, tile); } // 安全获取数据值(处理边界) private int GetDataValue(int dataX, int dataY) { if (dataX < 0 || dataY < 0 || dataX >= mapData.Count || dataY >= mapData[0].Count) return 0; // 边界外返回默认值 return mapData[dataX][dataY]; } // 从TileManager获取对应瓦片 private TileBase GetTileFromManager(int topLeft, int topRight, int bottomLeft, int bottomRight) { TileManager manager = TileManager.Instance; if (manager == null) { Debug.LogError("TileManager实例未找到"); return null; } // 尝试获取组合键对应的瓦片 var key = (topLeft, topRight, bottomLeft, bottomRight); if (manager.tileToTileBaseMapping.TryGetValue(key, out TileBase tile)) { return tile; } // 备用方案:尝试获取默认瓦片 if (manager.tileBaseMapping.TryGetValue("Default", out TileBase defaultTile)) { return defaultTile; } Debug.LogError($"未找到对应瓦片: {key}"); return null; } } }