
SPT改档教程
          ————By Lee Catalpa Tien
		  
欢迎来到人物SPT教程！本教程将由简单到复杂地讲解SPT中一些概念及应用！您可以一边翻看原版SPT，一边对照教程来理解。
一些概念性的东西可以暂时不去理解，会用就行，用多了自然理解。

目录：（按Ctrl+G可传送到指定行）
符号及格式：39
一些基本概念：75
正式开始教程：243
     
	  一、动作篇: 243
       01、技能按键设定篇: 355|02、动作frame篇: 604|03、动作组篇: 778|04、制作新技能篇: 1438|05、按键顺序篇：1898|06、动作移植篇：2138

      二、基础参数篇: 2158
       01、简单基础参数篇: 2167|02、战争招兵相关参数篇: 2229|03、皮肤绑定篇: 2270

      三、frame入门篇: 2441
       01、结束帧篇: 2449|02、拆action篇: 2477|03、frame延时篇: 2769|04、复制帧篇: 2783|05、简单参数篇: 3071
      
      四、frame篇：3091
	   01、极限篇：3096|02、body身体篇：3114|03、防御判定篇：3148|04、attack攻击篇：3165|05、攻击数据篇：3201
	   
	   06、cre道具篇：3303|07、寻找关键帧篇：3344|08、贴图入门篇：3373

	  五、frame进阶篇：3389
	   01、贴图设置篇：3396|02、贴图显示篇：3494|03、贴图分离篇：3531|04、贴图移植篇：3730|05、fSpec篇：3832

      六、高级技巧篇：
       01、变身动作篇：3855|02、变身贴图篇：4349|03、变身妙用篇：4425







符号：

首先，我们要了解一下符号，这是非常重要的，如果符号错误，将会导致文件无法正常使用。
接下来是一些基本符号，为了帮助理解，我会设定一些虚构的参数，例如"值1"，这些和原版游戏中的SPT无关。

基本符号：

双引号（必须是英文的双引号） ""   设定一个参数时，必须用将参数名称包含在双引号内，例如： "值1"           

冒号（英文）   :    为一个参数赋值时，必须在值的前面加入一个冒号，赋的值可以是一个数字，也可以是一个被原参数包含的小参数，例如：  "值1": 1.0
需要特别注意的点：①纯数值必须加入小数点后一位，小数点后一位可以为0，但不能没有；②冒号和值之间必须用空格隔开，例如："值1": 1.0 √  ; "值1":1.0 × ; "值1": 1 ×

逗号（英文）   ,    
若有多个同等级的参数并排，
则需要用逗号隔开，而一个大括号内最后一个参数不需要也不允许用逗号。
例如：

"值1": 1.0,
"值2": 3.0,
"值3": 10.0,
"值4": 12.0   <--------注意此处没有逗号，因为下方没有新的同级参数。

大括号      {   }    
当赋的值不是单纯的数字而是多个元素或是新的参数时，
将会用到大括号，
例如：

"值9": {          <-----------冒号和大括号之间同样要用空格隔开。
       "HFW_ArrayLenXXX": 3,        
         "0": 3.0,
		 "1": 6.0,
		 "2": 5.0                
}                           <------------前面用了上大括号，这里必须用下大括号收起，否则文件会出错。



基本概念：

多级参数：一个参数下往往会有多个元素，
这些元素可能是单纯的数值，
也可能是一个新的参数，例如：

 "值9": {
       "HFW_ArrayLenXXX": 3,         
         "0": 3.0,             <------------注意前面的"0"是一个元素而不是数值，如果是数值则要表示成"0.0"，后面的 3.0 则是一个具体数值
		 "1": 6.0,
		 "2": 5.0                <------------可以看到，值的大小并不一定要按顺序，顺序由其他因素决定，之后会详细讲解。
 }                         



<----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->




"值9": {
       "HFW_ArrayLenXXX": 3,        
         "0": 3.0,
		 "1": 6.0,
		 "2": 5.0                
},          <------------包含多个元素的参数之间同样要用逗号隔开
"值10": {
       "HFW_ArrayLenXXX": 3,        
         "0": 3.0,
		 "1": 8.0,
		 "2": 9.0
}

<------------需要注意的是，这里虽然有三个元素，但这三个元素的本质是完全一样的，都是关于"值10"的元素

这里我引入一个“同类元素”和“异类元素”的概念，帮助理解（只是我自己起的名称，不是专业术语）

同类元素：本质完全相同的元素，例如action中，0到100是不同的动作，但他们的性质完全相同，都是动作（action），可以理解成一共有N个动作，他们的参数被分成了N份。

异类元素：本质不同的多个元素，例如在action的"1"（站立动作）中，"nextAti"和"a_keyTgr"这两个是不同的元素，他们所起的作用不同，赋值的方式也不同。

一般来说，一个大参数下要么只包含异类元素，
要么只包含同类元素，要区分他们很简单，
我们可以看元素名称，如果是"0","1","2"这样的序号，那么是同类元素；如果是"nextAti"、"a_keyTgr"这样的具体名称，就是异类元素。

例如：

"action": {
"HFW_ArrayLenXXX": 4,         <------------当一个参数下的元素为同类元素时，须加入"HFW_ArrayLenXXX": n,（n表示有多少个元素，此处有0、1、2三个元素，则n=3, 此为元素的数量而非数值，所以不用加引号） 
"0": {
                "HFW_classNameXXX": "Data.Action",
            ......
            ......
			},
"1": {        <------------可以看到，这里的元素没有具体名称，只有序号，因为这些元素虽然代表不同的动作，但本质完全一样，都是动作（action），所以他们是同类元素
                "HFW_classNameXXX": "Data.Action",
            ......
            ......
			},
"2": {
                "HFW_classNameXXX": "Data.Action",
            ......
            ......
			},
"3": {
                "HFW_classNameXXX": "Data.Action",
            ......
            ......
			}			

<----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->


元素可以是一个数值，也可以是一个新的参数
例如：



"action": {
       "HFW_ArrayLenXXX": 220,     
               "0": {             <-------------注意此时"15"下的元素不再是数值，而是一个新的参数
                "HFW_classNameXXX": "Data.Action",        <-------------此时"0"内的元素代表很多种不同的意义（本质不同），所以是异类元素，
                "selfLoop": true,                                       因此不用"HFW_ArrayLenXXX"而是用"HFW_classNameXXX": "·······"来表示，
                "nextAi": -1.0,                                         "······"根据此元素的性质来决定，例如这里的"0"属于"action",则用"Data.Action"表示。
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "AVATAR",
                "a_keyTgr": {           <-------------内部的元素又可以再分为多个元素。
                    "HFW_ArrayLenXXX": 1,     <-------------这里可以看出"a_keyTgr"下的元素是同类元素，因为这些元素属于"a_keyTgr"，所以比"a_keyTgr"和与"a_keyTgr"同级的元素要低一级。
                    "0": {         <-------------这里的"0"是属于"a_keyTgr"的，要和"action"下方的"0"区分开来。
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gua"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },
			"1":·······,
			"2":·······,
			"3":·······,
			············
			············
			"219":·······


翻看SPT的时候，我们常常会看到"null"、"true"等词汇，这里大概地罗列一下这些词汇的概念。

true: 真实，若一个参数只有“是”或“否”两种可能时，就会用 true 和 false 来决定是与否，例如："isSoldier",这个是控制角色是否为士兵的值，若"isSoldier": true,则此角色为士兵。
false: 否定，与true作用相反，例如："isSoldier": false,则此角色不是士兵。
null: 不存在，若想让某个参数不发挥作用，可以使用null，例如："a_keyTgr": null 。
null 和 false 必须区分开，前者用于有具体设定的参数，后者用于“是”与“否”的参数。
若使用正确， true 、 false 、 null 字体会变成蓝色

x：横轴，也就是左右位置，正数为右，负数为左
z：纵轴，也就是上下位置，正数为下，负数为上
y：高度，正数为低，负数为高
hp：生命值
mp：能量值
g（guard）：防御
u（up）：向上
j（jump）：跳跃
a（attack）：攻击
l（left）：向左
r（right）：向右
d（down）：向下

由于SPT里常常会用到和他们有关的参数，所以提前说一下。

数值的意义：
赋值的时候，我们会用到数字，这些数字通常有两种意义

①具体数量、大小，例如："x": 230.0 代表横轴位置在人物右边230个单位长度
若设为负数，则是在人物左边

②对应另一个参数里的某个序号，例如："frameIndex": 53.0 代表这个动作所对应的起始帧是53号帧
若设为负数，则这个参数不会发挥作用，和 null 的性质相似，但用法不同

通常，带有"x","y","z"的参数后面的值都是具体大小，而"int1","int2","int3"以及带有"index"的都是序号
大小可以较为自由地改动，但序号不能乱改，否则会出错

正式教程：

一、动作（action）。

了解了基本的格式与概念之后，我们就可以开始尝试改档了，我们可以先从动作（action）这种比较简单的入手。
接下来，我会列出action中各参数的作用，然后示范性地做出修改。

Ctrl+F可以对文档进行搜索，您可以借此快速找到action的位置。

（PS：agi(actionGroupIndex)、ati(actionIndex)、ai(action)是比较复杂的东西，可以先选择性地忽略，后面会详细讲解。）
"action": {
            "HFW_ArrayLenXXX"（HFW_ArrayLenXXX后的数字代表有多少个值，例如这里是220，代表有220个动作）: 220,
			"0": ······,
            "1"（值的序号，此处为动作的序号，在agi-->ati-->ai里对应）: {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop"（动作循环，改为true则会在动作所有帧结束后重新从第一帧开始，例如drew的霸王冲锋，需配合mpBurn和nextAgi、nextAti、nextAi使用，否则不会自动停下）: false,
                "nextAi"（动作结束后，进入这个ai所对应的动作，仅限技能动作和部分攻击使用）: -1.0,
                "allowTurnFace"（是否允许转身，改成true会像Shawn的五连矢那样自由转身）: false,
                "nextAti"（动作结束后，进入这个ati下的ai对应的动作，仅限技能动作和部分攻击使用）: -1.0,
                "frame"（动作帧的参数，在action中作用未知，原版未使用，可以自行探索）: null,
                "special"（技能的特性，稍后讲解）: -1.0,
                "landAti"（落地后，进入这个ati下的ai对应的动作，适合用于落龙斩等空中落地技能，仅限技能动作和部分攻击使用）: -1.0,
                "landAi"（落地后，进入这个ai对应的动作，仅限技能动作和部分攻击使用）: -1.0,
                "nextAgi"（动作结束后，进入这个agi下的ati下的ai对应的动作，仅限技能动作和部分攻击使用）: -1.0,
                "name"（动作名称，也是故事中的ac代码，应尽量避免重复）: "STAND",    <-------------action中的动作名称都是大写，这是为了区分，可以写成小写。
                "a_keyTgr"（此动作下的技能按键）: {    <-------------keyTgr的T是大写，因为这是一个词组，第二个单词开始，每个单词的第一个字母用大写，如"allowTurnFace"，这个不能改大小写，否则会失效，与名称要区分开。
                    "HFW_ArrayLenXXX": 2 （2，代表站立动作下可以使用两个技能）,
                    "0"（序号，必须按顺序排列，几乎所有序号都是从"0"开始，而不是从"1"开始）: {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai"（动作序号，与action下的序号不同，是在actionGroup里设置的序号，之后会详细讲解。）: 0.0,   
                        "atf"（是否允许向后发技能，例如龙介跑攻时可以立刻转身飞龙，而泰来跑攻时只能向前方接烈光炮）: false,
                        "hp"（技能消耗的hp，人物hp低于这个值时无法放出技能）: 0.0,
                        "ati"（动作所属的actionIndex）: 3.0,
                        "pollhp"（com在低于这个血量百分比时才会释放这个技能，例如泰来的治疗为45，对玩家无效，0为无限制）: 0.0,
                        "kl"（按键数，与实际的按键数必须一致，否则无法按出技能，按键数太多同样会导致无法放出技能）: 3.0,
                        "k"（人物向右时的技能按键）: "gua",
                        "mp"（技能消耗mp）: 275.0,
                        "agi"（动作所属的actionGroupIndex）: 0.0,
                        "rkt"（是否会被"allowKeyTrigger"所限制，改为false则该动作下随时可以使用技能，true则需要在frame里面设置过才能正常使用，会在frame篇里详细讲解）: false,
                        "kr"（人物向左时的技能按键，可以与向右时的一样）: "gua"
					 },
					 （新参数也需要被大括号括起来，下面我把第二个技能的换行删掉，方便理解）
                    "1": {             "HFW_classNameXXX": "Data.A_KeyTgr","ai": 3.0,"atf": true,"hp": 0.0,"ati": 3.0,"pollhp": 0.0,"kl": 3.0,"k": "gra","mp": 90.0,"agi": 0.0,"rkt": false,"kr": "gla"}
					注意此处还有一个大括号，对应的是action下两行那个"0"后面的大括号，上下括号的数量必须一致。
					----------------------> },  <----------------------
                "landAgi"（落地后，进入这个agi下的ati下的ai对应的动作，仅限技能动作和部分攻击使用）: -1.0,
                "frameIndex"（frame代表帧，一个人物所有动作有几百个帧，而这个参数代表这个动作起始的那一帧）: 1.0,
                "mpBurn"（动作进行时，每 0.1 秒消耗的mp量,若为技能，则消耗完mp并完成本轮动作后进入nextAi对应动作，若非技能或没有设置nextAi则会保持原动作）: 20.0,
                "index"（序号，和action下的序号对应，在action中序号与index不一致影响不大）: 1.0,
				"nextActionName"（动作结束后接的动作的名称，只是作为标记，可以不写）: null,
				"type"（种类，用于设定人物性质，action中不会用到，因此全为-1.0 ）: -1.0,
				"aiz2"（com的Z轴下方判定范围，com在aiz1到aiz2的Z轴范围内检测到敌人时会使用这个技能）: 200.0,
				"aiz1"（com的Z轴上方判定范围，com在aiz1到aiz2的Z轴范围内检测到敌人时会使用这个技能）: -200.0,
                "aix2"（com的X轴右边判定右边界，com在aix1到aix2的X轴范围内检测到敌人时会使用这个技能）: 500.0,
				"aix1"（com的X轴右边判定左边界，com在aix1到aix2的X轴范围内检测到敌人时会使用这个技能）: 100.0,
                "aix2b"（com的X轴左边判定右边界，com在aix1b到aix2b的X轴范围内检测到敌人时会使用这个技能）: -100.0,
				"aix1b"（com的X轴左边判定左边界，com在aix1b到aix2b的X轴范围内检测到敌人时会使用这个技能）: -500.0,
                "landActionName"（落地后接的动作的名称，只是作为标记，可以不写）: null
				}		
            },
			
			对于aix2等参数，可能不太容易理解，所以我画了一张草图来帮助理解。			
———————————————————————————————————————————————————————————————————————————————————————————————————————
		  aix1b           aix2b                                 aix1          aix2
            |               |              人物位置               |             |
	  aiz1  |<------------->|                 ||                  |<----------->| aiz1
			|<------------->|                 ||                  |<----------->|
		    |<------------->|                 ||                  |<----------->|
			|<------------->|                ||||                 |<----------->|
			|<------------->|               ||  ||                |<----------->|
			|<------------->|              ||    ||               |<----------->|
			|<------------->|             ||      ||              |<----------->|
			|<------------->|            ||        ||             |<----------->|
	  aiz2  |<------------->|           ||          ||            |<----------->| aiz2
			|               |                                     |             |
			|               |                                     |             |
		这里的两个|代表地图左右范围，虚线内则是com判定范围，当虚线位置有敌人时，com会放出这个技能。
——————————————————————————————————————————————————————————————————————————————————————————————————————


可以看到，带有2的数值总是比1的大，如aix2的数值大于aix1，那么，如果像下图那样，把它们反过来，让aix1更大会怎样？可以先思考一下。


———————————————————————————————————————————————————————————————————————————————————————————————————————
		  aix2b           aix1b                                 aix2          aix1
            |               |              人物位置               |             |
	  aiz2  |<------------->|                 ||                  |<----------->|aiz2
			|<------------->|                 ||                  |<----------->|
		    |<------------->|                 ||                  |<----------->|
			|<------------->|                ||||                 |<----------->|
			|<------------->|               ||  ||                |<----------->|
			|<------------->|              ||    ||               |<----------->|
			|<------------->|             ||      ||              |<----------->|
			|<------------->|            ||        ||             |<----------->|
	  aiz1  |<------------->|           ||          ||            |<----------->|aiz1
			|               |                                     |             |
			|               |                                     |             |
——————————————————————————————————————————————————————————————————————————————————————————————————————

如果您有仔细观察泰来的治疗术技能的action，就会发现，治疗术所设定的ai范围就像图二那样，因为要治疗的是队友，而不是敌人。
所以，如果将1和2的大小反过来，com就会在范围内检测到队友（包括自己）时释放技能，而不是检测敌人。


知道action中各参数的作用后，我们就可以开始改档了，请打开龙介的SPT（442），然后跟着我一起操作。


special的种类及作用：

10： 跑步时会控制烟雾的生成（例如翔龙），防止一直生成烟雾。同时，若此action有设置nextAi，则按反方向键会直接跳到nextAi对应的动作。

20： 技能进行的过程中，可施加速度，例如drew的回旋淬击拳和戈登的石破。施加的速度由jumpSpeedX和speedXRate共同决定。

30： 反弹，例如滔滔肉弹，无论攻击造成敌人位移的方向如何，自身都是反弹至后上方。

01、技能按键设定篇。

先用Ctrl+F搜索"STAND"（区分大小写）来快速找到站立动作的位置，我们首先尝试修改升龙斩的按键以及mp消耗量。（如果您已经掌握了修改技能按键和mp消耗量的技巧，可以跳过这一部分，接下来其他篇章也一样）
PS：改的时候，操作和修改后的数值请严格按照教程来，不要随意修改，否则可能出错。

①修改升龙斩按键"gua"为"a"。

"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {       <------------首先，找到这个控制技能按键的参数
                    "HFW_ArrayLenXXX": 2,
                    "0": {        <------------通过大括号可以确定升龙斩技能按键设定的范围，只要点击这个大括号右边的空格，就能在左侧红线处观察到参数范围。
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,（改为 1.0 ） <------------按键数量由三个变为一个，所以"kl"（按键数）也得从 3.0 变为 1.0 ，我们要改的是升龙斩的"kl"，所以这个"kl"要和升龙斩的"k"在一个大括号内。
                        "k": "gua",（改为"a"）    <------------通过按键来辨别技能是最快捷的方式，我们可以看到这里的按键是g（防）u（上）a（攻），自然就是升龙斩，我们尝试把它改为"a" 。
                        "mp": 275.0,   
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gua"（改为"a"） <------------向左的按键同样要改为"a"，注意改的时候不要增加或者减少任何符号。
                    }, 
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }
改完后，就会像下列参数那样，然后保存文件，拖入龙介SPT的压缩包，通过HFW替换掉原文件，导出exe，
打开游戏后在龙介站立的动作下按攻击键，就会直接放出升龙斩！
"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",   <------------注意这里已经改成了"a"。
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "a"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }
			
②修改升龙斩的mp消耗量。

我们先保持刚才改的按键不要改回去（后面会解释原因），
然后再次找到升龙斩的按键位置。
"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",  
                        "mp": 275.0,（改为 100.0 ） <------------因为按键已经改成了"a",所以通过按键来找升龙斩可能变得困难，但我们也可以通过mp消耗量来寻找升龙斩，因为同一个角色的技能的mp消耗量很少会相同，找到后改为 100.0 。
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "a"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }		
<-----------------以下是改完后的参数------------------>
"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",  
                        "mp": 100.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "a"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }
再次导入后进入游戏，按攻击键放出升龙斩，会发现mp消耗量大大减少了。

由于人物在多个动作下都能释放升龙斩技能，所以改按键和mp消耗量的时候往往要在多个位置改，这也意味着不同的动作下，同一个技能的按键和mp消耗量可以不同，例如：龙介站立动作下需要按gra才能放出飞龙斩，但飞龙斩动作下只需要按a就能放出新的飞龙斩。
而像gra（防右攻）这样的按键，会先让角色进入防御动作，然后进入防御行走，然后按攻击放出技能。或者先进入防御动作，恢复站立后行走，再按攻击放出技能，因此，我们需要在站立、行走、防御、防御行走的动作下都加入同样的按键设定，否则会经常按不出技能。
之前让玩家保留升龙斩的"a"按键也是这个原因，因为单独的"a"不会进入行走或者防御状态，能保证是在站立动作下放出升龙斩。

02、动作frame篇

frame，就是帧，每帧可以有不同的判定，比如攻击，防御，放出道具等，人物的贴图、特效等也是在帧里面设置的。
一个动作一般包含5到30帧，有的帧会有停顿效果（duration），例如三巨头的自爆。
有的帧会放出道具（例如龙介的飞龙斩），而放出的道具同样可以放出道具（例如赤木的火球被消灭后放出大爆炸）
人物的身体碰撞范围、攻击范围、技能位移等也都是在frame里面设定的。
frame非常地复杂，因此这里只简单讲解一下动作（action）里设置frame的技巧，之后再详细讲解frame本身。

①寻找起始、结束帧

我们在action里，可以通过"frameIndex"来设置动作对应帧的序号，这个帧是动作的起始帧，action里没有结束帧的设定，因为这是在frame里设置的，
举个例子，龙介飞龙斩1的帧是316到330，那么330就是结束帧，在316到330以内，无论你的起始帧设到哪儿，结束帧都不会变，如果你把起始帧设为330，那么龙介经过一帧后便会结束动作，而如果设为331，那么错过了330这个结束帧，便会从330开始做动作直到下一个结束帧。
要找到结束帧，需要在frame里面搜索"last"，若"last"为 true ，那么这一帧就是结束帧，如果"last"是 false ，那么这一帧不是结束帧，需要继续往下找。
每次都在frame里找结束帧是一件麻烦的事，如果您对动作的名称和帧的数量熟悉的话，可以直接在动作里面推测出结束帧，但前提是需要对frame有一定的认知。
假如我们要找飞龙斩1（ball）的所有帧，可以先找到飞龙斩1（ball）和它的下一个动作，也就是飞龙斩2（ball2）。（注意这里的“下一个动作”指action里下方，也就是下一号的动作，而不是飞龙斩接的动作，只不过他们的序号刚好连起来了）
"94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
                "a_keyTgr": null, <-----------------为了简洁我把技能按键删了，方便浏览。
                "landAgi": -1.0,
                "frameIndex": 316.0,<-----------------我们发现飞龙斩1的起始帧是316，记下它，然后翻阅下一个动作。
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            },
            "95": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL2",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 331.0,<-----------------可以看到飞龙斩1下一个动作的起始帧是331，那么他的前一帧330很可能就是上一个动作的最后一帧。
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 95.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }
			由此，我们便可以推出飞龙斩1的帧为316到330，而最后的330自然就是结束帧。
			如果把第二个动作的起始帧改为333，不使用331和332两帧，也不会影响上一个动作的结束帧，仍然是330。
			但这样一来，我们要找结束帧就会变得困难，不过，值得放心的是，原版的遗弃帧几乎都放在了所有帧的最后面，不会影响我们推测结束帧。
			但还有一种特殊情况，就是有时两个动作会重复用到一些帧，只是起始位置不同，例如龙介的ball2to1是315到330，而ball是316到330，这么设定的目的是让ball的起手比ball2to1短。
			"93": {
			 "name": "BALL2TO1",
                "a_keyTgr": null,
                "landAgi": -1.0,   <-----------------为了简洁，删去了大部分无关参数。（实际改档的时候不能删）
                "frameIndex": 315.0
				},
			"94": {
				"name": "BALL",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 316.0
				},
			"95": {
                "name": "BALL2",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 331.0,
                }
			此时我们要找ball2to1的结束帧，自然不能在ball里面找,而是再往下一个动作，在ball2里面找，
			一般来说，两个动作的起始帧差距在5以内，就要怀疑是同一组帧了，还有一种方法是看名称，
			像ball2to1，是飞龙斩2转到飞龙斩1，本质还是飞龙斩1，所以和飞龙斩1（ball）是相同的动作，只是起手不同。
			所以，要快捷地推出结束帧，我们需要对动作名称和动作总帧数有一定的了解。
			实在无法判断的时候，我们就只能到frame里面找了，结束帧的"last"是 true ，而非结束帧的"last"是 false ，我们只要从起始帧开始向下找"last",直到出现 true 为止，但一般是不需要用到这种方法的，因为原版动作所对应的帧几乎全部都是按从小到大的顺序排列的。
			
		②修改起始帧的数值。
			
	    我们先尝试将站立（stand）动作的起始帧改为飞龙斩1（ball）的起始帧。
		
		找到站立的"frameIndex"，再找到飞龙斩的"frameIndex"
			
			"1": {
                "HFW_classNameXXX": "Data.Action",  
                "name": "STAND",   <-----------------这里同样删去了无关参数，方便浏览（实际改档的时候不能删）
                "frameIndex": 1.0
            },
            "2": {
                "HFW_classNameXXX": "Data.Action",
                "name": "WALK",
                "frameIndex": 5.0
            },
            "3": {
                "HFW_classNameXXX": "Data.Action",
                "name": "RUN",
                "frameIndex": 20.0
            },
			···········
			···········
			"94": {
				"name": "BALL",
                "frameIndex": 316.0
			}
			
			我们看到站立的"frameIndex"为 1.0,飞龙斩为 316.0
			把站立动作的"frameIndex"改为316
			"1": {
                "HFW_classNameXXX": "Data.Action",  
                "name": "STAND", 
                "frameIndex": 316.0
            },
            "2": {
                "HFW_classNameXXX": "Data.Action",
                "name": "WALK",
                "frameIndex": 5.0
            },
            "3": {
                "HFW_classNameXXX": "Data.Action",
                "name": "RUN",
                "frameIndex": 1.0
            },
			···········
			···········
			"94": {
				"name": "BALL",
                "frameIndex": 316.0
			}
			导入后进入游戏，会发现龙介站立时在不断地发出飞龙斩。
			
			③加快飞龙斩出的速度（略过一些起手帧）
			"94": {
				"name": "BALL",
                "frameIndex": 316.0
				},
			"95": {
                "name": "BALL2",
                "frameIndex": 331.0,
                }
			我们看到飞龙斩起始帧是316，把它改为321
			"94": {
				"name": "BALL",
                "frameIndex": 321.0
				},
			"95": {
                "name": "BALL2",
                "frameIndex": 331.0,
                }
			导入后进入游戏，使用飞龙斩时会发现起手变快，因为前面几帧被跳过了。
			但这种方法有一定的缺陷，就是会影响动作流畅度，而在frame里可以在不影响流畅度的情况下加快起手速度，之后会详细讲解。
			
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————			
			
			
03、动作组篇		
 
