Indexer系统全面教程.docx
- 文档编号:25711008
- 上传时间:2023-06-11
- 格式:DOCX
- 页数:21
- 大小:800.76KB
Indexer系统全面教程.docx
《Indexer系统全面教程.docx》由会员分享,可在线阅读,更多相关《Indexer系统全面教程.docx(21页珍藏版)》请在冰豆网上搜索。
Indexer系统全面教程
Indexer系统全面教程
1.Indexer系统有什么用?
做技能时,往往需要给单位绑定一些数据,比如做护盾类技能时需要绑定护盾能抵消的伤害值,做一些持续伤害的技能时需要给技能目标单位绑定伤害来源单位和每秒的伤害值.
目前常用的方法有全局变量、缓存和哈希表三种。
全局变量有高效、方便使用的有点,只需要设置变量=xx即可;缺点则是无法支持多人。
市面上大多数支持多人的做法是采用全局变量数组,用玩家索引做数组索引。
在控制单英雄的地图中可以起到很好的效果,但是对于需要支持更多单位、或者每个玩家多个单位的时候,就显得不够用。
缓存和哈希表分别对应1.20版本和1.24版本的魔兽。
缓存需要使用returnbug,需要使用jass或自定义代码来存储数据;哈希表提供了GetHandleId函数,但是在触发器中没有合适的接口,最后还是需要通过自定义代码或第三方we(比如ydwe)提供的功能来使用,比较复杂。
使用Indexer系统可以方便的记录很多数据,而且通过扩展,该系统可以支持位移系统等更多的功能。
2.Indexer系统的原理
Indexer系统是基于全局变量数组的记录方式。
触发中有设置单位自定义值的功能,自定义值可以是任意整数,而且可以绑定单位而没有其他副作用。
Indexer系统通过一定的算法,使得每个单位都拥有不同的自定义值。
这样,类似于利用玩家索引制作支持多人的技能,可以将单位的自定义值作为数组索引来使得触发支持多人,可以支持任意玩家的任意多个单位(理论上只能支持8191个单位,但绝大多数地图上不会同时存在如此多的单位)。
Indexer系统在地图初始化时选取全地图的单位来设置不同的自定义值。
之后通过单位进入可用地图区域来获取系统中新增的单位。
由于单位进入可用地图区域事件有延时,所以需要新建的单位立刻进入系统时(比如弹幕、马甲持续攻击芙蓉面还),还需要一个新增单位的触发。
当单位死亡时,判断是否为英雄单位。
如果不是英雄,则可以移出Indexer系统。
3.简单的Indexer系统
制作一个最简单的Indexer系统需要以下变量:
其中,Flag表示当前Indexer中最大的自定义值。
Group将进入Indexer系统的单位放入单位组,避免单位重复进入(创建单位手动添加的情况下)。
Unit数组将单位按自定义值作为索引添加到单位组,这样就可以通过单位自定义值来获取对应单位。
LocalIndex是个临时整数,用来记录当前单位的自定义值。
触发如下:
将初始化地图中的单位添加到Indexer系统中。
这里利用数组的0号索引作为临时的变量,不作为实际存储使用。
获取当前单位后(这里是单位组循环中的选取单位),将Flag的值+1,并作为单位的自定义值,即可保证每个单位的自定义值不同。
该触发最后一行是给下一个触发添加事件。
下一个触发里直接设置事件也可以。
游戏中动态进入地图的单位添加到Indexer系统中。
和上一个触发原理相同。
手动添加单位进入的触发。
需要先设置Index_Unit[0]为需要添加的单位,然后运行AddIndex触发器(无视条件)。
原理同上。
死亡的单位移出Indexer系统。
无论死亡的单位是不是拥有最大的自定义值,Flag的值都需要-1.
4.增强的Indexer系统
4.1给Indexer系统添加更多更复杂的功能
新建了如下触发。
这里是给进入Indexer系统的单位注册受伤害事件,通过这种方式做到捕获任意单位受伤害。
之后还需要改造一下前面的触发:
手动添加单位的时候就不需要再运行触发了,一般这种情况都不需要动态做,如果需要,自己再加上运行触发即可。
4.2学着自己添加一个新功能
我想做一个检测单位移动速度变化的触发。
如下所示。
新建了一个变量
我用New_Speed变量记录单位移动速度,然后每0.01秒与单位当前移动速度做比较。
但是这么做还不够!
还存在着不少bug!
首先:
给一个不确定大小或很大的数组设置数组大小是不明智的(大家都懂的!
)。
而变量如果不设置初始值,就会发生一个现象:
访问到未赋值变量时,触发就会中断。
到选中的这一行时就已经运行不下去了。
同时整个循环也都无法继续。
这时候上面创建的AddExFunction触发就开始发挥作用了。
在这个触发添加这一行即可避免变量未赋值导致的函数中断。
这样就结束了么?
当然没有。
在单位死亡移出Indexer系统时,单位的自定义值发生了变化,因此这里还需要加一行。
这个方法虽然管用。
但是也面临着一个缺陷,随着自己添加的功能逐渐增加,单位死亡时需要重新赋值的变量也会相应增加,导致ExitIndex触发越来越复杂。
为了避免这个状况,这里引入了双Indexer。
4.3双Indexer的原理及使用方式
对上节出现的问题提出一个双Indexer的解决方案。
方案原理为采用一个数组来记录单位对应的数组索引,而不是简单的采用单位自定义值,这里简称这个单位对应的数组索引为“索引”。
这个数组被称作双Indexer数组,简称D数组。
D数组为一个整数数组,默认的值即是数组索引,例如a[1]=1,a[2]=2以此类推。
当然D数组初始化是没有赋值的。
D数组赋值的长度为Indexer系统曾经达到的最大单位自定义值。
超出现有长度而新赋值的变量值一定是索引值,而已经赋值过的部分将会产生变化。
原本的Indexer系统
双Indexer系统
可见,只需要改变D数组中数字的排列顺序,就可以使得系统中单位排列紧凑,避免更改其他数组的值。
同时通过索引获取对应单位也需要新建一个单位数组来记录。
双Indexer系统新增了3个变量,Flag2、Index和Search。
其中Flag2是用来记录D数组初始化过的最大索引,当Flag值(Indexer系统中单位数量)大于Flag2时,就需要给D数组赋值。
Index整数数组就是D数组。
Search数组和Index数组是个互反的数组,即Index[b]=c,则Search[c]=b。
这样就可以通过Unit[Search[索引]]获得索引值对应的单位。
三个将单位添加到Indexer系统中的触发都做相应变化。
单位移出系统时的触发。
看起来很长,其实就是数组中的两个值互换赋值。
5.Indexer位移系统
如果要说Indexer位移系统与其他位移系统的区别,有两个主要的区别:
1是采用中心计时器来进行位移,效率高,可以支持同时位移的单位数量更多
2是通过全局变量和运行触发(无视条件)可以轻松的设置单位在位移路径中或位移结束时的额外效果,比如沿途伤害、到达目标点后晕眩周围单位等,甚至“碰到一个单位后停止位移并击退碰到的单位”这种比较复杂的功能也是可以的。
位移系统的变量设置如下:
我知道肯定被吓傻了。
这里一一解释。
Angle即角度,是指位移时下一点与当前位置的偏移角度,Dl则是偏移距离。
During是一个常数变量,游戏过程中不会变化,用来设定位移系统的运行间隔,与单位位移的流畅度有关,一般推荐0.03和0.025,不推荐小于0.01的值。
Group是正在位移的单位加入的单位组。
每个间隔运行位移系统时都会对该单位组中的单位进行循环位移。
Index用来记录正在位移的单位的索引值。
L记录单位已经位移的距离,L0则是单位位移过程的最大距离。
P0和P1两个点变量用两点间距和两点夹角来计算单位位移的距离和角度,开始位移和位移过程中都会用到。
Pathable和PItem是位移系统内部包含的一个可通行判断系统的变量,后面再说。
TriggerB和TriggerC分别是位移过程中和位移结束时运行的触发。
Tu是朝着单位冲锋时的目标单位。
TX和TY记录位移过程中一次位移改变的xy坐标值。
Type用来区分位移的方式(目前只有对点位移和对单位位移,值分别为0和1)。
位移系统的触发如下:
触发事件不能直接用变量,这是用变量设置触发的正确方式。
循环单位组,并判断位移方式。
Index_Index[单位自定义值]就是双Indexer系统获取单位索引的方法。
U和Index两个变量都作为全局变量传参,用于Movement1、2触发。
对点位移的触发。
L每次运行增加Dl,当L>=L0时则位移结束,运行触发TriggerC。
否则运行TriggerB。
这里用P0极坐标位移至P1来获取位移的目标点。
也可以直接坐标运算。
由于Indexer位移系统本身效率就较高,所以不考虑坐标运算和点运算这点效率。
向着单位位移有点不同。
需要的变量为目标单位Tu和每次位移的距离Dl。
其他的都是计算单位坐标的临时变量。
这里的64是两个单位的碰撞范围之和(一般单位的碰撞为32左右),强迫症患者可以枚举下单位碰撞。
下面介绍一下碰撞判断系统。
这里只判断地面单位可通行,即移动类型为地面的单位所能通过的地形。
这里利用创建物品的坐标与物品实际坐标之差小于3来判断是否可通行。
注意这里的碰撞检测包含了树木的碰撞。
如果沿途破坏树木,可以在TriggerB触发中破坏树木然后动态的检测碰撞。
位移系统的演示如下:
这里大部分都是给变量赋值,复杂一点的敌法在中间的循环部分。
作用是检测单位到位移目标点的路径上距离目标点最近的一个可通行地面。
这样可以很好的防止单位位移后卡在地形里面不能动。
NullTrigger就是这货,如其名称,啥都没,即位移结束后啥也不干。
TriggerB的函数。
就是在位移途中检测范围内敌军单位。
如果检测到就给个伤害和马甲晕。
移除Group即结束位移。
对单位的冲锋就简单多了。
不过这里并没有考虑地面碰撞。
一般情况冲锋的目标单位也是地面单位,所以冲过去一般就在可通行地面。
发生问题的几率不高。
这里是可以同时对敌军友军的闪电链。
冲锋结束后判断是敌军就给伤害。
如果冲锋的不是触发单位,而是新建的一个马甲单位,需要
手动加进Indexer系统,因为单位进入可用区域事件延时。
直接获取单位Indexer会获取到Indexer[0]的值。
Buff系统教程
1.Buff系统是什么
Buff系统是模拟技能给单位添加一定时间的持续效果的系统。
这里通常使用龙卷风减速光环(Aasl)作为添加buff的模板技能。
减速光环的优越性在于光环技能可以设定不同的buff且不同buff可以同时存在,同时减速光环没有技能图标,因此不需要像添加其他技能(如暴击,闪避)一样将技能放进魔法书并禁用。
这里的buff系统功能包括添加某个技能一段时间(包括但不局限于龙卷风减速光环)并且在删除技能的同时删除魔法效果。
以及单位死亡时移除添加的技能。
移除技能时可以选择一个特殊效果(比如护盾技能结束后回复生命值)。
由于是光环模拟buff,因此没有buff图标闪烁的功能。
2.Buff系统的构成
Buff系统所需的变量如上所示。
其中During是Buff系统检测Buff剩余时间的间隔(这里使用一个中心计时器以提高系统效率),和位移系统一样,默认采用0.03秒周期。
Unit是添加技能的单位,Id是添加的技能,Buff是技能持续时间结束时需要删除的技能buff,Time是记录添加技能的剩余时间,Trigger是技能结束时运行的触发,Flag代表Buff系统当前的Buff上限.Loop用来当做Buff系统循环判断时的数组索引.
Buff系统所用到的触发如下:
Buff系统的初始化触发.类似于位移系统,通过触发添加事件将变量During作为计时器循环的周期.
主要触发.上面的循环是判断Buff是否到期。
下面的循环是从Buff系统的数组中移除已经结束的Buff(这里将Unit数组的值设为没有单位来标记Buff结束)。
判断Buff剩余时间的触发。
没啥好说的,简明易懂。
添加Buff的触发。
这里分别将添加buff的单位、添加的技能id、技能的buff、持续时间赋值给为Unit[0],Id[0],Buff[0],Time[0],然后运行触发即可。
演示如下
这是给单位添加0.5秒粉碎的方式。
Buff设置为拔树,当做是空Buff。
为了避免冲突也可自己新建一个空buff。
移除单位Buff的触发。
如果不是强调Buff在单位死亡的瞬间有特殊功能,可以无视这个触发。
因为Buff系统在循环判断时也有移除死亡单位buff的功能。
3.Buff系统的应用示范
这里用斧王的反击螺旋为例做示范。
这里制作的反击螺旋在触发的最小间隔(这里是0.55秒)内英雄身上是没有魔法效果的(dota里面反击螺旋学习是用辉煌光环,因此单位身上有buff)。
首先技能设置:
用专注光环做转的学习模板,记住光环的目标允许自己。
魔法效果、文本等由于是演示,所以并未作更细致的模仿。
从上面那个技能复制一个过来。
目标允许改完“没有”即可让buff消失。
同时图标也可以改为暗图标或禁用的图标(演示图未做)。
工程升级,这个技能就是Buff系统要用到的,功能是记录这间隔的0.55秒时间。
工程升级这个技能有个很棒的地方就是直接禁用就可以隐藏图标而且效果还在。
被攻击的时候判断几率,然后添加0.55秒buff。
还有添加转的动画效果。
单位组伤害不解释。
这里直接删除新建的特效,特效仍旧会播放一遍(播放death动画,如果没有death动画就播放其他不知道哪一个。
)
Buff结束时的功能。
把单位转圈圈的动画删掉。
据说dota里面转的动画是0.3秒。
可以新建个+0的攻击之爪作为这个的计时。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Indexer 系统 全面 教程