Files
Gen_Hack-and-Slash-Roguelit…/Client/Assets/Scripts/Map/DoubleMap.cs

164 lines
5.6 KiB
C#
Raw Normal View History

using System.Collections.Generic;
using System.Linq;
using Data;
using Managers;
using UnityEngine;
using UnityEngine.Tilemaps;
namespace Map
{
public class DoubleMap : MonoBehaviour
{
public List<List<int>> mapData = new List<List<int>>();
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<int> column = new List<int>();
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;
}
}
}