action中较为复杂的frameIndex和按键设定都已介绍完，而其余参数（除了与actionGroup相关的）比较简单，所以不再详细解释。
接下来，我们开始学习动作组（actionGroup），相较于之前的内容，接下来的内容可能比较复杂，比较难理解，但依然是基础部分，用心去理解的话是肯定可以理解的。
			
首先，我们要明白一点，action中的动作，如果零零散散，不加以修饰，是没有任何作用的，而actionGroup所起的作用就是把他们整合起来，并加以修饰。
我们可以把action比喻成家具，actionGroup比喻成房子，如果没有房子，那么无论家具多么漂亮，多么丰富，都没什么作用。
而一个房子（actionGroup）可以把家具（action）整齐地排放好，让它们各自发挥自己的功能。
同时，家具（action）的位置也是非常重要的，如果你把被子放在厨房里，抽油烟机放在床上，它们就无法正常地发挥自己的作用，甚至出大问题。
action也是一样，在actionGroup中，除了技能以外，每一个数值所对应的功能是固定的，不会因action的改变而改变。
大概知道了actionGroup的意义之后，我们将正式开始讲解actionGroup，接下来我会把龙介普通状态的actionGroup列出来，请先大概浏览一遍。
"actionGroup": {
            "HFW_ArrayLenXXX": 10,
            "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "action": {           <-----------------这个action在原版是没什么用的，可以看到下面的数值都是 null ，有用的在后面。
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": null,    <-----------------我本想全部列出来，但数值实在太多了，所以中间的就折叠起来了。
                        "1": null,
                        ······
						······
                        "30": null
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": null,
                       ······
                        "57": null
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": null,
                        ······
                        "18": null
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": null,
                        ······
                        "10": null
                    }
                },
                "ite_dura": 0.0,
                "ite_duraD": 0.0,
                "ite_obstacle": false,
                "ite_atk1": -1.0,
                "ite_sfx1": 0.0,
                "ite_atkName1": "",
                "ite_lifeTime": 0.0,
                "ite_reboundable": false,
                "name": "normal",   <-----------------这是动作组名称，原版普通人物一共有五个动作组，后面再详细讲。
                "ite_landBreak": true,
                "ite_screen": false,
                "ite_atk2": -1.0,
                "index": 0.0,
                "ite_standable": false,
                "ite_weight": 1.0,
                "type": 0.0,
                "ite_hitable": true,
                "actionIndex": {     <-----------------这个是最重要的参数，缩写为ati，action中看到的nextAti指的就是这儿，除了这个参数其他基本没什么用。
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": 1.0,
                        ······
                        "30": 109.0
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                       ······
                        "57": 108.0
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        ······
                        "18": -1.0
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                       ······
                        "10": 101.0
                    }
                },
                "speedYRate": 1.0,<--------------y轴速度的比率，设为1是一倍，2就是二倍，作用于基础移动动作，以jumpspeedy等参数为单位速度。
                "shield1": 0.0,<-------------背面防御，设为0.8 的话，整个actiongroup下的动作都会带上自动防御，原理在body篇。
                "ite_gr": 1.0,
                "ite_lo": 0.0,
                "keyTriggerRef": null,
                "speedXRate": 1.0,<-------------x轴速度的比率，设为1是一倍，2就是二倍，作用于基础移动动作，是举重行走、举重跑步变慢的原理，以walkspeedx等参数为单位速度。
                "keyTrigger": {
                    "HFW_ArrayLenXXX": 0
                },
                "ite_atkName2": "",
                "mpBurn": 0.0,
                "keyTriggerRefIndex": -1.0,
                "ite_blastBreak": true,
                "piece": {
                    "HFW_ArrayLenXXX": 0
                },
                "ite_vo": 0.0,
                "ite_sfx2": 0.0
            },
            "1": {
                ······
				},
            "2": {
                ······
				},
            "3": {
                ······
                },
            "4": {
                ······
                },
			"5": null,
			"6": null,
			"7": null,
			"8": null,
			"9": null
			},

看完后，我们可以发现，在actionGroup中，只有少部分参数是有用的，其余大部分参数是用来设置道具的，人物SPT中不需要进行任何修改，一般来讲，带有ite字眼的参数是设置道具的，而不带ite的参数有的用来设置角色，有的用来设置道具、
接下来我会把这些无关参数以及其他不复杂的有用参数省略，着重讲actionGroup和actionIndex。

从actionGroup到actionIndex是整体到细节，actionInedx属于actionGroup，因此我先讲解整体的actionGroup。
以下是龙介的actionGroup，可以先浏览一遍，然后通过名称来猜测作用。
"actionGroup": {
            "HFW_ArrayLenXXX": 10,
            "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "normal", 
                "actionIndex": {
                  ······        <-----------------这里是为了讲解actionGroup，因此暂时省略了actionIndex的内容，后面再展开来讲。
                    }
            },
             "1": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "gua",
                "actionIndex": {
                    ······
                    }
            },
            "2": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "cat",
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                ······
                    }
            },
            "3": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "hea",
                "actionIndex": {
                ·······
                    }     
            },
            "4": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "rid",
                "actionIndex": {
                    ······
                }
            },
			"5": null,
			"6": null,
			"7": null,
			"8": null,
			"9": null

在原版HF中，人物的actionGroup最多用到了五个，分别是站立、防御、抓人、举重、骑乘，英雄拥有五个actionGroup，而士兵只有二到四个，大部分士兵不能举重，能举重的力士不能骑乘，若删掉英雄的4号actionGroup（骑乘），则英雄会无法骑乘，即使骑乘的动作（action）还在。
此处的站立是一个状态，而不是一个动作，凡是在自然状态下使用的动作和技能都属于站立，而骑乘状态下使用的动作和技能自然就属于骑乘，例如泰来骑马护盾、骑马烈光炮，虽然是不同的技能，但都是骑乘技能，agi都是4。
agi的全称为"actionGroupIndex",也就是actionGroup（动作组）的序号，0为站立，1为防御，2为抓人，3为举重，4为骑乘，序号是固定的，不能做任何更改，即使把名称改过也不行。
在原版中，5到9号agi未使用，但我们可以用它来实现变身功能，之后会有介绍。
观察一下骑乘站立这个动作，你会发现里面的技能的agi全部都是4，而如果使用agi为0的技能，角色会在使用站立技能的同时掉下马。
"65": {
                "HFW_classNameXXX": "Data.Action",
                "name": "_RID_STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 3,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gla",
                        "mp": 90.0,
                        "agi": 4.0,  <-----------------
                        "rkt": false,
                        "kr": "gra"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 4.0,  <-----------------
                        "rkt": false,
                        "kr": "gua"
                    },
                    "2": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 1.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 4.0,  <-----------------
                        "rkt": false,
                        "kr": "gla"
                    }
                }
            },
因此，在设置技能对应的agi的时候，我们要搞清楚这是个什么动作，一般情况下，技能对应的agi是0或者4，也就是站立和骑乘，而抓人状态下的技能除了褚英外非常少见。
如果是骑乘技能，那么按键（A_KeyTgr）下的agi就设成4，如果是普通技能，就设成0，如果是像褚英那样的抓人技能，就设成2。
而nextAgi、landAgi这种也是同样的道理，这里要注意0和-1 的区别，0为站立；-1 为不存在，也就是动作结束或落地后不会进入任何agi，两个数值不能混淆。

