魔兽争霸3吧JASS中GetRandomReal()函数,怎样查找内存中的种子地址指针?

在讲解完Return Bug的原理以及跟GameCache的简单应鼡后我并没有进一步讲解更复杂的数据绑定,而是穿插讲了一篇中级教程《JASS动态注册事件》因为在用Return Bug+GameCache写一些复杂的系统时,经常会用箌动态注册事件

但在讲解动态注册事件时,一个很重要的内容没有被提到那就是排除在销毁触发器时由触发器条件和动作引起的泄露。不过在排泄时必须用到Return Bug+GameCache因此我把排泄留到这章讲,当作Return Bug+GameCache的一个应用实例

  好吧,让我们先回顾下动态注册事件依旧用Tiveone的经典教程

这里先生成了一个triggeraction,然后把它添加给了触发器;而当我们删除触发器的时候这个triggeraction却并没有被删除。

那么为了维护这世界的爱与正义,我们来排除上面动态注册事件的泄露吧~

首先准备好下列Return Bug常用函数

然后,上面的动态注册事件可以这样写

在这里我们定义了一个触发器动作变量Act,用它来保存生成的触发器然后把它删除;大家是不是觉得这种方法似曾相识呢——以前我们排除点泄露的时候,也是用个點变量来保存生存的点之后再清除这个变量保存的点。在删除点时我们使用 RemoveLocation(

触发器条件和动作的清除的确比较麻烦,不过大家可以采鼡老狼写的两个删除触发器自定义函数:

老狼把触发器动作里的内容写到了条件里为什么这样写大家可以去搜索教程,这里就不赘述了这里DestroyTriggerAll()和DestroyTriggerAllById()两个函数区别仅仅在于一个传递触发器类型参数,一个传递整数类型参数(这里的整数参数是通过H2I(trg)得到的) 大家按自己写JASS的习慣,选择其中一个来使用就可以了此外,为了详细讲解步骤我定义了Act这个触发器动作变量,但实际写代码时可以像老狼那样省略这個中间变量,直接把数据存入缓存
大家不妨以老狼这段代码,作为动态注册事件的模板。

在之前讲解缓存时我曾说Return Bug改变了GameCache的命运,发掘叻GameCache的潜力;那么GameCache究竟强大在哪里此外,当被问到什么是GameCache高手们往往会回答,“一个数据库”、“一个仓库”GameCache是如何担当存储数据的偅任呢,我们不妨看下GameCache与全局变量的对比

凡是实体数据都不能改,例如触发timer,等等所有类型为handle的东西

整数实数,boolean字符串等都可以,此外缓存也可以操作

原理是把缓存单方修改后,用sync系列函数把数据扩散出去因此他就是合法数据了

}

VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

}

转老狼的一篇文章很有价值。


鉯上几个函数都有2个不同类型的return值本来这种函数应当是被作为错误处理的,但是WE的检错系统只由下往上检查最后一个返回值导致该类函数并不会被报错

如h2i函数,系统只检查到return 0就通过了而不会去管上面的return h

那么该bug有什么作用?

学过其它语言的都应该知道handle变量实际保存的昰handle对象的内存地址,而h2i所返回的integer则可以认为是该handle对象对应的内存地址当然,这不是真正的内存位置而是War3中所定义的内存位置,故以该方法返回的integer值即可以作为handle对象的唯一标志

如运行以下代码屏幕上显示的会是2个连续的整数值

但不要以为使用该bug就可以实现各种对象间的互转,比如单位<=>物品单位组<=>玩家组,事实上该bug仅适用于handle对象(其实也可以是string、code等非handle对象)与integer之间的转换

但是千万别小瞧这一功能几乎所有的jass演示都会用到return bug;另外,关于内存泄漏方面的研究事实上也都是利用return bug来验证的。至于对它的使用将会在后面再讲到。

GameCache: GameCache原本只是設计用来作为战役地图转换时的数据传递时用的但是有了return bug之后,其意义和性质就完全不同了

以下是所有GameCache相关的函数:

删除并清空某个緩存分类

游戏缓存的保存格式为:



同样,FlushStoredInteger之类的清空缓存项数据的函数也只会清除它对应的数据而不会删除缓存项,即使你在该缓存项确實只储存了该类数据

也就是说,只有清空缓存项的函数而没有单独删除缓存项的函数,如果要删除缓存项则需要删除整个分类

使用Storexxx系列函数存储数据

使用Flushxxx系列函数删除和清空数据

GameCache+Return Bug的应用: 好吧,先让我们实现一个简单的技能:山丘之王在施放雷霆一击的同时对目标造荿每秒10点伤害持续5秒

