心魔网 - 挥洒由笔,创意随心's Archiver

everguo 发表于 2007-6-19 11:42

恶搞的JASS教程(部分)

  恩  越来越觉得有写个轿教程的必要了   但不知大家能不能接受我YD的风格  先发上部分听下意见


[color=blue][size=4]四、缓存[/size]  [/color]    缓存(Cache)是什么  它跟变量有什么不同        这样说吧  缓存跟变量有异曲同工之妙    但却又有本质的差别

你可以把一个局部变量想象成一次性纸杯  可以N个人同时使用  用完就扔掉      而全局变量是玻璃杯  不能被同时使用  但用完后还在  可反复使用  (如果你反感我举的这个例子 认为太不YD了  你也可以把全局变量想象成黄瓜  把局部变量想象成避孕套)   

而Cache像帐本,或者日记本  是将一些东西的参数记录进去

变量是存放的是实质的东西  并且因存放的东西不同而分类不同   有单位、区域、触发器等变量      这样说吧    就像容器   放水的叫杯子  盛饭的叫碗    装屎的叫马桶

因分类不同  所以你不能让一个变量储存与它类型不同的东西  譬如你不能用单位变量来保存地图上一个区域    就像你不能用马桶给客人盛饭

Cache里只能存储integer(数值) real(实数)  boolean(真值,音译为”布尔“) string(字符窜)    就像帐本或日记本  只能有数字、 文字、图画一样

那么  Cache怎么用  跟变量有什么不同    让我们回归YD的主题

话说有个叫木子美的  喜欢写性爱日记  但她不可能把活生生的姘头塞几日记本里去啊     但她可以用文字的形式  把姘头描述出来

首先   木子美要写日记   得先有日记本吧    所以我们得先创建个游戏缓存,用个全局变量GC来保存      现在她要开始记录了  第一个被记录的  是李亚鹏 ——年龄34(乱编的),身高1米78,不帅      等等
记录如下:
call StoreInteger(udg_GC,"LiYaPeng", "age",34)
call StoreReal(udg_GC,"LiYaPeng", "stature",1.78)
call StoreBooleanl(udg_GC,"LiYaPeng", "handsome",false)
其中  udg_GC便是日记本了,因为木子美的日记本不止一个,所以你必须说清楚我们鸭棚格格到底在哪个日记本上    木子美翻开第一页  在页眉上写下LiYaPeng   然后在 下面写个  age   34    然后换行   stature   1.78  等等

记录  就这么简单

那么  如何清除缓存呢   我们来看

鸭棚格格打电话来了  说阿美啊你怎么可以记下我年龄呢  这是秘密啊让我女粉丝知道会伤心的   于是木子美就用橡皮擦将年龄那行擦掉

call FlushStoredInteger(udg_GC,"LiYaPeng",  "age"  )

于是我们便不知道鸭棚格格的年龄了  

不过这时鸭棚格格的弟弟鸭肠打来电话  说我哥都结婚的人了你就行行好不要写他了吧   于是木子美只好把这页撕了

call FlushStoredMission(udg_GC, "LiYaPeng")

这样一来    关于鸭棚格格的资料就全米了

mj39133414 发表于 2007-6-19 12:03

喜欢玩火影RPG的朋友请加群16125082~大家一起交流~一起进步~谢谢~~!!!!!

老子 发表于 2007-6-19 12:08

路过沙发,如此通俗易懂的东西,支持,因看到黄瓜避孕套等熟悉之物,so 纯支持 = .=

boss 发表于 2007-6-19 17:40

果然很强大

eff 发表于 2007-6-19 17:42

楼上上没有抢到沙发

圣诞№结 发表于 2007-6-20 09:23

我看这么多篇JASS教程~就这个可以看下去~~LZ好伟大~

jaina 发表于 2007-6-20 16:35

一点也不好。
好好的孩子都能让你教坏。

siren 发表于 2007-6-20 16:51

我晕,everguo跑到心魔来YD了.........

圣诞№结 发表于 2007-6-20 17:37

不用看啦~绝对够强大~快补充其他部分~

艾萨拉女王 发表于 2007-6-20 17:51

勉强看懂老。。。。= =!

但谁能告诉我。。。缓存具体用处

圣诞№结 发表于 2007-6-20 20:05

我感兴趣的是其他部分.......这里都基本能看懂~其他部分应该也很好理解~~~~

LZ这种比喻性说明我才能明白....

everguo 发表于 2007-6-21 10:13

[quote][b]引用第9楼[i]艾萨拉女王[/i]于[i]2007-06-20 17:51[/i]发表的“”[/b]:
勉强看懂老。。。。= =!