搞清楚agi以后，我们展开讲ati和ai，这是龙介站立状态（agi=0 ）下的actionIndex
"actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {           <-----------------"0" 为基本动作，如跑步、冲跳、后空翻等，这些动作本身通常没有什么特殊效果（除了kneel和pickitem），除非在frame设定特殊效果。
                        "HFW_ArrayLenXXX": 31,
                        "0": 1.0,       <-----------------ati内部则是ai，这里的"0"代表ai=0, ai=0 是站立的动作。
                        "1": 2.0,
                        "2": -1.0,
                        "3": -1.0,
                        "4": 3.0,
                        "5": -1.0,
                        "6": -1.0,
                        "7": 13.0,
                        "8": 6.0,
                        "9": 6.0,
                        "10": 7.0,
                        "11": 7.0,
                        "12": 8.0,
                        "13": 6.0,
                        "14": 6.0,
                        "15": 14.0,
                        "16": 16.0,
                        "17": 15.0,
                        "18": 17.0,
                        "19": 8.0,
                        "20": 4.0,
                        "21": 5.0,
                        "22": 9.0,
                        "23": 10.0,
                        "24": -1.0,
                        "25": 8.0,
                        "26": -1.0,
                        "27": -1.0,
                        "28": 6.0,
                        "29": 8.0,
                        "30": 109.0
                    },
                    "1": {             <-----------------"1" 为有特殊性质的基础动作，如挨打、倒地、被冰冻等。
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                        "1": 19.0,
                        "2": 22.0,
                        "3": 20.0,
                        "4": 21.0,
                        "5": 22.0,
                        "6": 28.0,
                        "7": 29.0,
                        "8": 30.0,
                        "9": 31.0,
                        "10": 32.0,
                        "11": 33.0,
                        "12": 38.0,
                        "13": 39.0,
                        "14": -1.0,
                        "15": -1.0,
                        "16": 36.0,
                        "17": 37.0,
                        "18": -1.0,
                        "19": -1.0,
                        "20": -1.0,
                        "21": -1.0,
                        "22": -1.0,
                        "23": -1.0,
                        "24": -1.0,
                        "25": -1.0,
                        "26": 40.0,
                        "27": 41.0,
                        "28": 42.0,
                        "29": 11.0,
                        "30": -1.0,
                        "31": -1.0,
                        "32": -1.0,
                        "33": 34.0,
                        "34": 8.0,
                        "35": -1.0,
                        "36": -1.0,
                        "37": 4.0,
                        "38": 4.0,
                        "39": 12.0,
                        "40": -1.0,
                        "41": -1.0,
                        "42": -1.0,
                        "43": 35.0,
                        "44": -1.0,
                        "45": 43.0,
                        "46": 44.0,
                        "47": 43.0,
                        "48": -1.0,
                        "49": 23.0,
                        "50": 24.0,
                        "51": 26.0,
                        "52": 25.0,
                        "53": 27.0,
                        "54": -1.0,
                        "55": 106.0,
                        "56": 107.0,
                        "57": 108.0
                    },
                    "2": {               <-----------------"2"为基础攻击，如跑攻、冲跳攻、普攻等。
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        "1": 74.0,
                        "2": 75.0,
                        "3": 76.0,
                        "4": 73.0,
                        "5": 73.0,
                        "6": 73.0,
                        "7": 77.0,
                        "8": 77.0,
                        "9": 77.0,
                        "10": 77.0,
                        "11": 78.0,
                        "12": 78.0,
                        "13": 78.0,
                        "14": 78.0,
                        "15": 77.0,
                        "16": 76.0,
                        "17": -1.0,
                        "18": -1.0
                    },  
                    "3": {                <-----------------"3"为技能，相比前面几个ati，技能更加自由，可以随意调换位置，但调换后ai也要跟着调换。
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0
                    }
                },
ati相对比较容易理解，但ai可能不太好理解，因为左边的数值也是动作，右边的数值也是动作，需要一定的脑浆才能理清。
以下是ai所对应的动作，接着我会讲解ai和action对应的方式。
ati:0
ai:
0 stand   
1 walk
4 run         <-----------------这里有很多跳过的序号，因为是不重要或者根本没用的ai
7 run_stop/rid_turn
8 jump_start
9 jump_forward_start
10 jump
11 jump_forward
12 jump_land
13 dash_start
14 dash_back_start
15 dash
16 dash_back
17 dash_air
18 dash_back_air
19 dash_land
20 roll
21 sky_roll
22 somersault
23 somersault2
24 rotate_end/rid_get_on
25 final_land
26 basic_guard
27 basic_catch
28 pick_item
29 picked_item
30 kneel

ati:1
ai:
0 hit1
1 hit2
2 hit3
3 hit1_back
4 hit2_back
5 hit3_back
6 fall1
7 fall2
8 fall3
9 fall4
10 fall5
11 fall6
12 fall7
13 fall8
16 fall_back1
17 fall_back2
26 fall_spin1
27 fall_spin2
28 fall_spin3
29 breakfall
33 lie
34 getup
37 lie_roll_up
38 lie_roll_down
39 lie_turn
43 lie_hit
45 breakguard
46 breakguard_sky
47 stepback
49 dizzy
50 caught
51 caught_struggle
52 caught_hit
53 fall_hit_wall
55 fall_ice
56 fall_fire
57 fall_thunder

ati:2
ai:
0 attack1
1 attack2
2 attack3
3 attack4          <---------------可以发现这里并没有attack5，那么褚英的第五击是怎么做到的呢？本篇结尾放答案。
4 up_attack
5 down_attack
6 forward_attack
7 jump_attack/rid_catch_attack
8 jump_up_attack/rid_catch_up_attack
9 jump_down_attack/rid_catch_down_attack
10 jump_forward_attack/rid_catch_forward_attack
11 dash_attack/rid_run_attack
12 dash_up_attack/rid_run_up_attack
13 dash_down_attack/rid_run_down_attack
14 dash_forward_attack/rid_run_forward_attack
15 dash_back_attack
16 run_attack
17 rotate
18 back_attack
 
 ati:3
 ai对应技能


如果您有观察站立动作的按键，会发现根本不存在移动、跳跃、攻击的按键设定，但角色却可以自由地跳跃、攻击、移动。这是因为"STAND"这个action对应了ai："0",使它获得了“站立”的性质，
如果把"STAND"与行走的ai，也就是"1"号ai对应，那么这个"STAND"虽然表面上是在站立，但实质上却是行走，看上去就是一个人在滑行。
action对frame进行了修饰，使它拥有了转身、循环的性质，而ai又对action进行了修饰，使它获得了移动、自由按键等性质。
"RUN"和"WALK"这两个动作本身是没有任何位移的，正是因为对应上了run和walk的ai，才具有了移动速度，如果把"BALL"和walk的ai对应上，那么行走的时候就会做出飞龙斩的动作，但仍然具有移动速度，如果不能理解，可以实际做一做试试，这样更容易理解。
接下来讲解一下ai与action对应的方法。

这里我用普通状态下的0号ati举例
"0": {       <----------------此为agi
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "normal", 
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {            <----------------此为ati
                        "HFW_ArrayLenXXX": 31,
此为ai序号------------> "0": 1.0,<----------------此为ai对应的动作序号。
                        "1": 2.0,         <----------------可以看到，左边的序号为1，代表ai=1 ，右边的数值为 2.0 ，代表action是2号action，也就是walk，
                        "2": -1.0,
                        "3": -1.0,
                        "4": 3.0,
                        "5": -1.0,
                        "6": -1.0,
                        "7": 13.0,
                        "8": 6.0,
                        "9": 6.0,
                        "10": 7.0,
                        "11": 7.0,
                        "12": 8.0,
                        "13": 6.0,
                        "14": 6.0,
                        "15": 14.0,
                        "16": 16.0,
                        "17": 15.0,
                        "18": 17.0,
                        "19": 8.0,
                        "20": 4.0,
                        "21": 5.0,
                        "22": 9.0,
                        "23": 10.0,
                        "24": -1.0,
                        "25": 8.0,
                        "26": -1.0,
                        "27": -1.0,
                        "28": 6.0,
                        "29": 8.0,
                        "30": 109.0     <----------------agi=0 ，ati=0 时，第30号ai代表的是kneel动作，kneel有两个性质，一是会转变队伍（故事中设置队友），二是不会被敌人主动攻击，
						    },                           转变队伍是frame里设置的，而不被敌人攻击则是ai里设置，也就是说，0号agi下的0号ati里的30号ai，无论对应哪个动作，都不会被敌人主动攻击。
						"1":······,                      可以尝试将30号ai对应的动作从109改成飞龙斩的94，这样在kneel的时候会自动放出飞龙斩，同时不会被攻击。
						"2":······,
						"3":······
						           },
						"1":······,                      
						"2":······,
						"3":······,
						"4":······
                    }
因此，当我们要设定技能结束或者落地后接的动作时，要找到接下来的动作所对应的agi、ati、ai，
比如kneel动作的序号为109，就在actionIndex里搜索 109.0 找到对应的agi（kneel为0）、ati（kneel为0）ai（kneel为30）后，将nextAgi、nextAti、nextAi改为和kneel一样的，
例如，将飞龙斩的nextAgi设为0，nextAti设为0，nextAi设为30，在飞龙斩动作结束后，将会进入下跪动作，实际修改示例如下：
	"94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": 30.0,
                "allowTurnFace": false,
                "nextAti": 0.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": 0.0,
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }
需要注意的是，如果通过按键使飞龙斩在结束前进入了其他动作，那么这个nextAi不会再生效，只有在通过"last": true 自然结束时，nextAi和landAi才能生效，
像褚英的霸王冲锋，按攻击键会接上勾拳，而自然结束则会进入另外设置好的结束动作，
之前有讲到，ati=3 对应的是技能，因为每个人的技能性质都不同，所以ati3内的ai并不会因为序号而使性质发生改变，因此移植技能或制作新技能时往往会把它的ai设置在ati=3 里，
此外，如果把新技能扩充到ati=0 或者ati=1 、ati=2 的话，这个技能会失去一些性质,例如位移和nextAi。但如果是替换原本的ai，则可以保留一些性质，例如位移。
是否选择替换ati=0 、ati=1 、ati=2 内的ai需要根据需要来决定，例如想制作一个新的跑步动作，那就可以在ati中用新动作的序号代替掉原本跑步的动作序号，修改action对应的frame同样可以实现这种功能。
在action篇有提到，nextAi等参数只适用于技能（ati=3 内的ai对应的动作），在ati=0 、ati=1 、ati=2 内的动作不适用，这点要注意。
landAgi、landAti、landAi的使用和nextAgi、nextAti、nextAi原理一样，因此不再详细讲述。
drew的第五击实质上是技能，在attack4的动作下设置按键通向这个技能，就可以做出attack5的效果。
通过本篇agi的知识和之前按键设定的知识，我们可以做到的就不仅有修改蓝耗和按键了，我们还可以修改按键所对应的动作。		
以下是龙介站立动作下的按键，我们尝试把对应飞龙斩的按键改为对应飞龙斩2（ball2）			
			

       "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,    <----------------ai是0，那么这个按键通向的是0号ai所对应的动作
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,  <----------------ati是3，那么这个按键通向的是技能
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,<----------------agi是0，那么这个按键通向的是0号actionGroup，也就是站立状态
                        "rkt": true,
                        "kr": "gua"        ↑将以上三段话联系起来，我们可以得出，这个按键通向的是站立状态下的0号技能，龙介的0号技能是升龙斩
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,<----------------而这个按键则是通向3号技能，也就是飞龙斩，我们尝试把它改为 4.0 ，也就是飞龙斩2（ball2）
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
				
"a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,   
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0, 
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"      
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,<----------------只有ai发生了变化
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },

导入后会发现龙介站立状态下使出的飞龙斩变成了飞龙斩2


4、制作新技能篇

在搞懂了agi、ati、ai的意义和应用后，我们可以制作出新的技能
这里只是讲解新技能action和actionGroup的设定，frame的知识放在后面

①添加新action

要制作新技能，我们需要加入新的action。由于action内参数较多，我们可以先复制一个原有action，然后再进行修改，这里我们用龙介飞龙斩举例

"94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            },<------------------------这个逗号不要复制，复制了的话要删掉
我们从动作序号前的引号开始，选择到最后的大括号（Shift+鼠标左键可快速选择）
复制它，注意不要复制到逗号，因为它是用于连接两个action的，而不是属于action的一部分
我们把他粘贴到最后一个action（一般为kneel）的后面然后改序号

"109": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "KNEEL",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 418.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 109.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },<---------------------------别忘了用逗号隔开
"94": {  <-----------------------------------------------------此时action序号还是原本的94，我们需要把它改为109后一号的110
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,<--------------------部分action会带有nextAi，需改为-1.0 ，如果有需要也可以选择保留
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",<--------------------名称也需要改一下，可以自由命名
                "a_keyTgr": { <--------------------这里的按键，若需要可以保留，不需要的话记得删掉
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0, <----------------此处为新动作的起始帧，由于我们还未提及frame的知识，所以仅仅把它往后5帧
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }


"109": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "KNEEL",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 418.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 109.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },
"110": {  <-----------------------------------------------------序号必须按顺序来，跳过一个数字的话会出错
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALLFAST",<--------------------这个名称就是故事里的新ac代码，若ac代码重复，则以后面的那个动作为准
                "a_keyTgr": null,<--------------------注意删除按键必须改成null的形式，不能改成"HFW_ArrayLenXXX": 0,不然有可能引起卡顿
                "landAgi": -1.0,
                "frameIndex": 321.0,<--------------------316 到 320 号帧已经被跳过，直接从321开始，因此起手会变快一些
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }

②将新增的action添加进actionGroup里
先找到站立状态的actionGroup，找到ati3的位置
"actionGroup": {
            "HFW_ArrayLenXXX": 10,
            "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                ······
				"name": "normal",
				······
                "actionIndex": {     
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        ······
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        ······
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        ······
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0<------------------这里的0到10是龙介原有的技能，不要改变，把新的技能扩充到10的后面
                    }
                },
                ······
				······
            }	

         扩充后：

			
			"actionGroup": {
            "HFW_ArrayLenXXX": 10,
            "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                ······
				"name": "normal",
				······
                "actionIndex": {     
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        ······
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        ······
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        ······
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0,
						"11": 110.0
                    }
                },
                ······
				······
            }
			此处的11指龙介站立状态下的第11号技能，而110则对应了action的序号，这就意味着，使用这个技能时，所进行的动作为110号动作
			
②在action中设置按键

我们先按照自己的想法为技能想好一个按键，这里我们设成grj，也就是防御、右、跳跃
一个技能的按键，需要在多个action中设置，因为每个按键设定只能作用于一个动作，
而我们放技能时无法避免防御、移动、跑步，因此，站立、行走、跑步、防御站立、防御行走、防御跑步都需要设定一次按键，这个技能才能正常使用
一般的地面技能，在这六个action里设置按键就已经足够使用，但如果需要在空中、滚地、攻击过程中使用，还需要另外加按键。	
我们先把按键加入到stand的动作里，先找到龙介站立的动作（stand）
			
	"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua", 
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gua"
                    },
                    "1": {      <---------------------------------这里原本有两组按键，我们要增加一组新按键，可以直接复制原本的按键再进行修改
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }		
			加入后代码如下
			
			"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 3, <------------------------加入新按键后，技能按键的数量自然也要跟着增加。不过，在不需要使用什么工具的情况下，标注的数量比实际数量少是没什么影响的，但只能少，不能多，否则会出错。
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua", 
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gua"
                    },
                    "1": {     
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    },
					"2": {     <------------------------------复制的技能按键，可以复制到后面再改序号，也可以复制到前面，然后改原本按键的序号，这里有一定的技巧，稍后会讲
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 11.0, <-----------------------刚刚加入的那个动作所对应的ai是11，所以这里改成11
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0, <-----------------------原本的飞龙斩为技能，ati=3 ，新的飞龙斩也是技能，所以ati还是3，不用改 
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "grj",<------------------------------按键改为grj，一般情况下不能和原有按键重复
                        "mp": 90.0,
                        "agi": 0.0,<-----------------------虽然是不同技能，但都是站立状态下发动的，所以agi也不需要改
                        "rkt": false,
                        "kr": "glj"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }		
			
第二个action开始，就不需要一个个复制改写了，我们可以直接复制出新增加的按键，然后扩充到其他动作的按键里，注意序号要调整好，	
仿照以上格式把按键加入到stand、walk、run、gua_run、gua_walk、gua_stand中，技能就能正常使用，
如果要滚地使用，就再给滚地动作（roll）加入按键，
如果是空中技能，就给跳跃（jump）、防跳（gua_jump）加入按键而不用给地面动作加按键，
冲跳、抓人等也是同理，需不需要加按键取决于技能的性质以及你的想法。

