(client) chore:修改了角色的身体结构的定义方式,现在图片资源统一使用ImageDef加载,使用了更节省资源的初始化方式;fix:修复了定义加载数组时只能初始化数组而不能初始化列表的问题

This commit is contained in:
m0_75251201
2025-08-22 20:43:55 +08:00
parent 3e099137a1
commit 8916440e7e
28 changed files with 1411 additions and 954 deletions

View File

@ -303,27 +303,40 @@ namespace Data
private static object ProcessArrayField(FieldInfo field, XElement element)
{
var elementType = field.FieldType.GetElementType();
// 获取集合元素的类型
Type elementType = field.FieldType.IsArray
? field.FieldType.GetElementType()
: field.FieldType.GetGenericArguments()[0];
if (elementType == null) return null;
var arrayElements = new List<object>();
// 遍历 XML 元素中的子元素
foreach (var liElement in element.Elements())
{
if (elementType.IsSubclassOf(typeof(Define)))
{
// 如果是 Define 类型或其子类
var nestedDefine = (Define)Activator.CreateInstance(elementType);
DefaultInitDefine(nestedDefine, liElement, elementType);
arrayElements.Add(nestedDefine);
}
else if (elementType.IsArray) // 嵌套数组处理
else if (elementType.IsArray || typeof(IList).IsAssignableFrom(elementType))
{
// 递归处理嵌套数组
// 嵌套数组处理(递归调用)
var pseudoField = new { FieldType = elementType };
var nestedArray = ProcessArrayField(
new { FieldType = elementType }.GetType().GetField("FieldType"),
pseudoField.GetType().GetField("FieldType"),
liElement
);
arrayElements.Add(nestedArray);
}
else if (elementType.IsEnum)
{
// 枚举类型处理
arrayElements.Add(Enum.Parse(elementType, liElement.Value));
}
else
{
// 基本类型处理
@ -331,14 +344,35 @@ namespace Data
}
}
// 构建结果数组
var resultArray = Array.CreateInstance(elementType, arrayElements.Count);
for (var i = 0; i < arrayElements.Count; i++)
// 根据目标字段的类型构建结果
if (field.FieldType.IsArray)
{
resultArray.SetValue(arrayElements[i], i);
// 如果目标字段是数组类型
var resultArray = Array.CreateInstance(elementType, arrayElements.Count);
for (var i = 0; i < arrayElements.Count; i++)
{
resultArray.SetValue(arrayElements[i], i);
}
return resultArray;
}
return resultArray;
else if (typeof(IList).IsAssignableFrom(field.FieldType))
{
// 如果目标字段是泛型集合类型(如 List<T>
var listType = typeof(List<>).MakeGenericType(elementType);
var resultList = (IList)Activator.CreateInstance(listType);
foreach (var item in arrayElements)
{
resultList.Add(item);
}
return resultList;
}
return null;
}
/// <summary>
/// 从 List<c>XDocument</c> 中查找指定根元素名称的文档。
/// </summary>

View File