但谁能告诉我。。。缓存具体用处[/quote]


缓存具体用处是跟return bug+timer一起用

这三个东西  可以说是YD三宝   J的优越性完全被体现出来

可惜后续的教程  不知什么时候有时间写

圣诞№结 发表于 2007-6-21 11:04

饿........return bug, timer又是什么?

eff 发表于 2007-6-21 11:36

缓存?类似数据库

作用等与随时创建全局变量,主要作用是在不同触发/函数之间传递参数

everguo 发表于 2007-6-21 12:47

在前面说了  Cache里只能存储integer(数值) real(实数)  boolean(真值,音译为”布尔“) string(字符窜)    也就是说  其它类型的数据  比如  单位  区域等   没法保存在Cache里

而Return bug  就是把类型不同的数据间相互转换  比如   H2I  就是把其它数据转换成integer(数值)

配合前面的例子  你可这么想象  木子美把她的姘头变成一窜0和1的字符窜   加到了她的日记本里    为虾米人会变成一窜数字呢  因为我们这个世界是不真实的  大家全生活在电脑程序里(见《黑客帝国》)


比如  用  H2I 将姘头转换成数据  保存在Cache里后   当有了生理需要  木子美会把姘头放出来  这时  要使用  I2U(function I2U takes integer i return unit)  将数据变成单位

也就是说    Cache+Return bug =  最完美的变量    它同时有局部变量跟全局变量的优点   

如果说局部变量是便签纸   大家一人拿张  在上面写东西  各写各的  相互不影响   但相互不知道对方写的是什么  而且写完后纸条就扔掉了

全局变量像是一块小黑板    大家都能看到    但若要你用它  就要把别人的内容搽掉

而Cache+Return bug  就是一本公用的笔记本   大家都可以在上面不同的页面  各写各的东西   相互不影响    又可以使坏   修改别人的内容


所以   Cache+Return bug  是最完美的变量    蚊子叮说它非常好用    还说下张图的目标是    不自定义一个全局全局变量

至于Timer   的用处    下次再说

jaina 发表于 2007-6-21 14:23

如果可以这样用
call TimerStart(timer_temp,0.01,true,kill(everguo)),那么就缓存的使用率一会下降。

everguo 发表于 2007-6-21 16:21

恩  的确  因为TimerStart里的那个函数  是不能写参数进去的  必须是 takes nothing  因此kull(everguo)这样写会出错

所以Timer要跟Cache和Return bug结合使用

关于这个我想放在以后讲的  如果真的要实现每秒kill一次everguo  那要先将everguo保存到Cache中   然后在计时器耗尽时  将everguo从Cache中调出来kill掉

圣诞№结 发表于 2007-6-21 20:11