此外，技能按键里有一项"rtk"也是很重要的，如果设置错误，就会导致技能放不出或提前放出。		
			"2": {     
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 11.0, 
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0, 
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "grj",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,<----------------站立动作下的一切技能按键，"rtk"都应为false
                        "kr": "glj"
                    }
"rtk"的具体机制比较复杂，暂时不需要理解，只需要清楚：一般情况下，普通动作下的rtk为false，攻击或技能动作下的rtk为true，"rtk"为false的按键是可以在此动作的任意时刻放出的			
		
5、按键顺序篇			
			
按键的顺序，是有很大的意义的，如果顺序不对，会导致技能无法放出。
举个例子，我们在飞龙斩动作里设置一组按键，通向飞龙斩的动作。
 "94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    },
					"2": {         <----------------这里设置了一个新的飞龙斩按键，这个按键的设定实际上是没有问题的，但他永远也放不出来，可以先思考一下原因
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }			
			
			这里就涉及到了按键顺序的问题。
			         "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",<-------------------这里已经有了一个"a"的按键，而新的按键为"gra"，要按出"gra"，就会不可避免地按到"a"
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    },
					"2": {         
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    }
                }
				
			按键冲突的情况下，技能按键的优先级，是由按键的序号决定的。在mp足够的情况下，按键冲突时，只有序号在前的按键会生效，	
			因此，我们可以调换一下两个按键的位置，从而解决按键冲突的问题，
			一般情况下，按键数量较少的技能按键会放在后面，因为按下"gra"时，会触发"a"按键,但反过来，按下"a"时，却不会触发"gra"按键，	
			修改完后代码如下。
			 "94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
			    "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
					"1": {        <------------------两者位置和序号已互换
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    },
                    "2": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
					
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }	
			这样一来，"a"的按键就无法影响到"gra"了。
			
			此外，利用按键的顺序和mp消耗量的设定，我们可以给同一个动作下的同一个按键设置多个不同技能。
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 3,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra", 
                        "mp": 400.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 200.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    },
					"2": {        
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 0.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    }
                }
			还是刚才那三组按键，但所有技能对应的按键都改成了gra，这样一来，还能放出0号以外的按键对应的技能吗？			
			
			答案是能。
			可以看到，0号按键的mp设到了400，那么在有400mp的情况下，自然就会触发0号按键对应的技能；
			而如果没有400mp，但有200mp，就会自动往下触发1号按键对应的技能；
  如果200mp也没有，就会触发2号按键对应的技能，因为此时剩余的蓝量只能符合2号技能按键的要求。
    
    
    
06、动作移植篇：	

本篇难度较高，可以先跳过，之后再学。

动作移植和之前提到的制作新技能相似，但是新技能的frame是从其他角色的frame里抄过来的。
第一步和制作新技能一样，我们要先新增一个action，并把这个action设置进actionGroup里，再设置好按键。
而第二步有点不同，我们不用角色自身的frame，而是将其他角色的frame复制过来，再设置好起始帧。

在传统的版本中，大部分角色的贴图位置不同，所以动作移植并不是只需要复制frame就行。
但在HF-EX版本中，绝大部分角色的贴图位置都已经统一，所以可以无障碍移植动作（其实也不是100%无障碍）
			
动作移植需要注意以下几点：		
			
有些frame里设置的贴图并没有在移植动作的角色里绑定，对于这些贴图应该进行删除或添加绑定处理。
有些frame设置了refIndex，直接移植会导致错乱，需在被移植动作的角色frame里找到refIndex对应的frame进行替换。
不同角色的同种贴图的数量可能不同，例如褚英的头部贴图比龙介多了一张侧面的图，龙介会因为缺少这张图而产生bug。			
部分技能的action不止一个，例如落龙斩是由两个动作组合而成，只移植一个动作不能发挥作用。
			
			
			
二、基础参数篇：

基础参数，就是位于spt第一级的参数，这些参数除了actiongroup、action、frame之外都是比较简单的，大部分都可以直接改数值或直接改下级参数的数值。
而基础参数，大概可以分成三类，一类是简单基础参数，这种参数的特点就是只有一个数值或是只需要设定true还是false，是最容易修改的。
第二类是普通基础参数，这种基础参数下方也有一定的下级参数，但它的下级参数和简单基础参数一样，只有一个数值。
第三类是复杂基础参数，人物spt里只有actiongroup、action、frame可以称得上是复杂基础参数，因为他们内部又包含了一大堆参数，尤其是frame


	 
 01、简单基础参数篇:	
			
		"teamApp": false,（皮肤是否会随着队伍而变化，原版游戏的英雄全部为false）
        "walkGrab": false,（走路时是否会自动抓住士兵，如drew）
        "id": "jenny",（角色id，与人物文件位置必须一致，例如想把lucas位置上的角色换成drew，就要把drew的spt里的"id"改成lucas）
        "mHp": 440.0,（无等级化下的血量，如果是角色没有 有等级数据 则会同时影响有等级时的血量，原版人物列表中的角色均有 有等级数据，不在人物列表的角色均没有 有等级数据，部分mod则为一些不在人物列表的角色额外添加了有等级数据）
        "rHp": 1.0,（回血速度，在spt里改无效，所以不用理会）
        "mSt": 500.0,（角色sp值，不管有无等级）
        "rMp": 1.0,（回蓝速度，在spt里改没有作用，应该是旧版本留下的参数）
        "rSt": 1.0,（sp回复速度）
        "mMp": 500.0,（无等级化下的蓝量，如果是角色没有 有等级数据 则会同时影响有等级时的蓝量，原版人物列表中的角色均有 有等级数据，不在人物列表的角色均没有 有等级数据，部分mod则为一些不在人物列表的角色额外添加了有等级数据）
      
        "defBody"可以理解成角色body一个模板，角色在一些动作下会使用这个模板，"defBody"会影响自动防御，后面会提到
		
		"defBodyW": 110.0,（body模板的长度）
        "defBodyH": 240.0,（body模板的高度）
        "defBodyT": 60.0,（body模板的宽度）
		
		"refSpt": "model0",（借用的贴图数据，当被借用的角色数据出错时，此角色也会跟着出错，之后详细讲解）
        "type": 1.0,（种类，有人类、坐骑、道具、特效等，不能随便改）
        "wisdom": 50.0,（智慧，会影响战争中的com智商）
        "st_rate": 1.0850694444444444,（sp的消耗速度，越高越容易消耗sp）
		"weight": 1.0,（重量，数值越大越不容易被击飞，同时也更难推动，同时推动重物更容易）
        "walkSpeedX": 17.0,（走路的移动速度）
        "runSpeedX": 25.0,（跑步、翻滚的移动速度）
        "jumpSpeedY": -63.0,（起跳时向上的速度）
        "jumpSpeedX": 29.0,（向前/后起跳时向前/后的速度，同时也会影响部分特殊技能的速度）
        "dashSpeedY": -38.0,（冲跳起跳时向上的速度）
        "dashSpeedX": 72.0,（冲跳时向前的速度）
		"airDashSpeedX": 61.0,（后空翻的移动速度）
		
		"hasHorse": false,（是否拥有马，改为true则开局自带马，例如骑兵。如果角色是士兵，下马后马会跑掉，过一段时间自动召唤新的马。如果角色是英雄，下马后马不会跑掉，同时不会再自动召唤马）
		"name": "Jenny",（名称，可以自由改，会在游戏结算的时候显示）
		"meleeDx": 280.0,（com普攻的x轴判定范围，当这个范围内有敌人时，com就会发动普攻，和技能的ai类似）
        "soldierNumber": 1.0,（作为vs里添加的士兵时，每组的人数，例如步兵为4，骑兵为2）
        "soldierReserved": 1.0,（作为vs里添加的士兵时，每组的后备，例如步兵为4，骑兵为2）
        "meleeDz": 80.0,（com普攻的z轴判定范围，当这个范围内有敌人时，com就会发动普攻，和技能的ai类似）
        "brk0": 0.0 （当防御值降低到这个值时，就会被破防，越高越容易被破，原版所有英雄都为0，士兵会高一些，改成负数能增强防御）
		"isSoldier": false,（是否为士兵，决定是否有血条、是否能被褚英直接抓住等）
		"sfxHurt": 45.0,（受伤时发出的声音，具体数值参照群文件-HFSE故事代码-ac代码补充最新版）
        "guardSfx": 0.0,（防御住攻击的时候发出的声音，如lucas为0，是刀剑碰撞声；drew为1，是肉体格挡声；冰人为4，是碎冰声。同时，当数值为4时，就会像冰人一样被打爆出冰块，血量为0时直接消失。）
        "shadowR": 1.0,（影子的面积，可以改成0）
        "RQ": 800.0,（威慑范围，这段范围内com会绕着走向你，远程角色的RQ会明显大于近战角色）
        "HQ": 0.8,（骑乘时，威慑范围=人物RQ+坐骑RQ*人物HQ，同时也是角色寻找坐骑的范围，例如力士的HQ为0，不会自动寻找坐骑）
        "STQ": 0.1,（举重和常态时的sp耐用度的比值，数值越小，举重时消耗sp越快）
		"soldierQ": 70.0,（战争复活价格，同时也决定了开局免费复活次数，50以内有20次免费复活，50到70为10次，70到100为5次，100到200为3次，200以上为1次）
		"HGQ": 0.1,（角色寻找重物的范围，改成0则不会寻找重物，同时与AI相关，推测影响的是骑乘抓人时的AI）
		
		以下为具体作用未知的参数，可以按照名称自行探索，欢迎补充
		
		"boxScale": 1.0,
		"auraColor": 16777215.0,（此数值代表纯白色的颜色代码，但改了不会有变化，所有角色都是这个数值）
		"horseApp": "0",
		"defense": 50.0,（防御，在设定方式上和wisdom相似，但具体作用未知）
		"attack": 50.0,（攻击，在设定方式上和wisdom相似，但具体作用未知）
		"leadership": 50.0,（领导能力，在设定方式上和wisdom相似，但具体作用未知，推测和带兵能力有关）
		"cropApp": "0",
		"fh": null,
		"fn": null,
        "gravityRate": 1.0,（从名称看和重力相关，但直接改并没有作用）
		
		
2、战争招兵相关参数篇：		
	
	
战争模式的招兵，涉及到了普通基础参数，这些普通基础参数相对于简单基础参数要稍微复杂一些，但也就是改改数字、id，并不复杂
普通基础参数并不多，只有皮肤绑定和战争招兵数据比较重要
以下是和战争模式招兵有关的参数		
		
        "hire_id": {（此角色在战争中召唤的士兵的种类，可以重复，而且高级兵可以在低级兵之前）
            "HFW_ArrayLenXXX": 4,
            "0": "z_infantry01",
            "1": "z_archer01",
            "2": "z_woman01",
            "3": "z_cavalry01"
        },
		"hire_max": {（此角色在战争中召唤的士兵的最大组数，与hire_id里的士兵对应，例如这里的5对应了hire_id里的z_infantry01，也就是步兵，意味着步兵最多召唤五组）
            "HFW_ArrayLenXXX": 4,
            "0": 5.0,
            "1": 2.0,
            "2": 1.0,
            "3": 4.0
        },
		"hire_h": {（此角色在战争中召唤的士兵所带的骑乘，"h"为马，"m"为魔兽,"t"为三角龙）
            "HFW_ArrayLenXXX": 4,
            "0": null,
            "1": null,
            "2": null,
            "3": "h"
        },
		"hire_price": {（此角色在战争中召唤的士兵所需的价格，例如这里步兵为100，妇人为150）
            "HFW_ArrayLenXXX": 4,
            "0": 100.0,
            "1": 100.0,
            "2": 150.0,
            "3": 160.0
        },
		这4组参数共同决定了战争的招兵，正常情况下他们的元素量必须是一样的，如果需要扩充新的兵种，必须同时扩充4个参数，
		否则不能起作用，即使此兵种不带骑乘，也要在hire_h里给新兵种的序号加上 null
		
	

	
3、皮肤绑定篇：				
		
皮肤绑定的参数为："spriteLimb",此处我列出的是龙介的皮肤绑定		
		
"spriteLimb": {
            "HFW_ArrayLenXXX": 45,
            "0": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_00Head",（此处为这个序号所绑定的贴图组的名称，这里是龙介的头部）
                "limbType": 0.0,（种类，仅作为标记）
                "xScale": 0.99,
                "limb": null,
                "yScale": 0.99,
                "limbTypeName": null
            },
            "1": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {（此角色不同队伍下的不同绑定，a为1队，b为2队，c为3队，d为4队，e、f在原版是故事专用，这也是设置皮肤的原理，如果teamapp为true，角色就会根据队伍而改变皮肤）
                    "HFW_ArrayLenXXX": 0,
                    "b": "z_bandit01_01ChestB"（这里可以看到，原版龙介第二队绑定了盗贼的上衣，是第五话中穿着狱卒衣服的皮肤，但由于原版龙介的teamapp为false，所以玩家不会因队伍而改变皮肤）
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_01Chest",
                "limbType": 1.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },
            ······
            "28": {（28通常是披风的位置，由于龙介没有披风，所以未绑定）
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "",
                "limbType": 28.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },
           ······
        },

在原版中，所有人物的不同部位都是会整齐地放在固定序号的，例如所有人的头部都为0号，身体为1号，武器为20号，这也为技能的移植提供了可能性。
以下是原版游戏中，每个序号所对应的贴图部位，左和右指的是角色向右站立时，呈现在屏幕上的左边或者右边，而不是角色的左侧或者右侧。

"0": Head 头部
"1": Chest 身体
"2": 原版未使用
"3": Hips 裆部
"4": LeftShoulder 左肩甲
"5": UpperArm 左大臂
"6": LowerArm 左小臂
"7": LeftFist 左手
"8": LeftFistCover 左手指
"9": RightShoulder 右肩甲
"10": UpperArm 右大臂
"11": LowerArm 右小臂
"12": RightFist 右手
"13": RightFistCover 右手指
"14": UpperLeg 左大腿
"15": LowerLeg 左小腿
"16": Foot 左脚
"17": UpperLeg 右大腿
"18": LowerLeg 右小腿
"19": Foot 右脚
"20": Sword 左手武器，正常角色的武器都放在这个位置
"21": 原版未使用
"22": icefire 冰火雷特效
"23": Collar 衣领
"24": Sword 右手武器，原版可选人物中只有Shawn有使用
"25": 原版未使用
"26": icefire 冰火雷特效
"27": Cape 少部分角色绑定披风的位置
"28": Cape 大部分角色绑定披风的位置
"29": Skirt 裙子
"30": Hair 头发
"31": 原版未使用
"32": 原版未使用
"33": 腰带
"34": HipsGuard 裆布
"35": 原版未使用
"36": 原版未使用
"37": LegGuard 左腿甲
"38": LegGuard 腿甲
"39": 原版未使用
"40": 原版未使用
"41": 左手武器的柄，用于覆盖手部
"42": 右手武器的柄，用于覆盖手部
"43": effect 武器或拳头挥舞时的残影
"44": effect 武器或拳头挥舞时的残影

这些贴图部位，虽然在原版都是按照序号进行绑定，但有时也可以不按照序号进行绑定，但这样做的前提是在frame进行一定的设置，这是较为复杂的内容，以后会讲解。
由上面的数据可以得知，大部分位置都是有被使用的，但它们是被不同的角色使用，例如leo、eason、jenny有头发的绑定，但大部分角色没有。
正常角色不可能既有头发绑定，又有裙子、又有腿甲、又有双手剑、又有披风。因此，正常角色只会用到一半左右的位置。
因此，我们可以利用空余的位置额外绑定一些贴图，但并不是绑定了就能起作用，我们还需要在frame中对新增的贴图进行设置。
但如果是单纯的换掉原本的绑定，而不是新增绑定，贴图就能直接显示出来。

要换绑定，只需要改 "limbName" 即可，举个例子，如果要把龙介的身体换成承影的，我们就要到承影的spt里复制身体部位的limb名称
就像这样：
"1": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0,
                    "b": "z_bandit01_01ChestB"
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_01Chest",
                "limbType": 1.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },
改完后
 "1": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0,
                    "b": "z_bandit01_01ChestB"
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Shawn_01Chest",
                "limbType": 1.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },

（不过，并不是所有人物之间都能直接换绑定，因为不同人物贴图的位置、大小不一样，直接换可能会导致错位，但也有位置和大小差不多的贴图，这些贴图可以互相替换绑定。
具体哪些人物的哪些部位可以互换绑定，请到HFW群下载文件：“HFW可互换绑定.docx”。）
不过，这个问题已经得到解决，新出的HF-EX版本将绝大部分角色的贴图位置和大小都设成了一致，在这个版本里面可以自由地互换绑定。
"limbName"对应的是角色lmi文件里，limb内写的名称，limb是一套贴图，例如龙介的头部贴图，包含了正面、侧面、被击倒时的头部贴图。
如果想要制作一套新皮肤，我们就需要新增limb文件，具体操作可以到HFW群内下载“HFW替換皮膚綁定.docx”

 除了皮肤绑定和战争招兵、剩下的普通基础参数都比较不重要，以下是剩下的普通基础参数，这些参数没什么作用，可能是作为注释或者是老版本遗留下来的废弃代码。      		
		
		"lmiFiles": {（此角色用到的lmi，只是作为记录，并没有什么影响）
            "HFW_ArrayLenXXX": 2,
            "0": "lmi_data/global.lmi",
            "1": "lmi_data/jenny.lmi"
        },
		"cad": {（改掉不会有任何影响，可能是类似于注释的参数）
		"keyTgr": {（按键，与A_keyTgr不同，这个改掉不会有影响，可能是作为注释）
		
		以下为作用未知参数。
		"renderedPic": {
		"renderedPic_2": {
		"renderedPicH": {
		"renderedPic_2H": {	
		
		
		
三、frame入门篇:

掌握了actiongroup和action的知识后，就可以开始学习frame了，frame是spt中最重要的一部分，占了整个文件的98%以上。
同时，它也是这个spt里最复杂的一部分，其中的一些小细节可能都要比之前的很多参数复杂。可以说，掌握了frame，你就掌握了改角色。	
frame其实就是帧，就像视频的帧一样，但区别是HF里的帧除了图片还要设置身体、攻击等判定。	
理解透frame的知识可能有点难度，但只要有耐心、肯用心，掌握它也只是时间的问题。
由于frame参数太多，所以这里不像action那样直接把全部参数列出来，而是一个一个讲解。

01、结束帧篇：
		
frame里有一个"last"的参数，这是用来结束动作的，当此frame的last为false时，意味着这个动作还没结束，当这一帧结束时，会自动进行到下一帧。		
而如果"last"为 true ，就意味着这是此动作的最后一帧，当此帧结束时，就会结束动作，如果有设置nextAi，就进入下一个动作，如果没有设置，就会回到站立，如果是空中动作则回到跳跃状态、
"last"并不复杂，但却非常重要，通过"last"，可以找到一个action的所有帧，还可以将多个动作合成为一个动作，或者将一个动作拆成多个动作。
举个例子，龙介的飞龙斩，是从316号帧开始的，316号帧到329号帧的"last"都是false，因为它们不是结束帧，而到了330号帧，"last"就变为了true，这就意味着330号帧是飞龙斩的最后一帧。 
"329": {
                "HFW_classNameXXX": "Data.Frame",
				······
                "last": false,
				······
                 },
"330": {
                "HFW_classNameXXX": "Data.Frame",
				······
                "last": true,
				······
                 },
"331": {
                "HFW_classNameXXX": "Data.Frame",
				······
                "last": false,
				······
                 }
而331号帧，刚好又是ball2的起始帧，因此，如果把330号帧的"last"改成false，那么飞龙斩动作就不会结束，要到飞龙斩2的结束帧才会结束。
这样一来，飞龙斩动作所进行的就是飞龙斩+飞龙斩2的所有帧，相当于把两个动作合成了一个动作，而原本的飞龙斩2动作，331号开始的帧没有改，所以不会受影响。
如果不能理解就实际改一次试试。

02、拆动作篇:

把两个连着的动作合成为一个动作不是什么难事，但把一个动作拆成两个动作相对来说比较麻烦，因为要进行动作的连接。
不过这也正好可以用来尝试之前学到的关于动作连接的知识。
一个动作拆成两个动作，并不会因为动作数的改变而变慢，因为动作之间是无缝连接的，没有延迟，所以，理论上一帧一个动作也是可行的。
拆动作有很大的意义，比如在一定动作下发动技能时跳过起手、为前面的帧和后面的帧设置不同的按键、将起手或收手动作借给其他动作用来节省空间等。
例如,PMM里的Eason0，将四连斩分成了四个动作，在前三刀收尾时均可放出落龙，但不能放出飞车落。而最后一刀收手时既可放出落龙，也可以接飞车落。
不过，比起实际意义，拆动作更大的好处是可以帮你更好地理解last和动作的连接。

还是拿龙介的飞龙斩举例，龙介的飞龙斩由316号帧开始，330号帧结束，其中，323号帧会放出一个飞龙斩道具。
因此，我们可以把316号帧到322号帧单独设为一个动作，将其作为起手动作，这样一来，322号帧就成了这个动作的结束帧，因此"last"要改为true
这样一来，原本从316号开始，到330号才结束的动作，变为322号就结束了，因此它就变成了起手动作，而323到330这段帧，我们还要另外设置一个动作。

我们先将ball的动作原原本本地复制到原本的最后一个动作的后面，然后改序号
"109": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "KNEEL",（原版龙介最后一个动作为kneel）
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 418.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 109.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },
			"110": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }	
			
然后修改一下"frameIndex"，使这个动作对应的帧为后半部分的帧。			
			实际修改如下
			
	"109": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "KNEEL",（原版龙介最后一个动作为kneel）
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 418.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 109.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },
			"110": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL1B",（名称最好改一下）
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 323.0,（这里的316已改为323）
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }

	我们将这个新动作的起始帧由316改为323，那么这个动作所对应的帧就是飞龙斩的后半部分，也就是323到330。此时只要再把原本的action（316至322号帧）和这个新增的action（323到330号帧）连接起来，就完成动作的拆分了。
	先将新的动作（可以看到这个新动作的序号为110）设置进actiongroup，否则不会起作用。
			
			 "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                ······
                "name": "normal",（由于飞龙斩是站立技，所以设置进站立的actiongroup里）
                ······
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": 1.0,
                        ······
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                        ······
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        ······
                    },
                    "3": {（新增的动作往往都是技能，因此扩充到技能的ati，也就是3号ati）
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0,
						"11": 110.0 （我们把新的action扩充到最后，然后ai的序号向后推，可以看到11号ai现在对应上了110号动作）
                    }
                },
               ······
            },
			
设置完以后，我们记住这个ai（11），然后到原本的动作里设置连接到这个动作			
	 "94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": 11.0,（新动作的ai为11，所以nextAi设置成11）
                "allowTurnFace": false,
                "nextAti": 3.0,（连接到技能动作，所以nextAti为3）
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": 0.0,（连接到站立状态的动作，所以nextAgi为0，和-1 要区分开）
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }

设置完以后，飞龙斩动作就算是拆开了，可以尝试在一些动作下直接接上无起手的飞龙斩，因为是很基础的知识所以不再详细讲解。

03、frame延时篇：

如果你在游戏中有仔细观察，会发现一些人物在做出一些动作时会保持一段时间，例如三巨头自爆、一些收手或起手动作。（此处的动作指视觉上的动作，和action无关）
其实，这是因为某些帧有延时，会保持一段时间后再进入下一帧。
延时，在frame中表示为"duration"，数值越大则延时越长，duration为1时，相当于把这一帧延长了和原本一帧的时长相同的时长，也就是说，这一帧保持的时长翻倍了，而duration为2则是翻三倍，为3是翻4倍，以此类推。
当人物处于帧的延时状态时，攻击、身体受击范围、人物贴图都会保持不变，如果这一帧有释放道具，则只会放出一次道具。
延时并不是起手、收手动作的专利，实际上，很大一部分帧都是有延时的，因为原版每个动作的帧的数量并不多，如果没有延时，动作就会很快过去。
除去蓄力、起手、收手、硬直的帧，普通的帧的"duration"一般为0或1，少部分为2，而3以上则大多为特殊帧（起手、收手、硬直等）			
举个例子，龙介的attack1和attack4的总帧数都是8，但它们的速度却完全不一样，这就是因为"duration"的不同。
龙介attack1的八个帧的"duration"分别为:"0.1.0.0.0.0.1.2”共延时了4帧，加上帧原本所占的时值，动作一共进行了相当于12帧的时间。		
龙介attack4的八个帧的"duration"分别为:"0.1.1.1.1.5.1.1”共延时了11帧，加上帧原本所占的时值，动作一共进行了相当于23帧的时间。
同样是八帧的两个动作，却因为延时不同而导致速度几乎差了一倍，可见"duration"也是很重要的一个参数。
不过，"duration"虽然重要，改起来却没什么难度，只需要改数值就行。我们可以利用它做出加速角色、减速角色或是单独给某个动作加速、设置蓄力动作等。			
			
04、复制帧篇：

利用"duration"，我们可以给某一帧进行延时。但是，在延时的过程中，这一帧的判定没法进行调整，而且只能同时放出一组道具。
如果我们要让角色的某个动作（视觉上的动作，非action）在前一段时间和后一段时间里拥有不同的判定，或者按顺序轮流放出道具，我们就要用到另一种方法来进行延时。

这种方法就是复制，我们可以把原本那一帧复制一次，这样这一帧就进行了两次，相当于延长了一倍的时间。
比起"duration"，复制帧的优点是可以精细地进行调整，但缺点是比较麻烦。
之前有提到过，无论frame、action还是actiongroup，都必须按顺序排列。而如果把某一帧复制了一次，复制出的帧就要改一下序号。
如果复制的这一帧在最后面，那么改完序号就没事了，但如果在中间，由于复制出的帧占了一个序号，会导致之后的序号全部乱掉，需要重新手动排列一次。除非之后有一些废弃的帧可以空出一个序号。
简单来说，就是处于中间或前面的帧，不适合用这种方法，但一般新增技能的frame都会增加到frame最后面，因此复制法在制作新技能的时候还是很有用的。

以下是实际复制示范，由于frame内参数过多，我会先删掉所有的参数，只保留"index"
······
"305": {
              ······
                "index": 305.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},
"307": {
              ······
                "index": 307.0,
              ······
				},
"308": {
              ······
                "index": 308.0,
              ······
				}		
······		
	
可以看到，这里展示了四个frame，假如我们需要复制两次306号帧，就把306号帧的全部内容原原本本地复制到306号帧后面

······
"305": {
              ······
                "index": 305.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},
"306": {<-----------------------这里已将306号帧复制了两次，但序号还没改，是没有作用的，所以我们要把序号改好
              ······
                "index": 306.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},				
"307": {
              ······
                "index": 307.0,
              ······
				},
"308": {
              ······
                "index": 308.0,
              ······
				}		
······		

↑以上是第一步：复制

······
"305": {
              ······
                "index": 305.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},
"307": {
              ······
                "index": 307.0,<--------------------"index"也要跟着改
              ······
				},
"308": {<--------------------复制出的帧已经改好了序号
              ······
                "index": 308.0,
              ······
				},				
"307": {<--------------------由于前面的帧数量增加，导致这里序号乱掉，因此要手动将其调整好
              ······
                "index": 307.0,
              ······
				},
"308": {
              ······
                "index": 308.0,
              ······
				}		
······	

↑以上是第二步：为复制出的帧改序

······

"305": {
              ······
                "index": 305.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},
"307": {
              ······
                "index": 307.0,
              ······
				},
"308": {
              ······
                "index": 308.0,
              ······
				},				
"309": {
              ······
                "index": 309.0,
              ······
				},
"310": {<--------------------这里往下的所有帧都需要调整好序号
              ······
                "index": 310.0,
              ······
				}		
······	
	
↑以上是第三步：为之后的帧改序			
		
这里我们复制帧是为了延时，同时精细地调整。
如果是已经用了"duration"进行延时的帧，我们也可以进行复制，但要减少"duration"的数值来使帧的总时值保持不变。
例如：

"305": {
              ······
                "index": 305.0,
				"duration": 0.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
				"duration": 5.0,<-------------这一帧的"duration"为5，加上其本身所占的时间，相当于是6帧的时间。
              ······
				},
"307": {
              ······
                "index": 307.0,
				"duration": 0.0,
              ······
				},

复制后：
"305": {
              ······
                "index": 305.0,
				"duration": 0.0,
              ······
				},
"306": {                         \
              ······              \
                "index": 306.0,    \
				"duration": 1.0,	\
              ······				 \
				},					  \
"307": {							   >------------复制后，原本的一帧变为了三帧，帧本身所占的时值也从1增加到了3，因此"duration"的总值不再是5，而是3，和帧本身占的时值加起来还是6。
              ······				  /
                "index": 307.0,      /
				"duration": 1.0,    /
              ······			   /
				},				  /
"308": {          				 /
              ······
                "index": 308.0,
				"duration": 1.0,<--------------"duration"不一定要平均分配，这里分成003、012、111、120、210、030等，都是可以的，具体怎么分配要看具体情况。
              ······
				},		
"309": {<-------------------顺带改掉序号和"index"
              ······
                "index": 309.0,<--------------复制出了两个帧，则序号向后推两位，也就是 +2 。
				"duration": 0.0,
              ······
				},

此外，在复制帧的时候，我们还需要注意一点：如果我们复制的帧为action的最后一帧，既"last"为 true ，那么复制完以后，原本帧的"last"要改成 false ，因为它推迟结束了，只保留最后的那一个 true 。
例如：

"305": {
              ······
                "index": 305.0,
				"last": false,
              ······
				},
"306": {<-------------------复制这一帧两次
              ······
                "index": 306.0,
				"last": true,
              ······
				},
"307": {
              ······
                "index": 307.0,
				"last": false,
              ······
				},

	复制完后：
	
"305": {
              ······
                "index": 305.0,
				"last": false,
              ······
				},
"306": {
              ······
                "index": 306.0,
				"last": true,  		\
              ······				 \
				},					  \
"307": {							   \
              ······					\
                "index": 307.0,          \
				"last": true,			  >------------这里有三个true，action进行的时候，遇到第一个true就会结束，但我们希望让307和308号帧也起作用，这里的 true 自然要改成 false
              ······					 /
				},						/
"308": {							   /
              ······  				  /
                "index": 308.0,		 /
				"last": true,		/
              ······
				},				
"309": {
              ······
                "index": 309.0,
				"last": false,
              ······
				},		
		
	
修改后：

"305": {
              ······
                "index": 305.0,
				"last": false,
              ······
				},
"306": {
              ······
                "index": 306.0,
				"last": false,  		
              ······				 
				},					  
"307": {							   
              ······					
                "index": 307.0,          
				"last": false,			 
              ······					 
				},						
"308": {							   
              ······  				  
                "index": 308.0,		 
				"last": true,		
              ······
				},				
"309": {
              ······
                "index": 309.0,
				"last": false,
              ······
				},	


05、简单参数篇：

frame里还有一些很简单的参数，因为很好理解，所以在这里一笔带过。

"name": "jump_attack",（名称，作为标记，同时也作为其他人物引用贴图的位置，之后有详细讲解）
"vx": 0.0,（人物处于这一帧时，人物的x轴速度）
"vy": 0.0,（人物处于这一帧时，人物的y轴速度）
"attackMany": 5.0,（攻击所击中敌人的最大数量，只对本体攻击起作用）
"footY": 96.0,（站立的高度，越大站得越高，太大的话人物会浮空）
"onGround": true,（是否在地面，若是，则动作完成后进入stand，若不是，则动作完成后进入jump，要根据实际情况来设置）
			




	




四、frame篇：

到了这里，我们就正式开始学习frame了，现在开始的参数不像duration和last一样改个数字就行，要在一个参数内改多个小参数，有一定的难度，
但只要记住各个小参数的作用，同样是很容易理解的。

01、极限篇：

人物的判定，分为离体判定和本体判定，离体判定就是发射的道具，例如飞龙斩、弓箭、烈风钻。
除了承影的技能以外，大部分带道具的技能都是本体判定与离体判定的结合，例如龙介飞龙斩会带有一个很弱的本体攻击，大E升龙霸除了本体的攻击还有一个光柱。
判定不仅仅指攻击判定，防御、受击、被抓起也是一种判定，而这些都属于本体判定，也就是角色自身所发出的，能反馈到角色本身的判定。
而这些本体判定，有一个极限（best），超过这个极限，无论是碰撞、防御、攻击、受击判定都无法起作用，因此在扩大判定范围的时候，我们要同时扩大这个极限。
极限的英文为best，那么x轴极限自然就是bestx，为了简洁，frame里将它表示成bx。
同理可得bz就是z轴极限，by就是y轴极限。
由于xyz轴都是双向的，所以控制xyz极限的参数也各有两个，一共6个："bx1","bx2","bz1","bz2","by1","by2"。

"bx1": x轴的左极限
"bx2": x轴的右极限
"bz1": z轴的上极限
"bz2": z轴的下极限
"by1": y轴的上极限
"by2": y轴的下极限


02、body身体篇：

frame里有一项"body"，是控制人物身体的参数，如果没有body，人物就不会被打中（攻击碰撞除外），也不会被抓，
而body内的参数又决定了人物受击范围的大小，例如三角龙、魔龙的受击范围和碰撞大小要远远大于普通角色
碰撞范围和受击范围是互相独立的，你可以设置一个受击范围很大，但不能碰撞的角色；也可以设置一个碰撞范围很大，但受击范围很小的角色。

