XML 使用说明 - 定义绘制顺序集

在游戏配置文件中,您可以使用 <DrawingOrderDef> 元素来定义一个实体在不同状态和朝向下的绘制节点集合。每个 <DrawingOrderDef> 元素都必须包含在顶层的 <Define> 元素之内,并遵循其通用的属性定义规则。

功能介绍

<DrawingOrderDef> 用于为游戏中的实体(如角色、单位)提供一套完整的、基于状态和朝向的视觉表现配置。它允许您为实体的“闲置”、“行走”、“近战攻击”、“远程攻击”和“死亡”等行为,以及“向上”、“向下”、“向左”、“向右”等朝向,指定不同的绘制结构 (DrawNodeDef)。这使得实体的行为和动画能够无缝地与视觉呈现相结合。

参数说明

所有的参数都必须通过嵌套元素的方式进行赋值。每个参数都期望一个 <DrawNodeDef> 引用或匿名定义,用于描述该特定状态和朝向下的绘制内容。

  • <defName> (必需,字符串)

    • 该绘制顺序集定义的唯一标识符。在整个游戏配置中,此名称必须是全局唯一的,除非您有意覆盖现有定义。
    • 作为匿名定义时,此字段可以省略。
  • <label> (可选,字符串)

    • 提供一个人类可读的标签,用于更好地理解该绘制顺序集定义的用途。
  • <description> (可选,字符串)

    • 提供更详细的文本描述,解释该绘制顺序集的具体内容或特殊用途。
  • 闲置状态(Idle States)

    • <idle_down>:实体向下(前方)闲置时的绘制节点。
    • <idle_up>:实体向上(后方)闲置时的绘制节点。
    • <idle_left>:实体向左闲置时的绘制节点。
    • <idle_right>:实体向右闲置时的绘制节点。
  • 行走状态(Walk States)

    • <walk_down>:实体向下行走时的绘制节点。
    • <walk_up>:实体向上行走时的绘制节点。
    • <walk_left>:实体向左行走时的绘制节点。
    • <walk_right>:实体向右行走时的绘制节点。
  • 近战攻击状态(Melee Attack States)

    • <meleeAttack_down>:实体向下近战攻击时的绘制节点。
    • <meleeAttack_up>:实体向上近战攻击时的绘制节点。
    • <meleeAttack_left>:实体向左近战攻击时的绘制节点。
    • <meleeAttack_right>:实体向右近战攻击时的绘制节点。
  • 远程攻击状态(Ranged Attack States)

    • <rangedAttack_down>:实体向下远程攻击时的绘制节点。
    • <rangedAttack_up>:实体向上远程攻击时的绘制节点。
    • <rangedAttack_left>:实体向左远程攻击时的绘制节点。
    • <rangedAttack_right>:实体向右远程攻击时的绘制节点。
  • 死亡状态(Death States)

    • <death_down>:实体向下死亡时的绘制节点。
    • <death_up>:实体向上死亡时的绘制节点。
    • <death_left>:实体向左死亡时的绘制节点。
    • <death_right>:实体向右死亡时的绘制节点。

缺项替换机制

为了减少重复定义,<DrawingOrderDef> 内置了缺项替换机制。当某个特定的状态和朝向没有被明确定义时,系统会尝试寻找最接近的替代项。替换规则遵循以下优先级:

  1. 同一类别内替换: 替换不会跨越不同的行为类别(例如,idle_down 不会替换 walk_down)。
  2. 左右优先互相替换: 如果 _left_right 方向缺失,系统会优先使用同类别下的另一个左右方向。例如,如果 idle_left 缺失,会尝试使用 idle_right
  3. 上下优先互相替换: 如果 _up_down 方向缺失,系统会优先使用同类别下的另一个上下方向。例如,如果 idle_up 缺失,会尝试使用 idle_down

引用方式

  • 当其他定义(例如角色定义)需要使用这套绘制动画时,始终使用该绘制顺序集定义的 defName

示例

示例 1:一个完整的角色绘制顺序集定义