@ -14,84 +14,221 @@ namespace Data
Up
}
public enum DrawNodeType
public enum EntityState
{
Image,
Animation
Idle,
Walking,
MeleeAttack,
RangedAttack,
}
public class DrawingOrderDef : Define
{
public DrawNodeDef drawingOrder_down;
public DrawNodeDef drawingOrder_up;
public DrawNodeDef drawingOrder_left;
public DrawNodeDef drawingOrder_right;
public string texturePath;
public float pixelsPerUnit = 16;
public DrawNodeDef GetDrawingOrder(Orientation orientation, out Orientation sourceOrientation)
public DrawNodeDef idle_down;
public DrawNodeDef idle_up;
public DrawNodeDef idle_left;
public DrawNodeDef idle_right;
public DrawNodeDef walk_down;
public DrawNodeDef walk_up;
public DrawNodeDef walk_left;
public DrawNodeDef walk_right;
public DrawNodeDef meleeAttack_down;
public DrawNodeDef meleeAttack_up;
public DrawNodeDef meleeAttack_left;
public DrawNodeDef meleeAttack_right;
public DrawNodeDef rangedAttack_down;
public DrawNodeDef rangedAttack_up;
public DrawNodeDef rangedAttack_left;
public DrawNodeDef rangedAttack_right;
public DrawNodeDef GetDrawNodeDef(EntityState state, Orientation orientation,
out Orientation? fallbackOrientation)
{
// 定义一个临时变量用于存储结果
DrawNodeDef result = null;
fallbackOrientation = null;
// 初始化 sourceOrientation 为默认值
sourceOrientation = Orientation.Down;
// 根据状态和方向获取对应的DrawNodeDef
var result = GetDrawNodeDefInternal(state, orientation);
// 根据传入的 Orientation 获取对应的 DrawingOrderDef
if (result != null)
{
return result;
}
// 如果找不到,按照规则查找替补
switch (orientation)
{
case Orientation.Down:
result = drawingOrder_down;
sourceOrientation = Orientation.Down;
break;
case Orientation.Up:
result = drawingOrder_up;
sourceOrientation = Orientation.Up;
// 上方向优先找下方向
result = GetDrawNodeDefInternal(state, Orientation.Down);
if (result != null)
{
fallbackOrientation = Orientation.Down;
return result;
}
// 其次找左右方向
result = GetDrawNodeDefInternal(state, Orientation.Left);
if (result != null)
{
fallbackOrientation = Orientation.Left;
return result;
}
result = GetDrawNodeDefInternal(state, Orientation.Right);
if (result != null)
{
fallbackOrientation = Orientation.Right;
return result;
}
break;
case Orientation.Down:
// 下方向优先找上方向
result = GetDrawNodeDefInternal(state, Orientation.Up);
if (result != null)
{
fallbackOrientation = Orientation.Up;
return result;
}
// 其次找左右方向
result = GetDrawNodeDefInternal(state, Orientation.Left);
if (result != null)
{
fallbackOrientation = Orientation.Left;
return result;
}
result = GetDrawNodeDefInternal(state, Orientation.Right);
if (result != null)
{
fallbackOrientation = Orientation.Right;
return result;
}
break;
case Orientation.Left:
result = drawingOrder_left;
sourceOrientation = Orientation.Left;
// 左方向优先找右方向
result = GetDrawNodeDefInternal(state, Orientation.Right);
if (result != null)
{
fallbackOrientation = Orientation.Right;
return result;
}
// 其次找上下方向
result = GetDrawNodeDefInternal(state, Orientation.Up);
if (result != null)
{
fallbackOrientation = Orientation.Up;
return result;
}
result = GetDrawNodeDefInternal(state, Orientation.Down);
if (result != null)
{
fallbackOrientation = Orientation.Down;
return result;
}
break;
case Orientation.Right:
result = drawingOrder_right;
sourceOrientation = Orientation.Right;
// 右方向优先找左方向
result = GetDrawNodeDefInternal(state, Orientation.Left);
if (result != null)
{
fallbackOrientation = Orientation.Left;
return result;
}
// 其次找上下方向
result = GetDrawNodeDefInternal(state, Orientation.Up);
if (result != null)
{
fallbackOrientation = Orientation.Up;
return result;
}
result = GetDrawNodeDefInternal(state, Orientation.Down);
if (result != null)
{
fallbackOrientation = Orientation.Down;
return result;
}
break;
default:
throw new ArgumentException("Invalid orientation value.");
throw new ArgumentOutOfRangeException(nameof(orientation), orientation, null);
}
// 如果当前方向的结果为空,则尝试用 drawingOrder_down 填充
if (result == null)
// 如果所有替补都找不到返回null
return null;
}
private DrawNodeDef GetDrawNodeDefInternal(EntityState state, Orientation orientation)
{
// 根据状态和方向获取对应的DrawNodeDef
switch (state)
{
result = drawingOrder_down;
sourceOrientation = Orientation.Down; // 更新 sourceOrientation
case EntityState.Idle:
switch (orientation)
{
case Orientation.Down: return idle_down;
case Orientation.Up: return idle_up;
case Orientation.Left: return idle_left;
case Orientation.Right: return idle_right;
}
break;
case EntityState.Walking:
switch (orientation)
{
case Orientation.Down: return walk_down;
case Orientation.Up: return walk_up;
case Orientation.Left: return walk_left;
case Orientation.Right: return walk_right;
}
break;
case EntityState.MeleeAttack:
switch (orientation)
{
case Orientation.Down: return meleeAttack_down;
case Orientation.Up: return meleeAttack_up;
case Orientation.Left: return meleeAttack_left;
case Orientation.Right: return meleeAttack_right;
}
break;
case EntityState.RangedAttack:
switch (orientation)
{
case Orientation.Down: return rangedAttack_down;
case Orientation.Up: return rangedAttack_up;
case Orientation.Left: return rangedAttack_left;
case Orientation.Right: return rangedAttack_right;
}
break;
}
// 如果 drawingOrder_down 仍然为空,则尝试用其他非空方向填充
if (result != null) return result;
if (drawingOrder_up != null)
{
result = drawingOrder_up;
sourceOrientation = Orientation.Up; // 更新 sourceOrientation
}
else if (drawingOrder_left != null)
{
result = drawingOrder_left;
sourceOrientation = Orientation.Left; // 更新 sourceOrientation
}
else if (drawingOrder_right != null)
{
result = drawingOrder_right;
sourceOrientation = Orientation.Right; // 更新 sourceOrientation
}
return result;
return null;
}
}
public class DrawNodeDef : Define
{
public List<DrawNodeDef> children = new();
public DrawNodeType drawNodeType = DrawNodeType.Image;
public List<string> animationTextures = new();
public List<DrawNodeDef> nodes = new();
public string nodeName;
public Vector2 position = new(0, 0);
public float FPS = 0.5f;
@ -101,19 +238,9 @@ namespace Data
base.Init(xmlDef);
nodeName = xmlDef.Attribute("name")?.Value??"noName";
drawNodeType = Enum.TryParse(xmlDef.Attribute("type")?.Value, true, out DrawNodeType typeResult)
? typeResult
: DrawNodeType.Image;
position = StringToVector(xmlDef.Attribute("position")?.Value ?? "(0 0)");
FPS = float.TryParse(xmlDef.Attribute("FPS")?.Value, out float result) ? result : 1.0f;
foreach (var childNode in xmlDef.Elements())
{
var child = new DrawNodeDef();
child.Init(childNode);
children.Add(child);
}
return true;
FPS = float.TryParse(xmlDef.Attribute("FPS")?.Value, out var result) ? result : 1.0f;
return false;
}
public Vector2 StringToVector(string vectorDef)
{
@ -132,35 +259,10 @@ namespace Data
// 返回 Vector2 对象
return new Vector2(x, y);
}
else
{
return Vector2.zero;
}
return Vector2.zero;
}
// 判断两个 DrawNodeDef 是否相等
public static bool AreEqual(DrawNodeDef a, DrawNodeDef b)
{
if (ReferenceEquals(a, b)) return true; // 如果是同一个对象,直接返回 true
if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) return false; // 如果其中一个为 null返回 false
// 比较基本属性
if (a.drawNodeType != b.drawNodeType ||
a.nodeName != b.nodeName ||
a.position != b.position ||
Math.Abs(a.FPS - b.FPS) > 0.001f) // 浮点数比较需要考虑精度
return false;
// 比较 children 的数量
if (a.children.Count != b.children.Count)
return false;
// 递归比较每个子节点
for (var i = 0; i < a.children.Count; i++)
{
if (!AreEqual(a.children[i], b.children[i]))
return false;
}
return true;
}
}
}