"body": {
                    "HFW_ArrayLenXXX": 1,
                    "0": {
                        "HFW_classNameXXX": "Data.Body",
                        "x1": -55.0,<-----------body受击左边界
                        "z1": -30.0,<-----------body受击上边界
                        "x2": 55.0,<------------body受击右边界
                        "g0": 0.0,<-------------正面防御判定，之后详细讲解
                        "z2": 30.0,<------------body受击上边界
                        "y1": -212.0,<----------body受击y轴上边界
                        "cy": -92.0,
                        "y2": 28.0,<------------body受击y轴下边界
                        "w": 110.0,<------------body碰撞体积的左右范围
                        "g1": 0.0,<-------------背面防御判定，之后详细讲解
                        "h": 240.0,<------------body碰撞体积的高
                        "j": 0.0,
                        "cx": 0.0,
                        "l": 1.0,
                        "t": 60.0<--------------body碰撞体积的上下范围
                    }
                },

未注明的参数作用未知，推测作用不大或者没有作用

此外，frame内还有一项"editBody"，是对body进行一定的修正，这个参数已确定是有作用的，但具体作用还未研究清楚。
PS："body"内的位置参数受到bx、bz、by的影响


03、防御判定篇：

人物防御的时候，正面会带有防御判定，而一些特殊技能（例如三巨头自爆蓄力）会同时带有正面和背面的防御判定，这些防御判定其实就是在body内设置的。

body内有两项和防御有关的参数，分别是"g0"和"g1"，"g0"代表正面防御，只要数值改成一个大于0的数字，例如0.1 ，正面就会带上防御判定，背面同理。
原版除莱格以外的人物，有防御判定的帧的"g0"都是0.8 ，莱格是0.9 ，目前还未发现不同数值之间有什么区别，因此设置防御判定的时候，按照普通人物的0.8 就行。
另外，frame内有一个"UseDefBody"的参数，如果需要防御判定，这个参数就要设成 false 。

如果要让整个actiongroup的动作都带上防御判定，还有一种简单的方法，就是修改actiongroup内的"shield0"（正面防御判定）和"shield1"（背面防御判定）
将"shield0"或者"shield1"的数值改成一个大于0的数，然后整个actiongroup下的所有动作的所有帧的body内的"g0"、"g1"就会自动判断成和"shield0"、"shield1"一样的数值
例如，如果将normal这个actiongroup的"shield1"改成0.7 ，然后属于normal的动作，例如stand、run、jump等，它们的所有帧的body的"g1"虽然还是0.0 ，但在实际进行游戏时会被判定成0.7

如果你有仔细观察，会发现人物的防御动作，例如gua_stand、gua_run，它们frame内的"body"的"g0"都是0.0 ，但却拥有正面的防御判定，正是因为在actiongroup里设置了"shield0"




04、attack攻击篇：
	
"attack"是frame内一个重要的参数，控制的是人物的攻击判定。
以下是龙介跑攻第三帧的攻击判定
	
	"attack": {
                    "HFW_ArrayLenXXX": 1,
                    "0": {
                        "HFW_classNameXXX": "Data.Box",
                        "x1": 15.0,<======================攻击判定左边界
                        "y2": -69.0,<======================攻击判定y轴下边界
                        "j": 1.0,
                        "ref": 15.0,<======================使用的攻击判定的序号，作为标记
                        "z2": 40.0,<======================攻击判定下边界
                        "y1": -207.0,<======================攻击判定y轴下边界
                        "refName": "hard",<======================使用的攻击判定的名称，必须填写正确，下一篇会详细解释
                        "x2": 197.0,<======================攻击判定右边界
                        "l": 20.0,
                        "z1": -40.0<======================攻击判定上边界
                    }
                },
	
未注明的参数作用未知，推测作用不大或者没有作用	
	
和body一样，frame里也有一项"editAttack"，是对攻击判定的编辑、修正，具体作用未知，但"editAttack"对"attack"的影响往往是负面的，因此判定范围出问题的时候，删掉"editAttack"可能会解决这个问题。	
PS："attack"内的位置参数受到bx、bz、by的影响	
	
此外，frame内还有两项关于attack的参数，它们分别是"newAttack"、"attackMany"。
"attackMany"是攻击的群伤数量，改成3则最多攻击到三人目标，只对本体判定起作用。
"newAttack"是判定这个攻击是否为新攻击，例如龙介跑攻的226号帧和227号帧都有攻击判定，但对于同一个目标只能产生一次伤害，正是因为227号的帧不是新攻击。
这种攻击可以理解成是一个整体，226号帧和227号帧的"attack"共同构成了一个维持了两帧的攻击，对于已经被攻击中的目标无法再次击中，但可以击中新的目标。
而如果将"newAttack"改成 true ，这一帧的攻击判定就是新攻击，不仅能攻击到新目标，还能击中原本已经击中的目标，杰斯的车轮能持续伤害就是这个原理，此外，"newAttack"设置为 true 的话，"attackMany"会进行重置，之前的旧攻击击中的目标不会算进群伤限制里。
还有一种特殊情况，如果一个攻击持续的时间太长，即使没有"newAttack": true ,它也同样可以击中原本已经被击中的目标。
"newAttack"可能相对较难理解，但只要亲自试验一下，很快就能明白。


05、攻击数据篇：
	
142 - Data.Global_globalDat是存储攻击数据的位置，里面有ptWithName_xxx.json和Attack_xxx.json两种文件（xxx代表序号），ptWithName_xxx.json暂时不用理会。
Attack_xxx.json就是攻击数据，xxx为序号，在"attack"的"ref"里填写的也正是这个序号，角色攻击时的破防、伤害、击飞等数据也是取决于绑定的攻击数据。
例如，第15号攻击：Attack_15.json的内容如下
PS：攻击数据参数的作用介绍来自HFW群—“教程-attack.json”（by 不饿白帝）
{
    "Data.Attack": {
        "hp": 45.0,（该攻击造成的伤害。如果设置为负值则可以为敌人加血。）
        "fall": 200.0,（该攻击的扣除的击倒值。正常英雄角色的击倒值满值为180。）
        "brk": 130.0,（该攻击所扣除的防御值。正常英雄角色防御值满值为180）
        "name": "hard",（该攻击的名字，每个攻击之间名字不可重复，名字是角色绑定伤害时重要的绑定数据）
        "ref": -1.0,
        "z1": 60.0,
        "dizzy": 30.0,（当fall小于180，击晕敌人时造成的晕眩时间，最大为60）
        "x1": 0.0,
        "stun": 2.0,（在击中敌人时，对方动作被定格的时间）
        "x2": 150.0,
        "z2": 0.0,
        "y1": 0.0,
        "type": 0.0,（仅在effect=0或1 时不同的攻击效果）
        "y2": 150.0,
        "selfStun": 2.0,（在击中敌人时，自己动作被定格的时间）
        "effect": 0.0,（攻击种类，下面会全部列出）
        "vx": 33.0,（击飞敌人时，敌人飞出的x轴速度，当vx足够大时，敌人会被旋转击飞（fall_spin1），例：旋风掷）
        "dxMirror": false,（决定攻击方向是否以角色为中心对称，例：白色极光、魔神怒哮为true，攻击方向为双向，魔临天下为false，攻击方向为单向）
        "vy": -40.0,（击飞敌人时，敌人飞出的y轴速度，当vy小于-85时，敌人会被旋转击飞(fall_spin3)，例：魔临天下）
        "i": 15.0,（該攻擊的序號）
        "vz": 0.0,（击飞敌人时，敌人飞出的z轴速度）
        "j": 0.0,
        "dx": 0.0,
        "refName": null,
        "l": 1.0,
        "aaa": true（决定该攻击是否可被碰撞。例：魔临天下为true，因此可被fall与brk都大于自己的升龙击飞白色极光与石破天惊为false，因此可无视fall与brk的规则击飞升龙）
    }
}
没有作说明的都是无关紧要的数据，所有attack中都没有任何变化。
	
此外，fall和brk还有一些特殊作用：

		当fall大于180会将敌人直接击飞，小于180将扣除敌人的击倒值并在数击后使敌人进入晕眩状态，当击倒值为0时可被抓取，直接击飞不扣除击倒值。
        
        当fall=300，为"fallstrong"，在攻击对碰时会将"fall"与"brk"小于自身的本体攻击直接击飞。例：冲锋撞普攻、车轮，魔临天下撞大部分本体攻击 等。
        
        当fall=500，为"fallsuperatk"，在fall=300 的特性基础上，在攻击对碰时自己的防御值不会降低，血量也不会减少。
	
		当brk大于180时，经过防御或攻击对碰，敌人会进入被破防造成的短暂硬直状态。当brk小于180则会扣除对方的防御值。
       
        当brk=500 时，将会无视对方防御直接击飞，并且不会扣除对方防御值。例如：破空
以下是effect的一些可用数值：
		  effect = 0 effectNormal 正常攻击
          
          effect = 1 effectAttackToCatch 抓人攻击
          
          effect = 7 effectAttackItemOnly 仅对item飞行道具起效果的攻击，例如e0升龙蓄力可弹箭、eason使用气功波时可反弹item等。并在攻击对碰时可以起到防御效果。
          
          effect = 9 effectSinanCircle 悬浮攻击，无视fall与brk的规则将敌人悬浮，例：sinan原版的芒星
          
          effect = 100 effectHeal 治疗
          （注：在设置为治疗时，"hp"为回复的血量，"fall"为可回复血量的百分比。
          例如：taylor治疗的fall为50，所以他只能治疗血量少于50%的友军）
          
          effect = 200 成为队友。仅能够将team2的角色转变为team1，为故事中队友设置的原理。
		  
		  effect = 8 effectAttackNonBlastOnly 不能击中攻击型道具的攻击，例如骑兵的突刺、HFE莱格的普攻。
		  
		  effect = 6 effectCanBeStanded 无法击中敌人的攻击，但可以进行攻击碰撞，碰撞时只有己方的brk和hp会减少，可用于模拟body。
		  
		  以下为原版未使用且有bug的攻击类型，使用须谨慎
		  
          effect = 2 effectCatch 强制抓人，触碰到敌人后会抓住敌人并瞬间中止当前动作进入抓人动作，即使brk拼不过对方也能强制抓取，击中item会出错。
		  
		  effect = 3 effectRide 骑乘攻击，击中敌人时会像坐骑一样骑上敌人并将敌人转化为自己的队友，解除骑乘后依然是自己的队友。
		  
		  effect = 4 effectCanBePicked 给道具使用，设置后能被拾起，然后变成石头，石头性质和普通石头有所不同。
		  
		  effect = 5 effectPick 举重攻击，击中重物时会将其举起，击中敌人会出错。
以下是type的一些可用数值：
        type = 0 TypeSword 音效为锐器攻击
        
        type = 1 TypeFist 音效为钝器攻击
        
        type = 2 TypeCatch 音效为抓取攻击
        
        type = 3 TypeBat 效果为吸血攻击
        
        type = 4 TypeIceGuard 暂时未知，疑似与冰之傀儡相关
        
        type = 100 TypeIce 冰冻攻击
        
        type = 101 TypeFire 火烧攻击
        
        type = 102 TypeThunder 雷霆攻击
        
        type = 111 TypeFireInfect 火烧传导
        
        type = 112 TypeThunderInfect 电传导
          
之前有说过，"attack"中的"ref"为攻击的序号，仅仅作为标记，而"refName"才是真正绑定攻击的参数，所以，"ref"设置错误其实并没有影响。
但为了找攻击数据的时候能方便一些，"ref"最好还是写上。

	
06、cre道具篇：	
	
	
人物进行一些动作时，会释放出道具，这些道具是离体判定，因此不受极限（bx、bz、by）的影响。
设置道具的参数为"cre",同样在frame内。
一个帧内可以释放多个道具，没有上限（前提是电脑撑得住），这些道具是同时出现的，而如果想要让它们轮流出现，可以将道具设置进多个不同的帧。
以下是龙介飞龙斩释放的道具，处于323号帧.


"cre": {
                    "HFW_ArrayLenXXX": 1,
                    "0": {
                        "HFW_classNameXXX": "Data.Pt",
                        "sx": 160.0,
                        "ref": 33.0,（设置好的道具模板，对应142中的ptWithName，会用模板内的vx等参数覆盖掉cre内的参数，因此要把"ref"改成负数（不使用模板）才能直接在cre内编辑移速等设定。）
                        "facing": 0.0,（道具面对的方向，0为正面，1为反面）
                        "vx": 45.0,（道具的x轴移动速度）
                        "sy": -10.0,
                        "refName": null,
                        "x": 255.0,（道具相对人物的x轴位置）
                        "o": 0.0,（道具贴图的旋转角度）
                        "y": -121.0,（道具相对人物的y轴位置，注意地面上释放道具最好不要设置成正数，因为部分道具落地会爆炸）
                        "int2": 0.0,（道具发射时的特殊效果，1为无差别或者治疗，2为贴图随着玩家上下按键而旋转，，3为跟随道具，4为分身（须搭配int3），6为增大z轴位移）
                        "vz": 0.0,（道具的z轴移动速度）
                        "j": 1.0,
                        "int3": 0.0,（若int2为4（分身），int3决定了分出的人物，HFW群内有记录）
                        "vy": 0.0,（道具的y轴移动速度）
                        "ai": 2.0,
                        "z": 2.0,（道具相对人物的z轴位置，改成正数贴图会挡住人物，改成负数贴图会被人物挡住）
                        "l": 7.0,
                        "int1": 5.0 （道具对应的序号，不同序号发射不同道具，对应itemspt里的actiongroup，HFW群内有统计各序号对应的道具）
                    }
                },
		
		
龙介的飞龙斩动作的帧为316到330，但只有323有cre，因为他只释放了一个飞龙，如果把323号帧内的cre复制到322号帧和324号帧，龙介就会分别放出三个飞龙斩。
而如果316到330每帧都加上cre，龙介在使用飞龙斩时就会持续放出飞龙斩。
要给没有道具的技能加道具时，我们可以到有释放道具的帧内复制出cre给要加道具的技能的帧。
但是，一个技能有那么多帧，要加到哪个帧最合适？难道要一个一个试？
并不需要，接下来我会分享一些寻找“关键帧”的方法。

07、寻找关键帧篇：

有时候，我们想给技能加道具，却不知道要加到哪个帧，想要给人物加上攻击判定或者位移，却不知道加到哪里合适。
而一些适合加道具、加位移、加判定的帧，我们暂且称它为“关键帧”。要加的内容不同，“关键帧”的位置自然也不同。

一、目测估计法

通过对当前帧在所有帧中所处的位置及当前帧的"duration"的观察，直接得出关键帧。
新手比较难驾驭，仅适合用于自爆等长时间停顿的技能。

二、攻击判定法

攻击判定出来时，角色的武器往往也刚挥出去，这个时候加道具的效果是很好的。
我们可以选择在攻击判定出现的前一帧，或者攻击判定出现的那一帧加入道具，这样就像是角色把道具挥出来了一样。

三、观察位移法

通过观察frame内的vx、vy等参数而得出当前帧内角色的状态。
例如，褚英轰天拳技能的每个帧的x轴位移（vx）如下：
14,14,14,0,0,0,0,0,0,0,0,37,0,37,0,0,0,0
可以很直观地看到，前三帧是起手动作，而4到11号帧是蓄力动作（无位移），12号帧是蓄力完成后开始挥拳的动作，14号帧是拳头挥出去的动作，后四帧是拳头停顿动作以及收尾动作。

四、逐个击破法

如果前面几种方法都不管用，还有最终的方法-逐个击破。
我们只要记录下每一帧的动作，自然就能找出最合适的帧。
但帧进行的速度太快，要记录下每一帧来并不容易，因此，我们可以利用"duration"
将技能的"duration"改成20或者更高，每一帧的速度就会很慢，就可以慢慢地截图，观察，截图的同时记录下当前帧的位置，最终得出合适的帧。

08、贴图入门篇：
如果说，frame是Spt里最重要的内容，那么贴图就是frame中最重要的内容,本篇将简单介绍一些贴图相关的参数。

"effect":此帧贴图的颜色效果，有1，2，3（冰）、10，11（火）、20，21（雷），会改变人物贴图的颜色，例如fall_ice。
"uz":控制贴图数据的参数，人物贴图在此处设置。
"refIndex":引用某一帧"uz"的数据，同时显示位置和显示范围也是按照被引用的那一帧为准。
"index":序号，当refindex指向此帧时，实际被引用的是此帧的"index"所指向的那一帧的贴图数据，因此要保证"index"和实际序号相同。

"r1":此帧贴图的缩放倍率，数值越大贴图就越大，是巨人的制作原理。
"lz":下身贴图，同样是控制贴图的参数，但较少使用，一般会将身体的上下两部分同时放到"uz"，但用得好可以做出有趣的动作，所以mod版本经常会用到。
"refIndex_2":引用某一帧"lz"的数据，同时显示位置和显示范围也是按照被引用的那一帧为准。
"lowAtBottom":下身贴图是否在底部，之后详细解释。
"ULseparate":上下身贴图分离，之后会详细解释。
"lp1":对引用的贴图进行缩放、旋转、整体移动等操作。