<Define>
    <!-- 假设 Character_Maid_Walk_0 到 Character_Maid_Walk_38 等 ImageDef 已经存在 -->
    <DrawingOrderDef>
        <defName>MaidDrawingOrder</defName>
        <label>女仆角色绘制顺序</label>
        <description>包含所有方向和状态的动画。</description>

        <!-- 闲置状态 -->
        <idle_up>
            <textures>
                <li>Character_Maid_Walk_37</li> <!-- 引用 ImageDef -->
            </textures>
        </idle_up>
        <idle_down>
            <textures>
                <li>Character_Maid_Walk_1</li>
            </textures>
        </idle_down>
        <idle_left>
            <textures>
                <li>Character_Maid_Walk_13</li>
            </textures>
        </idle_left>
        <idle_right>
            <textures>
                <li>Character_Maid_Walk_25</li>
            </textures>
        </idle_right>

        <!-- 行走状态 (动画) -->
        <walk_up>
            <FPS>5.0</FPS>
            <textures>
                <li>Character_Maid_Walk_36</li>
                <li>Character_Maid_Walk_37</li>
                <li>Character_Maid_Walk_38</li>
                <li>Character_Maid_Walk_37</li>
            </textures>
        </walk_up>
        <walk_down>
            <FPS>5.0</FPS>
            <textures>
                <li>Character_Maid_Walk_0</li>
                <li>Character_Maid_Walk_1</li>
                <li>Character_Maid_Walk_2</li>
                <li>Character_Maid_Walk_1</li>
            </textures>
        </walk_down>
        <walk_left>
            <FPS>5.0</FPS>
            <textures>
                <li>Character_Maid_Walk_12</li>
                <li>Character_Maid_Walk_13</li>
                <li>Character_Maid_Walk_14</li>
                <li>Character_Maid_Walk_13</li>
            </textures>
        </walk_left>
        <walk_right>
            <FPS>5.0</FPS>
            <textures>
                <li>Character_Maid_Walk_24</li>
                <li>Character_Maid_Walk_25</li>
                <li>Character_Maid_Walk_26</li>
                <li>Character_Maid_Walk_25</li>
            </textures>
        </walk_right>

        <!-- 近战攻击状态 (动画帧,假设testPawn_2,6,10,14是单帧或动画的第一帧) -->
        <meleeAttack_up>
            <textures>
                <li>testPawn_2</li>
            </textures>
        </meleeAttack_up>
        <meleeAttack_down>
            <textures>
                <li>testPawn_6</li>
            </textures>
        </meleeAttack_down>
        <meleeAttack_left>
            <textures>
                <li>testPawn_10</li>
            </textures>
        </meleeAttack_left>
        <meleeAttack_right>
            <textures>
                <li>testPawn_14</li>
            </textures>
        </meleeAttack_right>

        <!-- 远程攻击状态 -->
        <rangedAttack_up>
            <textures>
                <li>testPawn_3</li>
            </textures>
        </rangedAttack_up>
        <rangedAttack_down>
            <textures>
                <li>testPawn_7</li>
            </textures>
        </rangedAttack_down>
        <rangedAttack_left>
            <textures>
                <li>testPawn_11</li>
            </textures>
        </rangedAttack_left>
        <rangedAttack_right>
            <textures>
                <li>testPawn_15</li>
            </textures>
        </rangedAttack_right>

        <!-- 死亡状态 -->
        <death_down>
            <textures>
                <li>Character_Maid_Death_0</li>
            </textures>
            <FPS>2.0</FPS>
        </death_down>
        <!-- 其他死亡方向未定义,将使用 death_down 进行替换 -->
    </DrawingOrderDef>
</Define>

在其他定义中引用此绘制顺序集:MaidDrawingOrder

示例 2:利用缺项替换机制的简化定义

<Define>
    <DrawingOrderDef>
        <defName>SimpleMonsterDrawingOrder</defName>
        <label>简易怪物绘制</label>

        <!-- 闲置只定义向下和向左,上下、左右会自动替换 -->
        <idle_down>
            <textures>
                <li>Monster_Idle_Front</li>
            </textures>
        </idle_down>
        <idle_left>
            <textures>
                <li>Monster_Idle_Side</li>
            </textures>
        </idle_left>
        <!-- idle_up 会使用 idle_down -->
        <!-- idle_right 会使用 idle_left -->

        <!-- 行走只定义向下,所有行走方向都将使用此动画 -->
        <walk_down>
            <FPS>3.0</FPS>
            <textures>
                <li>Monster_Walk_Front_0</li>
                <li>Monster_Walk_Front_1</li>
            </textures>
        </walk_down>
        <!-- walk_up, walk_left, walk_right 都会使用 walk_down -->

        <!-- 死亡只定义向下 -->
        <death_down>
            <textures>
                <li>Monster_Death_0</li>
            </textures>
        </death_down>
    </DrawingOrderDef>
</Define>

此示例展示了如何通过省略部分朝向的定义,利用系统的替换机制来简化配置,尤其适用于那些在不同朝向表现差别不大的实体。

注意事项

  • defName 唯一性: 强烈建议所有 <DrawingOrderDef>defName 都是全局唯一的,以避免在加载和引用时出现混淆或不确定的行为。如果存在重复的 defName,后加载的定义将会覆盖先加载的。
  • 匿名定义:<DrawingOrderDef> 作为其他定义的内部结构使用时,defName 可以省略,此时它将作为一个匿名的、局部可用的绘制顺序集定义。在这种情况下,该绘制顺序集无法通过名称在外部引用。
  • DrawNodeDef 的内容: 每个 <DrawingOrderDef> 的子元素(如 <idle_down>)内部都期望一个 <DrawNodeDef> 的定义。这个 <DrawNodeDef> 可以是一个完整的匿名定义(如示例),也可以是一个对已存在的 <DrawNodeDef> 的引用(如果该字段被设计为允许引用)。在当前示例中,它是一个匿名 <DrawNodeDef>
  • 合理利用替换机制: 在设计 DrawingOrderDef 时,可以充分利用替换机制来减少 XML 长度,但也要注意不要过度简化,以防视觉表现过于僵硬。对于方向性强的动作(如攻击),通常建议为所有方向提供独特的绘制。