mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-20 06:57:12 +08:00
(client) feat:实现技能树界面,实现地图生成器,实现维度指定,实现规则瓦片定义,实现逃跑逻辑,实现消息定义,实现武器动画,实现受击动画 fix: 修复单攻击子弹击中多个目标,修复人物属性计算错误 (#56)
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/56
This commit is contained in:
223
Client/Assets/Scripts/Map/PlantMapGenerator.cs
Normal file
223
Client/Assets/Scripts/Map/PlantMapGenerator.cs
Normal file
@@ -0,0 +1,223 @@
|
||||
using UnityEngine;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Threading.Tasks; // 引入 System.Threading.Tasks
|
||||
using Managers;
|
||||
using Utils;
|
||||
|
||||
namespace Map
|
||||
{
|
||||
/// <summary>
|
||||
/// 植物生成器配置类。
|
||||
/// </summary>
|
||||
public class PlantGeneratorConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 植物瓦片的定义名称。
|
||||
/// </summary>
|
||||
[JsonProperty("tileDefName", Required = Required.Always)]
|
||||
public string TileDefName { get; set; } = "DefaultPlantTile";
|
||||
/// <summary>
|
||||
/// 柏林噪声的缩放因子。
|
||||
/// </summary>
|
||||
[JsonProperty("scale")]
|
||||
public double Scale { get; set; } = 0.08;
|
||||
/// <summary>
|
||||
/// 柏林噪声阈值,高于此值才可能生成植物 (-1到1之间)。
|
||||
/// </summary>
|
||||
[JsonProperty("threshold")]
|
||||
public double Threshold { get; set; } = 0.3;
|
||||
/// <summary>
|
||||
/// 植物生成概率 (0-1之间),控制稀疏度。
|
||||
/// </summary>
|
||||
[JsonProperty("density")]
|
||||
public double Density { get; set; } = 0.6;
|
||||
/// <summary>
|
||||
/// 柏林噪声的X轴偏移。
|
||||
/// </summary>
|
||||
[JsonProperty("offsetX")]
|
||||
public double OffsetX { get; set; } = 0.0;
|
||||
/// <summary>
|
||||
/// 柏林噪声的Y轴偏移。
|
||||
/// </summary>
|
||||
[JsonProperty("offsetY")]
|
||||
public double OffsetY { get; set; } = 0.0;
|
||||
/// <summary>
|
||||
/// 植物必须生长在其上的基础瓦片名称 (可空)。
|
||||
/// </summary>
|
||||
[JsonProperty("requiredBaseTileDefName")]
|
||||
public string RequiredBaseTileDefName { get; set; } = null;
|
||||
/// <summary>
|
||||
/// 地图生成区域的宽度(单元格数量)。
|
||||
/// </summary>
|
||||
[JsonProperty("mapCellSizeX")]
|
||||
public int MapCellSizeX { get; set; } = 100;
|
||||
/// <summary>
|
||||
/// 地图生成区域的高度(单元格数量)。
|
||||
/// </summary>
|
||||
[JsonProperty("mapCellSizeY")]
|
||||
public int MapCellSizeY { get; set; } = 100;
|
||||
/// <summary>
|
||||
/// 是否避免植物瓦片互相重叠。
|
||||
/// </summary>
|
||||
[JsonProperty("preventOverlap")]
|
||||
public bool PreventOverlap { get; set; } = true;
|
||||
}
|
||||
|
||||
public class PlantMapGenerator : MapGeneratorWorkClassBase
|
||||
{
|
||||
private PlantGeneratorConfig _config;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化植物生成器,解析JSON配置字符串。
|
||||
/// </summary>
|
||||
/// <param name="value">包含植物生成参数的JSON字符串。</param>
|
||||
public override void Init(string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
_config = JsonConvert.DeserializeObject<PlantGeneratorConfig>(value);
|
||||
|
||||
if (_config == null)
|
||||
{
|
||||
Debug.LogError("植物地图生成器:配置反序列化为空。请检查JSON格式。将使用默认配置。");
|
||||
_config = new PlantGeneratorConfig();
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(_config.TileDefName))
|
||||
{
|
||||
Debug.LogWarning("植物地图生成器:瓦片定义名称为空。将使用默认值 'DefaultPlantTile'。");
|
||||
_config.TileDefName = "DefaultPlantTile";
|
||||
}
|
||||
if (_config.Scale <= 0)
|
||||
{
|
||||
Debug.LogWarning($"植物地图生成器:缩放值必须为正数。将设置为默认值 0.08。当前值: {_config.Scale}");
|
||||
_config.Scale = 0.08;
|
||||
}
|
||||
// Unity的Mathf.PerlinNoise输出0-1,如果PerlinNoise.Instance.Noise也如此,这里需要修改范围
|
||||
// 假设 PerlinNoise.Instance.Noise() 返回值在 -1 到 1 之间。
|
||||
if (_config.Threshold < -1.0 || _config.Threshold > 1.0)
|
||||
{
|
||||
Debug.LogWarning($"植物地图生成器:阈值 ({_config.Threshold}) 超出柏林噪声典型范围 (-1.0到1.0)。已钳制到 0.3。");
|
||||
_config.Threshold = 0.3;
|
||||
}
|
||||
if (_config.Density < 0 || _config.Density > 1)
|
||||
{
|
||||
Debug.LogWarning($"植物地图生成器:密度 ({_config.Density}) 必须在 0 到 1 之间。已钳制到 0.6。");
|
||||
_config.Density = Mathf.Clamp((float)_config.Density, 0f, 1f);
|
||||
}
|
||||
if (_config.MapCellSizeX <= 0)
|
||||
{
|
||||
Debug.LogWarning($"植物地图生成器:地图宽度 ({_config.MapCellSizeX}) 必须为正数。将设置为默认值 100。");
|
||||
_config.MapCellSizeX = 100;
|
||||
}
|
||||
if (_config.MapCellSizeY <= 0)
|
||||
{
|
||||
Debug.LogWarning($"植物地图生成器:地图高度 ({_config.MapCellSizeY}) 必须为正数。将设置为默认值 100。");
|
||||
_config.MapCellSizeY = 100;
|
||||
}
|
||||
}
|
||||
catch (JsonSerializationException ex)
|
||||
{
|
||||
Debug.LogError($"植物地图生成器:配置JSON反序列化错误:{ex.Message}。输入JSON: '{value}'");
|
||||
_config = new PlantGeneratorConfig();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"植物地图生成器:初始化过程中发生未预期错误:{ex.Message}。输入JSON: '{value}'");
|
||||
_config = new PlantGeneratorConfig();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据柏林噪声和配置参数在 `MapGenerator` 的 `plantTilemap` 上生成植物。
|
||||
/// 此方法现在是异步的,以避免阻塞主线程。
|
||||
/// </summary>
|
||||
/// <param name="map">MapGenerator实例,包含要操作的Tilemap。</param>
|
||||
public override async Task Process(MapGenerator map) // 标记为 async Task
|
||||
{
|
||||
if (_config == null)
|
||||
{
|
||||
Debug.LogError("植物地图生成器:在Init方法调用前或Init失败后调用Process。中止生成。");
|
||||
return; // async Task 方法直接 return; 意味着返回 Task.CompletedTask
|
||||
}
|
||||
|
||||
if (map == null || map.plantTilemap == null)
|
||||
{
|
||||
Debug.LogError("植物地图生成器:MapGenerator或植物瓦片地图为空。无法生成植物。中止。");
|
||||
return;
|
||||
}
|
||||
|
||||
var plantTile = TileManager.Instance.GetTile(_config.TileDefName);
|
||||
if (plantTile == null)
|
||||
{
|
||||
Debug.LogError($"植物地图生成器:无法获取名称为 '{_config.TileDefName}' 的瓦片。请确保瓦片管理器返回有效瓦片。中止生成。");
|
||||
return;
|
||||
}
|
||||
|
||||
// 缓存 requiredBaseTile 的引用,避免在循环中重复查询 TileManager
|
||||
UnityEngine.Tilemaps.TileBase requiredBaseTile = null;
|
||||
if (!string.IsNullOrEmpty(_config.RequiredBaseTileDefName))
|
||||
{
|
||||
if (map.baseTilemap == null)
|
||||
{
|
||||
Debug.LogWarning($"植物地图生成器:已配置基础瓦片名称 ('{_config.RequiredBaseTileDefName}') 但基础瓦片地图为空。将忽略基础地形要求。");
|
||||
}
|
||||
else
|
||||
{
|
||||
requiredBaseTile = TileManager.Instance.GetTile(_config.RequiredBaseTileDefName);
|
||||
if (requiredBaseTile == null)
|
||||
{
|
||||
Debug.LogWarning($"植物地图生成器:无法获取所需的基础瓦片 '{_config.RequiredBaseTileDefName}'。将忽略基础地形要求。");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var x = 0; x < _config.MapCellSizeX; x++)
|
||||
{
|
||||
for (var y = 0; y < _config.MapCellSizeY; y++)
|
||||
{
|
||||
var cellPosition = new Vector3Int(x, y, 0);
|
||||
|
||||
var sampleX = (x / (double)_config.MapCellSizeX) * _config.Scale + _config.OffsetX;
|
||||
var sampleY = (y / (double)_config.MapCellSizeY) * _config.Scale + _config.OffsetY;
|
||||
var noiseValue = PerlinNoise.Instance.Noise(sampleX, sampleY);
|
||||
|
||||
if (noiseValue < _config.Threshold)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查所需的基础瓦片
|
||||
if (requiredBaseTile != null)
|
||||
{
|
||||
var baseTileOnMap = map.baseTilemap.GetTile(cellPosition);
|
||||
if (baseTileOnMap == null || baseTileOnMap.name != requiredBaseTile.name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否重叠
|
||||
if (_config.PreventOverlap)
|
||||
{
|
||||
var existingPlant = map.plantTilemap.GetTile(cellPosition);
|
||||
if (existingPlant != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查密度
|
||||
if (UnityEngine.Random.value >= _config.Density)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
map.plantTilemap.SetTile(cellPosition, plantTile);
|
||||
}
|
||||
// 每处理完一列,就让出控制权给主线程
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user