五、frame进阶篇

若理解透以上所有知识，你在HFW界就有一定的地位了，相当于vs的二线玩家，道具、攻击、位移都难不倒你。
但若要成为HFW界的强者，还需要经历贴图的考验，要理解透贴图不是一件容易的事，所以接下来的学习要有耐心。
学习贴图的知识之前，建议先搞清楚皮肤绑定的原理，否则很难理解，就算理解了也难以应用。
这里不再讲解皮肤绑定的知识，可自行翻阅其他资料。

01、贴图设置篇：
"uz"内贴图的数量一般有10到20个，这里减少到两个，方便阅览。
"uz": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 1.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 1.094973516681288,
                            "b": 0.29339726952821754,
                            "c": -0.2903949686050283,
                            "tx": -3.559217632682902,
                            "d": 1.0837687770963347,
                            "ty": -3.941936243722864
                        },
                        "x": 0.0,
                        "p": 2.0,
                        "y": 0.0
						},
                    "1": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 0.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": -0.974959675482086,
                            "b": 0.1719116958902611,
                            "c": 0.1719116958902611,
                            "tx": 64.04427819315168,
                            "d": 0.974959675482086,
                            "ty": -28.433773789806907
                        },
                        "x": 0.0,
                        "p": 17.0,
                        "y": 0.0
						}
                    }


可以看到，"uz"内的参数里有"i","m","x","p","y"五个参数。

其中，"i"对应的是绑定的贴图序号，我们可以先回到贴图绑定的位置观察
"spriteLimb": {
            "HFW_ArrayLenXXX": 45,
            "0": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_00Head",
                "limbType": 0.0,
                "xScale": 0.99,
                "limb": null,
                "yScale": 0.99,
                "limbTypeName": null
            },
            "1": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_01Chest",
                "limbType": 1.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },
			···
			···
			}
可以看到，0号对应的是头部贴图，1号对应的是身体贴图。
而"i": 0.0 自然就是设置的头部贴图

而"p",则是在确认了"i"的情况下，控制显示出的是"i"的贴图组内的哪张贴图。
例如龙介"i": 0.0 "p": 1.0 对应的是常态的头部贴图，而"i": 0.0 "p": 9.0 为被打时的头部贴图

"x"和"y"为贴图在x轴和y轴上的动感模糊，数值越大越模糊，此外如果"x"改为-10.0 还会触发滤色效果。
"m"则是对贴图进行再次编辑
"m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 1.094973516681288,（贴图的长度，或者说是x轴的缩放比例）
                            "b": 0.29339726952821754,（贴图的斜切角度）
                            "c": -0.2903949686050283,（贴图的旋转角度）
                            "tx": -3.559217632682902,（贴图的x轴位置）
                            "d": 1.0837687770963347,（贴图的宽度，或者说是y轴的缩放比例）
                            "ty": -3.941936243722864 （贴图的y轴位置）
                        },

其中，"a","b","c","d"四个参数是不作任何修改的，因为一旦进行修改，贴图的位置就会发生变化，要手动修改位置才能变回正常。
tx、ty一般在扩充显示范围的时候进行修改。

02、贴图显示篇：

人物贴图的显示有范围的限制，所以一些皮肤会显示不全，同时，一些改了贴图的新技能也会显示不全。
为了解决这个问题，我们就要搞懂贴图显示的知识。


在frame内有四个参数控制贴图的显示：
"cx1": 贴图显示左边界
"cx2": 贴图显示右边界
"cy1": 贴图显示上边界
"cy2": 贴图显示下边界

如此说来，要扩大贴图的显示范围，只需要将"cx1"和"cy1"的数值减小，并增大"cx2"和"cy2"的数值就好了啊？这有何难？

不对不对，你们全都搞错了（摇手指）。
贴图的显示位置，是以"cx1"和"cy1"为基准进行计算的，也就是说，如果"cx1"减100（左移100个单位），那么虽然边界向左移动了100个单位，但贴图的显示位置也跟着往左移动了100个单位，不仅没有起到扩充的效果，还导致贴图位置错误。
因此，我们要修改"uz"内的"tx"来使贴图恢复原来的位置，这样一来，边界向左移动了，但贴图还在原位，显示范围自然就扩大了。
"tx"和"cx1"数值的改变量造成贴图移动的距离原本是完全相等的，"cx1"增加100会使贴图向右移动100个单位，"tx"增加100同样会使贴图向右移动100个单位，位置的改变量是一样的。
不过，大部分的frame都对贴图进行的缩放，控制缩放的数值为"r1"，所以，修改"tx"时，实际的效果还会受到"r1"的影响。

但这个影响非常好计算，只需要将"tx"乘上"r1"的数值即可。例如，某一帧内"r1"为2.0 此时若"tx"的数值增加100，实际上是使贴图向右移动了200个单位，而要想让它只移动100个单位，"tx"增加的数值要换成50。
所以，扩充贴图显示范围时，要注意"r1"的数值，值得庆幸的是，原版角色的"r1"只有三种数值：1.0 、2.0 、4.0 
其中，1.0 是站立帧和一些废弃帧才会用到的数值，如果你仔细观察的话，会发现角色站立时的贴图比其他动作的贴图要清晰很多，因为站立贴图原本就是这个大小，而其他贴图原本没有这个大小，是通过"r1"放大到这个大小，所以比较模糊。
4.0 则是只有fall_spin会用到的数值，仔细观察会发现fall_spin的贴图非常模糊。
而2.0 则是除了站立和fall_spin以外所有帧的"r1"值。

假设要往左扩充100个单位的显示范围，我们需将"cx1"减少100，此时再把此帧"uz"内所有"tx"加上（100/r1）的数值，例如若"r1": 2.0 ，则"tx"增加的值为（100/2 ）= 50
值得注意的是，若"r1"经过人为修改（例如巨人），"tx"改变量的计算需以"r1"的原数值（修改前数值）为准

"cy1"和"cx1"同理，不再赘述，而"cx2"和"cy2"不会影响显示位置，因此可以直接增加。
但要注意不能增加太多，一般要把整体扩充的量控制在200以内，单个帧扩充的量控制在400以内。（其实，对于一般的皮肤来说，四个方向各扩充100就已经绰绰有余了）
若需要较大的贴图，我们可以先设置出小的贴图，然后将其放大。

然而，一个角色有几百个帧，一帧有十几二十个"tx"，若要一个一个改，得改个上万次，因此，扩充贴图的显示范围一般直接使用工具。
我已制作出了“贴图显示范围扩充工具”，到HFW群可以下载到，此工具在修改"tx"的时候会自动把"r1"算上，只需输入扩充的范围即可一键扩充。
虽然现在已经有了工具，但我仍希望大家能理解清楚显示范围的原理，以备以后学习更深奥的知识。

03、贴图分离篇：

在frame内，除了"uz"以外，还有一个名为"lz"的参数。
"lz"的本意是下身贴图，但实际上并不仅限于下身贴图，可以将它理解成一个额外的贴图存放点。

将贴图分离，虽然内容没有改变，但也有很大的意义。
例如，你可以将跳跃时的腿部贴图与地面技能的上身贴图结合，这样就能做出一些新的空中动作，例如轰地拳（空中轰天拳）、空中雷炮等。
另外，分离后可将上身或下身贴图单独进行旋转，达到向斜上方攻击/斜下方攻击的效果。

要使用"lz"，我们要先修改一个参数："ULseparate"
将"ULseparate"改成true，"lz"内的贴图才会被显示，否则不会理睬。同时，若"lz"内没有贴图，应将"ULseparate"设为false，否则会触发bug

"lz"和"uz"是可以互相移植的，但要注意显示位置。（之后会讲解移植方法）
"lz"的显示和"uz"显示参数的原理完全一样，但它们的显示参数并不共用。
"lz"采用了一套新的参数来控制显示范围，它们分别是"cx1_2","cx2_2","cy1_2","cy2_2"
"cx1_2"对应"cx1","cx2_2"对应"cx2","cy1_2"对应"cy1","cy2_2"对应"cy2"
两套显示参数采用完全相同的算法，但它们互相独立，互不干扰。

要分离贴图，我们需要将frame内"cx1_2"等参数的数值改成和"cx1"一样，然后将"uz"内的部分数据直接移植到"lz"，然后将这部分数据从"uz"删除。
此外，因为部分贴图分离到了"lz"，"ULseparate"需要改成true，分离出的这部分贴图才会生效。

举个例子：
以下是刃逊attack1的第三帧，这一帧的贴图本身是没有分离的。
我们先来观察一下这帧的内容，为了简洁我删掉了无关的参数（例如attack）。

"181": {
                "HFW_classNameXXX": "Data.Frame",
                "lowAtBottom": false,
                "ULseparate": false,
                "uz": {
                    "HFW_ArrayLenXXX": 3,（此处将贴图数量减少到三个以便阅览）
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 1.0864571746546516,
                            "b": 0.17207791154425398,
                            "c": -0.17989963479626547,
                            "tx": 6.765972909367832,
                            "d": 1.1358415916844085,
                            "ty": 24.36529215566813
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 0.0
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 10.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.855819112405483,
                            "b": -0.8862266340172167,
                            "c": 0.34636211386306054,
                            "tx": -5.9865019031373095,
                            "d": 0.3344780053760072,
                            "ty": 80.56685327497604
                        },
                        "x": 9.0,
                        "p": 0.0,
                        "y": 0.0
                    },
                    "2": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 11.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": -0.5444722215136419,
                            "b": -0.5444722215136417,
                            "c": 1.022829958986336,
                            "tx": 43.126585347878915,
                            "d": -1.0228299589863366,
                            "ty": 137.40958124651252
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 16.0
                    }
                },
				"cx1": 444.0,（原本贴图的贴图显示范围）
				"cx2": 655.0,
				"cy1": 250.0,
                "cy2": 505.0,
				"cx1_2": -1.0,（没有贴图自然也不需要显示，所以显示范围均为-1 ）
                "cx2_2": -1.0,
				"cy1_2": -1.0,
                "cy2_2": -1.0,
				"lz": null,（原本没有分离贴图，所以"lz"为空）
            },
            
假设我们需要将"i": 10.0 和 "i": 11.0 的贴图分离到"lz"，
经过处理后，得到以下代码。

"181": {
                "HFW_classNameXXX": "Data.Frame",
                "lowAtBottom": false,
                "ULseparate": false,
                "uz": {
                    "HFW_ArrayLenXXX": 3,
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 1.0864571746546516,
                            "b": 0.17207791154425398,
                            "c": -0.17989963479626547,
                            "tx": 6.765972909367832,
                            "d": 1.1358415916844085,
                            "ty": 24.36529215566813
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 0.0
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.LZ",（删去贴图数据往往会改变原有的排序，导致分离的过程麻烦很多，所以这里并没有直接将贴图数据删去）
                        "i": -10.0,（但是要保证分离出去的贴图在"uz"内不再生效，所以我们可以将原本的"i": 10.0 改成负数，代表其为无效值，贴图就不会显示）
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.855819112405483,
                            "b": -0.8862266340172167,
                            "c": 0.34636211386306054,
                            "tx": -5.9865019031373095,
                            "d": 0.3344780053760072,
                            "ty": 80.56685327497604
                        },
                        "x": 9.0,
                        "p": -1.0,（当然把"p"改成负数也可以达到让贴图不显示的效果）
                        "y": 0.0
                    },
                    "2": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": -11.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",（这个负数可以是原数值的相反数，也可以是任意负数，例如-1 ，但我建议改成原数值的相反数，这样一来，之后若要将分离的贴图还原，就能轻松的将"i"改回原数值）
                            "a": -0.5444722215136419,
                            "b": -0.5444722215136417,
                            "c": 1.022829958986336,
                            "tx": 43.126585347878915,
                            "d": -1.0228299589863366,
                            "ty": 137.40958124651252
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 16.0
                    }
                },
				"cx1": 444.0,
				"cx2": 655.0,
				"cy1": 250.0,
                "cy2": 505.0,
				"cx1_2": 444.0,（将"lz"的显示范围全部改成和"uz"的显示范围一样的值）
                "cx2_2": 655.0,
				"cy1_2": 250.0,
                "cy2_2": 505.0,
                "lz": {
                    "HFW_ArrayLenXXX": 2,（"i": 10.0 和"i": 11.0 的贴图已复制到"lz"，由于显示范围设成了和"uz"一样的数值，所以移植后不需要对"lz"内的数据进行任何修改（当然序号除外））
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 10.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.855819112405483,
                            "b": -0.8862266340172167,
                            "c": 0.34636211386306054,
                            "tx": -5.9865019031373095,
                            "d": 0.3344780053760072,
                            "ty": 80.56685327497604
                        },
                        "x": 9.0,
                        "p": 0.0,
                        "y": 0.0
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 11.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": -0.5444722215136419,
                            "b": -0.5444722215136417,
                            "c": 1.022829958986336,
                            "tx": 43.126585347878915,
                            "d": -1.0228299589863366,
                            "ty": 137.40958124651252
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 16.0
                    }
                }
            },
			
移植完后，可以通过修改"lowAtBottom"来控制下身贴图是否在底部，若改成 true 则下身贴图会被上身贴图所覆盖，否则下身贴图会覆盖上身贴图。
这些过程都已经用工具实现，HFW群里有“上下身贴图分离工具”，只需要输入要分离的帧的范围，工具就能将这些帧自动分离并设置好相关参数。
但若想精益求精，应该理解清楚它的原理，理解透原理后，就可以利用"lz"做出更神奇的事情，而不仅仅是分离贴图。


04、贴图移植篇：

众所周知，原版龙奥并没有绑定披风，超级龙介的动作和龙奥完全一样，同时拥有披风绑定。
所以，如果将超级龙介的披风数据移植到龙奥的Spt，龙奥就会拥有披风。
不过，超级龙介和龙奥每一帧的显示位置（"cx1"和"cy1"）不一样，因此，直接移植会导致错位。

这时候，就会用到我们接下来要学习的知识-贴图移植。
所谓贴图移植，就是将一帧内的一个或多个贴图数据，移植到另一帧。

举个例子：

"102":
  {
    "cx1": 200.0,
    "cy1": 100.0
    "uz": {
                    "HFW_ArrayLenXXX": 1,
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.9205048534524404,
                            "b": 0.39073112848927377,
                            "c": -0.386823817204381,
                            "tx": 22.464704088149944,
                            "d": 0.911299804917916,
                            "ty": 7.717228700728185
                        },
                        "x": 0.0,
                        "p": 2.0,
                        "y": 0.0
                    }
                  }
},
"103":
  {
    "r1": 2.0,
    "cx1": 300.0,
    "cy1": 150.0
    "uz": {
                    "HFW_ArrayLenXXX": 0
                  }
    }

可以看到，上面有两个frame，若我们想将102号frame的贴图移进103号frame，就会用到贴图移植。
"103":
  {
    "r1": 2.0,
    "cx1": 300.0,
    "cy1": 150.0,
    "uz": {
                    "HFW_ArrayLenXXX": 1,
                     "0": {(<----------先将贴图原封不动地复制过来)
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.9205048534524404,
                            "b": 0.39073112848927377,
                            "c": -0.386823817204381,
                            "tx": 22.464704088149944,
                            "d": 0.911299804917916,
                            "ty": 7.717228700728185
                        },
                        "x": 0.0,
                        "p": 2.0,
                        "y": 0.0
                    }
                  }
 }
同时我们可以看到，102号frame的cx1为200，103号的cx1为300，这使得此贴图的位置向右边移动了100个单位。
所以我们要把这100个单位左移，也就是-100，可以用uz内的tx来实现。
算上r1对贴图位置改变量的影响，"tx"实际减少的数值应该是100/2=50。


"103":
  {
    "r1": 2.0,
    "cx1": 300.0,
    "cy1": 150.0,
    "uz": {
                    "HFW_ArrayLenXXX": 1,
                     "0": {(<----------先将贴图原封不动地复制过来)
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.9205048534524404,
                            "b": 0.39073112848927377,
                            "c": -0.386823817204381,
                            "tx": -27.54,（不用计算的太精密，误差控制在1以内就行。）
                            "d": 0.911299804917916,
                            "ty": -17.29 （ty同样需要减少）
                        },
                        "x": 0.0,
                        "p": 2.0,
                        "y": 0.0
                    }
                  }
 }

05、fSpec篇：

fSpec是frame内一个重要的参数，对人物的技能性质有着很大的影响。
fSpec的修改其实非常简单，只需要改个数字就行，但由于涉及到一些其它概念，想要用好还是有一定难度的，所以放到后面讲。


人物fSpec的值的作用：

0：普通frame，无效果。
1：z轴速度清零，若全程设置1则全程无z轴速度。
2：令发射出的跟踪道具拥有跟踪的效果，否则即使是跟踪道具也不会跟踪，对普通道具无效，只有在技能中设置才有效。（例如承影箭雨）
20：受到道具的攻击时，道具对自身的破防减半，例如原版旋风盾。
30：令角色当前x轴速度减半。
40：令角色当前x轴速度清零。
50：无摩擦力，速度不会自动降低，例如赤木火焰拳。
80：受到不可碰撞的攻击时，此攻击的破防降低，同时在较远处发生攻击碰撞时受到的破防降低，为原版莱格攻击的性质。