很厉害`还是看不懂~能把变量用好我就进步很大了.....

ddo 发表于 2007-6-21 23:52

LZ到处宣传YD风格.....是虾米意思?

everguo 发表于 2007-6-22 12:23

将YD变成褒义词

朱朱 发表于 2007-6-22 13:28

你这个不算YD了。
有一种方法可以摆脱缓存,提高效率。

缓存的缺点如下:
1.一般用于timer,导致产生大量的timer,且经常都是0.01秒周期的timer有很多个同时运行。
2.缓存两个标签要产生大量的string,而string无法释放。
3.缓存的读取速度没有变量快。
4缓存一般都是handle-----integer类型来回转换,损失类型安全性。

secret_sea 发表于 2007-6-22 13:34

有没有unit group的用法
我找了几个教程都没

everguo 发表于 2007-6-22 14:51

[quote][b]引用第20楼[i]朱朱[/i]于[i]2007-06-22 13:28[/i]发表的“”[/b]:
你这个不算YD了。
有一种方法可以摆脱缓存,提高效率。

缓存的缺点如下:
1.一般用于timer,导致产生大量的timer,且经常都是0.01秒周期的timer有很多个同时运行。
.......[/quote]

1.老狼做过测试  即便同时运行大量Timer  也不会卡
2只要注意不在文件名中使用"+"  那产生的string不是很多  再说即便产生几十万条string  对游戏速度都不会有明显影响
3访问变量的更确快些  但这点在游戏的时候感觉不到
4这点我没听过  能不能解释下

其实以前夜影冰剑提出了种全局替代游戏缓存的方法  不知你说的是不是这个  我发上来好了


[box=royalblue]function h2i takes handle h returns integer
   return h
   return 0
endfunction

function i2u takes integer i returns unit
   return i
   return null
endfunction

function MoveUnit takes nothing returns nothing
   local integer int0 = h2i(GetExpiredTimer() )
   local integer int1 = int0/1000
   local integer int2 = int0-int1*1000
   local unit u = i2u ( udg_StoreI[int1]*1000+udg_StoreII[int2] )
   local location loc1 = GetUnitLoc( u )
   local location loc2 = PolarProjectionBJ(loc1,10,GetUnitFacing(u))
   call SetUnitPositionLoc( u, loc2 )
   call RemoveLocation( loc1 )
   call RemoveLocation( loc2 )
   set int0 = 0
   set int1 = 0
   set int2 = 0
   set u = null
   set loc1 = null
   set loc2 = null
   if(GetUnitUserData(u)>=100)then
      call DestroyTimer(GetExpiredTimer())
   else
      call SetUnitUserData( u, GetUnitUserData(u)+1 )
   endif
endfunction

function TimerCreate takes unit u returns nothing
   local timer t = CreateTimer()
   local integer int1 = h2i(t)/1000
   local integer int2 = h2i(t)-int1*1000
   set udg_StoreI[int1] = h2i(u)/1000
   set udg_StoreII[int2] = h2i(u)-udg_StoreI[int1]*1000
   call SetUnitUserData( u, 0 )
   call TimerStart( t, 0.02, true, function MoveUnit )
   set t = null
endfunction

传统方法

function MoveUnit takes nothing returns nothing
   local unit u = i2u (GetStoredInteger(udg_GC,I2S(h2i(GetExpiredTimer())),"MoveUnit"))
   local location loc1 = GetUnitLoc( u )
   local location loc2 = PolarProjectionBJ(loc1,10,GetUnitFacing(u))
   call SetUnitPositionLoc( u, loc2 )
   call RemoveLocation( loc1 )
   call RemoveLocation( loc2 )
   set u = null
   set loc1 = null
   set loc2 = null
   if(GetUnitUserData(u)>=100)then
      call DestroyTimer(GetExpiredTimer())
   else
      call SetUnitUserData( u, GetUnitUserData(u)+1 )
   endif
endfunction

function TimerCreate takes unit u returns nothing
   local timer t = CreateTimer()
   call StoreInteger( udg_GC,I2S(h2i(t)),"MoveUnit",h2i(u) )
   call SetUnitUserData( u, 0 )
   call TimerStart( t, 0.02, true, function MoveUnit )
   set t = null
endfunction[/box]

everguo 发表于 2007-6-22 14:54

[quote][b]引用第21楼[i]secret_sea[/i]于[i]2007-06-22 13:34[/i]发表的“”[/b]:
有没有unit group的用法
我找了几个教程都没[/quote]


教程只能教你最基础的东西  如果你想知道具体某些东西的用法  找演示看看吧


这是老狼以前写的一个返回单位组里HP最低的单位 不知是不是你要的

[box=blue]function GroupPickLowestLifeUnitEnum takes nothing returns nothing
   if GetUnitState(GetEnumUnit(), UNIT_STATE_LIFE) < GetUnitState(bj_groupRandomCurrentPick, UNIT_STATE_LIFE) then
      set bj_groupRandomCurrentPick = GetEnumUnit()
   endif
endfunction

function GroupPickLowestLifeUnit takes group whichGroup returns unit
   set bj_groupRandomCurrentPick = FirstOfGroup(whichGroup)
   call ForGroup(whichGroup, function GroupPickLowestLifeUnitEnum)
   if bj_wantDestroyGroup then
      call DestroyGroup(whichGroup)
   endif
   set bj_wantDestroyGroup = false
   return bj_groupRandomCurrentPick
endfunction[/box]

朱朱 发表于 2007-6-22 16:23

[quote]
1.老狼做过测试  即便同时运行大量Timer  也不会卡
2只要注意不在文件名中使用"+"  那产生的string不是很多  再说即便产生几十万条string  对游戏速度都不会有明显影响
3访问变量的更确快些  但这点在游戏的时候感觉不到
4这点我没听过  能不能解释下

其实以前夜影冰剑提出了种全局替代游戏缓存的方法  不知你说的是不是这个  我发上来好了
[/quote]
也是利用全局变量。
不过是全局数组,之后写一个函数库支持操作。
不用还是不爽,TimerStart不能带函数参数是最大的问题。

everguo 发表于 2007-6-22 16:35

厄...这类似的方法我好象用过

在优化的《灌水》里  定时刷怪跟掉落物品  我都用的数组

圣诞№结 发表于 2007-6-22 19:59

你们说的话都好深奥哦~我要路过一下~你们继续~

zenkilai 发表于 2008-4-11 00:12

太TM强大了

kimmy_zx 发表于 2008-4-11 22:51

很好很强大,多谢楼主,辛苦了

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.