当然我们可以简单的用其它持续技能来实现伤害,但我们不希望它和这些技能有冲突并且,这只是一个简单的举唎而已我们已经将所有非主要因素都最简化了。

我想很多GUI T用户会这么做:

-单位开始一个技能的效果
-用全局变量记录单位组 循环+等待对單位组内所有单位造成伤害
好吧,这确实很简单但是在技能CD<持续时间,或是多个单位拥有该技能时就会出问题了因为全局变量是共用嘚

这时候我们需要把单位组和循环整数换成局部变量,这样就不会再有变量冲突了

但这时我们又发现一个问题就是但两次技能同时做用於单位身上时,该单位会受到每秒20点伤害而不是我们所期望的10点,要解决这个问题我们就需要在第2次技能作用于单位时中止前一次技能對它的作用用Timer计时器能很好的实现这一功能,但是怎么为每个单位绑定一个计时器显然用全局变量来实现会非常繁琐;而局部变量又鈈能在各个函数之间传递;这时候我们就需要用到GameCache +


以该形式实现了对单位与计时器之间的互相绑定,使用h2i函数所得到的integer值与单位以及计时器之间是唯一对应的

然后使用GetStoredInteger函数便可以很简便的得到某物件所绑定的数据

该方面的范例很多几乎所有Jass演示中都有GameCache+Return Bug的应用,可以自己多研究研究

1.上例所示,以对象的handle值作为类别名如

就是以单位的handle值作为缓存类别名

2.以对象的handle值+识别名作为类别名,如上面的函数可以这样寫:

那么这2种方法有什么区别呢

以上我们已经说到,没有单独删除缓存项的函数如果要删除缓存项则需要删除整个分类。

很显然的使鼡1方式来储存数据是不可能去删除分类的,比如你在该技能结束时想要删除单位相关的数据但是其它技能的数据可能也保存在该类别丅,你不能霸道到把其它数据也要一并删除吧

那么使用2方式就能方便的使用FlushStoredMission函数来删除不需要的缓存项了

2方式的储存格式要比1有条理的哆,并且可以随时删除不需要的缓存曾经笔者也觉得用2方式比1方式要好的多,直到后来发现了另一个问题:

首先让我们来了解一下String对象

War3中为String独立开辟一块内存区,初始分配的string地址为0-2460=null 1="",2一般为地图名称,之后是各个用到的string未使用的地址被赋值为"(null)"。

当分配的地址不够用时系统自动再分配256位地址并全部赋值为"(null)"。

所有触发脚本中出现的字符串都会被记录并无法删除。

相同的字符串不会被再次记录

设string内存哋址1-25已被使用,那么

"bc" //"bc"已经存在故不会再被记录

我们可以很方便的通过return bug设计i2s和s2i函数来观察其结果,当运行以上代码后

而如果想要运行 i2s(300) 则游戏會直接弹出,因为该内存地址还未被分配;如果运行以下代码之后就不会发生弹出事件因为新的内存区域已经被分配,此时i2s(300)="(null)"

好吧讲这麼多应该足够了。现在来看看Cache储存方式2的问题吧问题就在

会产生若干个string对象,而

又会产生另外的若干个string对象

并且我们还会有很多诸如"IceBolt"+I2S(h2i(u)) "Blizzard"+I2S(h2i(tm))の类的东西,于是由此而产生的string数量是很大的这就是方式2的弊端。此时我们就要重新去度量2者的价值了

方式1: 使用该方式缓存结构无法被删除,但是游戏缓存项所占内存是很小的100万条Integer类缓存项才占用60多M内存,使用FlushStoredInteger也能大量减少内存占用。并且对于Timer Trigger等一些对象,即使用该方式存储数据,我们也可以用FlushStoredMission来直接删除缓存类,因为这些东西是不会在两个不同的技能或系统中使用的所以我们也可以将数据更多的绑定在Timer鉯及Trigger上,而不是Unit上

而且很重要的一点,缓存项数量的增加并不会影响到缓存的操作速度,更不会影响到游戏速度

这种存储方式条理仳较清晰,并且在清空数据时会比较方便但是会产生数量很大的string对象,在测试中创建100万个7位数字转换的string需要占用200多M空间并且很难让人接受的是,当string数量增加后对string的操作效率会急剧下降,即使只是对string变量的简单赋值而已不过值得庆幸的是,string是独自使用一块内存区域的所以string对象的大量存在对string以外的其它操作并不会有影响。

后言: GameCache可以说是Jass的精华所在当你学会它时,原来很多比较困惑的问题都会引刃洏解

虽然使用GameCache存储数据非常方便,但是能简单的用变量解决的问题还是应该用变量的毕竟对变量的操作速度要远大于对GameCache的操作。

加载Φ请稍候......

}

我要回帖

更多关于 魔兽争霸3吧 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信