六、高级技巧篇：

拥有了以上的知识，你就可以做出很多有趣的角色了，而接下来要讲的是一些高级的技巧，可以让你如虎添翼。
当然，学习接下来的知识的前提是对之前的知识已经熟练掌握，否则很难理解清楚。

01、变身动作篇：

很多玩家都幻想过龙介在实战中变身为超级龙介的情景，而利用HFW，我们可以将它真正实现。
变身有两种制作方法，第一种是将变身后的站立、移动等动作全部做成技能，再通过按键和nextAi连接，CW中的超龙和zous的变身就是这么实现的。
不过，由于设置起来较麻烦，且变身后不能像常态一样操作，所以现在一般不再使用这种方法制作变身人物。
第二种方法是利用actionGroup，之前有说过，一个actionGroup对应人物的一个状态，那么如果将站立状态的actionGroup复制一下，就有了一个新的状态，再对这个actionGroup进行修改，就实现了变身。
但这么做也有一定的缺点，就是变身后的人物不能防御或骑乘，抓人和举重则会导致角色解除变身，角色被抓也会导致解除变身。
但总的来说，这种方法实现的变身可以像常态那样正常操作，所以问题不大。

在原版HF中，0到4号actionGroup都有各自的具体作用，而5到9号actionGroup并没有经过特别的设置，因此我们可以将变身后的动作放到5到9号actionGroup里。
事实上，直接新增一个10号actionGroup也和5到9号没有任何区别，因为原版游戏并没有对5到9号actionGroup进行设定。
所以，一个角色理论上可以有无数个变身状态，也就是说，你可以把整个游戏的全部角色都作为一个角色的变身出场，比较典型的例子就是HFT的模仿者，可以变身为刃逊，龙奥，利佛魔，雷殷。

以下是龙介站立状态的actionGroup。

"0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "ite_atk2": -1.0,
                "ite_lifeTime": 0.0,
                "ite_vo": 0.0,
                "ite_lo": 0.0,
                "keyTriggerRef": null,
                "index": 0.0,
                "ite_atkName2": "",
                "ite_atk1": -1.0,
                "ite_sfx2": 0.0,
                "name": "normal",
                "ite_sfx1": 0.0,
                "shield1": 0.0,
                "keyTrigger": null,
                "ite_weight": 1.0,
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": 1.0,(0号ai对应stand动作)
                        "1": 2.0,
                        "2": -1.0,
                        "3": -1.0,
                        "4": 3.0,
                        "5": -1.0,
                        "6": -1.0,
                        "7": 13.0,
                        "8": 6.0,
                        "9": 6.0,
                        "10": 7.0,
                        "11": 7.0,
                        "12": 8.0,
                        "13": 6.0,
                        "14": 6.0,
                        "15": 14.0,
                        "16": 16.0,
                        "17": 15.0,
                        "18": 17.0,
                        "19": 8.0,
                        "20": 4.0,
                        "21": 5.0,
                        "22": 9.0,
                        "23": 10.0,
                        "24": -1.0,
                        "25": 8.0,
                        "26": -1.0,
                        "27": -1.0,
                        "28": 6.0,
                        "29": 8.0,
                        "30": 109.0
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                        "1": 19.0,
                        "2": 22.0,
                        "3": 20.0,
                        "4": 21.0,
                        "5": 22.0,
                        "6": 28.0,
                        "7": 29.0,
                        "8": 30.0,
                        "9": 31.0,
                        "10": 32.0,
                        "11": 33.0,
                        "12": 38.0,
                        "13": 39.0,
                        "14": -1.0,
                        "15": -1.0,
                        "16": 36.0,
                        "17": 37.0,
                        "18": -1.0,
                        "19": -1.0,
                        "20": -1.0,
                        "21": -1.0,
                        "22": -1.0,
                        "23": -1.0,
                        "24": -1.0,
                        "25": -1.0,
                        "26": 40.0,
                        "27": 41.0,
                        "28": 42.0,
                        "29": 11.0,
                        "30": -1.0,
                        "31": -1.0,
                        "32": -1.0,
                        "33": 34.0,
                        "34": 8.0,
                        "35": -1.0,
                        "36": -1.0,
                        "37": 4.0,
                        "38": 4.0,
                        "39": 12.0,
                        "40": -1.0,
                        "41": -1.0,
                        "42": -1.0,
                        "43": 35.0,
                        "44": -1.0,
                        "45": 43.0,
                        "46": 44.0,
                        "47": 43.0,
                        "48": -1.0,
                        "49": 23.0,
                        "50": 24.0,
                        "51": 26.0,
                        "52": 25.0,
                        "53": 27.0,
                        "54": -1.0,
                        "55": 106.0,
                        "56": 107.0,
                        "57": 108.0
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        "1": 74.0,
                        "2": 75.0,
                        "3": 76.0,
                        "4": 73.0,
                        "5": 73.0,
                        "6": 73.0,
                        "7": 77.0,
                        "8": 77.0,
                        "9": 77.0,
                        "10": 77.0,
                        "11": 78.0,
                        "12": 78.0,
                        "13": 78.0,
                        "14": 78.0,
                        "15": 77.0,
                        "16": 76.0,
                        "17": -1.0,
                        "18": -1.0
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0
                    }
                },
                "keyTriggerRefIndex": -1.0,
                "speedXRate": 1.0,
                "shield0": 0.0,
                "ite_reboundable": false,
                "ite_standable": false,
                "speedYRate": 1.0,
                "ite_blastBreak": true,
                "ite_gr": 1.0,
                "piece": null,
                "ite_landBreak": true,
                "ite_dura": 0.0,
                "ite_obstacle": false,
                "ite_screen": false,
                "ite_hitable": true,
                "ite_atkName1": "",
                "action": null,(忽略)
                "ite_duraD": 0.0,
                "type": 0.0,
                "mpBurn": 0.0
            },

我们直接将它复制到5号actionGroup内。
然后找到stand对应的action，然后将它复制到action最后面，命名为EX_STAND，再修改对应frame即可。

"110": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextActionName": null,
                "aix1": 0.0,
                "allowTurnFace": true,
                "nextAi": -1.0,
                "aix2": 0.0,
                "nextAti": -1.0,
                "aix1b": 0.0,
                "frameIndex": 5.0,（需自行添加变身后stand的frame，这里我们先用走路的frame测试）
                "nextAgi": -1.0,
                "aix2b": 0.0,
                "index": 1.0,
                "landActionName": null,
                "aiz1": 0.0,
                "landAi": -1.0,
                "name": "EX_STAND",
                "landAti": -1.0,
                "landAgi": -1.0,
                "aiz2": 0.0,
                "special": -1.0,
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "gua",
                        "atf": false,
                        "ai": 0.0,
                        "kr": "gua",
                        "ati": 3.0,
                        "hp": 0.0,
                        "agi": 0.0,
                        "mp": 300.0,
                        "rkt": false
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "gra",
                        "atf": true,
                        "ai": 3.0,
                        "kr": "gla",
                        "ati": 3.0,
                        "hp": 0.0,
                        "agi": 0.0,
                        "mp": 60.0,
                        "rkt": false
                    }
                },
                "frame": null,
                "type": -1.0,
                "mpBurn": 0.0
            },



"5": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "ite_atk2": -1.0,
                "ite_lifeTime": 0.0,
                "ite_vo": 0.0,
                "ite_lo": 0.0,
                "keyTriggerRef": null,
                "index": 0.0,
                "ite_atkName2": "",
                "ite_atk1": -1.0,
                "ite_sfx2": 0.0,
                "name": "exA",
                "ite_sfx1": 0.0,
                "shield1": 0.0,
                "keyTrigger": null,
                "ite_weight": 1.0,
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": 110.0,(新增action后，对应上新的action即可)
                        "1": 2.0,
                        "2": -1.0,
                        "3": -1.0,
                        "4": 3.0,
                        "5": -1.0,
                        "6": -1.0,
                        "7": 13.0,
                        "8": 6.0,
                        "9": 6.0,
                        "10": 7.0,
                        "11": 7.0,
                        "12": 8.0,
                        "13": 6.0,
                        "14": 6.0,
                        "15": 14.0,
                        "16": 16.0,
                        "17": 15.0,
                        "18": 17.0,
                        "19": 8.0,
                        "20": 4.0,
                        "21": 5.0,
                        "22": 9.0,
                        "23": 10.0,
                        "24": -1.0,
                        "25": 8.0,
                        "26": -1.0,
                        "27": -1.0,
                        "28": 6.0,
                        "29": 8.0,
                        "30": 109.0
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                        "1": 19.0,
                        "2": 22.0,
                        "3": 20.0,
                        "4": 21.0,
                        "5": 22.0,
                        "6": 28.0,
                        "7": 29.0,
                        "8": 30.0,
                        "9": 31.0,
                        "10": 32.0,
                        "11": 33.0,
                        "12": 38.0,
                        "13": 39.0,
                        "14": -1.0,
                        "15": -1.0,
                        "16": 36.0,
                        "17": 37.0,
                        "18": -1.0,
                        "19": -1.0,
                        "20": -1.0,
                        "21": -1.0,
                        "22": -1.0,
                        "23": -1.0,
                        "24": -1.0,
                        "25": -1.0,
                        "26": 40.0,
                        "27": 41.0,
                        "28": 42.0,
                        "29": 11.0,
                        "30": -1.0,
                        "31": -1.0,
                        "32": -1.0,
                        "33": 34.0,
                        "34": 8.0,
                        "35": -1.0,
                        "36": -1.0,
                        "37": 4.0,
                        "38": 4.0,
                        "39": 12.0,
                        "40": -1.0,
                        "41": -1.0,
                        "42": -1.0,
                        "43": 35.0,
                        "44": -1.0,
                        "45": 43.0,
                        "46": 44.0,
                        "47": 43.0,
                        "48": -1.0,
                        "49": 23.0,
                        "50": 24.0,
                        "51": 26.0,
                        "52": 25.0,
                        "53": 27.0,
                        "54": -1.0,
                        "55": 106.0,
                        "56": 107.0,
                        "57": 108.0
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        "1": 74.0,
                        "2": 75.0,
                        "3": 76.0,
                        "4": 73.0,
                        "5": 73.0,
                        "6": 73.0,
                        "7": 77.0,
                        "8": 77.0,
                        "9": 77.0,
                        "10": 77.0,
                        "11": 78.0,
                        "12": 78.0,
                        "13": 78.0,
                        "14": 78.0,
                        "15": 77.0,
                        "16": 76.0,
                        "17": -1.0,
                        "18": -1.0
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0
                    }
                },
                "keyTriggerRefIndex": -1.0,
                "speedXRate": 1.0,
                "shield0": 0.0,
                "ite_reboundable": false,
                "ite_standable": false,
                "speedYRate": 1.0,
                "ite_blastBreak": true,
                "ite_gr": 1.0,
                "piece": null,
                "ite_landBreak": true,
                "ite_dura": 0.0,
                "ite_obstacle": false,
                "ite_screen": false,
                "ite_hitable": true,
                "ite_atkName1": "",
                "action": null,(忽略)
                "ite_duraD": 0.0,
                "type": 0.0,
                "mpBurn": 0.0
            },

设置好后，我们设置一个按键进行变身。

"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextActionName": null,
                "aix1": 0.0,
                "allowTurnFace": true,
                "nextAi": -1.0,
                "aix2": 0.0,
                "nextAti": -1.0,
                "aix1b": 0.0,
                "frameIndex": 0.0,
                "nextAgi": -1.0,
                "aix2b": 0.0,
                "index": 1.0,
                "landActionName": null,
                "aiz1": 0.0,
                "landAi": -1.0,
                "name": "EX_STAND",
                "landAti": -1.0,
                "landAgi": -1.0,
                "aiz2": 0.0,
                "special": -1.0,
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "gua",
                        "atf": false,
                        "ai": 0.0,
                        "kr": "gua",
                        "ati": 3.0,
                        "hp": 0.0,
                        "agi": 0.0,
                        "mp": 300.0,
                        "rkt": false
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "gra",
                        "atf": true,
                        "ai": 3.0,
                        "kr": "gla",
                        "ati": 3.0,
                        "hp": 0.0,
                        "agi": 0.0,
                        "mp": 60.0,
                        "rkt": false
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "guj",
                        "atf": true,
                        "ai": 0.0,
                        "kr": "guj",
                        "ati": 0.0,
                        "hp": 0.0,
                        "agi": 5.0,（变身状态设置在了5号actionGroup，因此按键设置5号agi，也可以另外做个变身技能，然后用nextAgi转到变身）
                        "mp": 450.0,
                        "rkt": false
                    }
                },
                "frame": null,
                "type": -1.0,
                "mpBurn": 0.0
            },

02、变身贴图篇：

部分角色变身后贴图保持不变（例如兵头四），此时不需要对贴图进行设置。
之后的新角色也可能会出现改变少量贴图的情况，例如变身后只改变武器，我们只要在spriteLimb内空的地方绑定个新的武器，然后修改变身后frame的贴图中的"i"即可。

但还有一种情况，就是变身后需要改变大量贴图（例如模仿者），此时贴图的设置就比较麻烦。
但也不是没有办法，我们可以在spriteLimb中新增绑定。

"44": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limb": null,
                "limbName": "weapon_effect_white",
                "limbTypeName": null,
                "xScale": 1.0,
                "limbType": 44.0,
                "limbNames": {
                    "HFW_ArrayLenXXX": 0,
                    "b": "weapon_effect_white",
                    "a": "weapon_effect_white",
                    "c": "weapon_effect_white",
                    "d": "weapon_effect_white",
                    "e": "weapon_effect_white",
                    "f": "weapon_effect_white"
                },
                "yScale": 1.0,
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                }
            }

原版所有角色的贴图绑定都是到44号，因此，我们可以将变身后人物所用到的0号贴图改成45号,就像这样。

        "44": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limb": null,
                "limbName": "weapon_effect_white",
                "limbTypeName": null,
                "xScale": 1.0,
                "limbType": 44.0,
                "limbNames": {
                    "HFW_ArrayLenXXX": 0,
                    "b": "weapon_effect_white",
                    "a": "weapon_effect_white",
                    "c": "weapon_effect_white",
                    "d": "weapon_effect_white",
                    "e": "weapon_effect_white",
                    "f": "weapon_effect_white"
                },
                "yScale": 1.0,
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                }
            },
        "45": {（这里把盗贼的头部贴图从0号改成了45号并加进了龙介spt里。）
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limb": null,
                "limbName": "z_bandit01_00Head",
                "limbTypeName": null,
                "xScale": 1.0,
                "limbType": 0.0,
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "yScale": 1.0,
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                }
            },

以此类推，1号的身体改成46号，20号的武器改成65号……

之后到frame里将全部"i"替换即可。

这些设置手动完成的话会非常麻烦，特别是像模仿者这种有多个变身状态的角色。
所以我制作了能一键设置变身的工具，将在不久后发布。

03、变身妙用篇：

接下来我们来讲讲变身功能的特殊玩法。

1、强制变身、强制解除变身。

有的时候，我们需要一个角色位置来放新增的角色，但当前所有角色位置的角色都还有用，这时候变身功能就派上了用场。
利用变身功能，可以将一个角色设置成另一个角色的变身，这样就空出了一个角色位置。

当然，这么做肯定是有缺点的，变身角色无法防御、骑乘、举重、抓人，因此我们可以优先挑选步兵这种本就不能骑乘、举重、抓人的角色来设置变身。
而对于一些贴图位置相同且体型接近的角色（例如HFE戈登和索思），我们可以令角色在变身时不改变贴图，然后在故事内通过皮肤来设置贴图。

那么，强制变身该如何实现呢？我们可以利用按键。

com在释放技能时，实际上也是需要进行按键的，只不过按键所需的时间极短。
如果我们将按键数量设置为1，例如a、j、g、u、d、l、r，com在按下这些按键的时候就会强制触发按键，对玩家也是如此。
我们可以设置一个按键"a"，这样一来，com一旦想要进行攻击，就会强制触发按键，然后我们可以将这个按键指向的动作设置成变身站立的动作。
而如果将七个基础按键全部设置一遍，那么com无论按什么键都必定会触发技能，而呈现给玩家的，就是在刚看到这个com的时候，他就已经是变身状态了。

我们可以将这些按键所需的蓝量设到比角色的总蓝量更高，然后在故事中设置<mmp></mmp>来决定com是否进行变身。


强制解除变身也是同样的道理，PMM的龙介就是用了这种方法解除变身，变身时将蓝量清空，然后自身慢慢回蓝，按键需要满蓝才能触发，满蓝的时候触发按键解除变身。





		    |
		   /|
		  / |
		 /  |—————————————————————————|
		/                             | 
	   《      To  Be  Continued       |
		\                             |
		 \  |—————————————————————————|
		  \ |
		   \|
		    |