这是我的一次排除地图故障的经历。其实严格来说这不算一个故障,但是它的确给地图带来了很大的问题
我下面是把思路理清以后再写出来的,实际找错误的时候比它曲折了一些
昨天晃论坛的时候发现有个人说自己的地图出现了很奇怪的毛病
就是触发器完全没反应,而且看几个前人的回帖竟然是连新加入的T都不能执行
就好象游戏完全忽略了触发器这部分一样
于是好奇心使我把这个有问题的地图下了下来,首先开始瞎捣鼓了一阵。
发现还真是怎么弄触发器都完全不能执行,和完全没有这部分内容是一样的。
这么奇怪的问题还是第一次听说,于是好奇心使我冷静下来,决定好好研究一下。
我先把地图的war3map.j文件导了出来,浏览了一下,发现大体上没有什么错误(WE自动生成的,有错误才怪了)。然后进入游戏,发现单位,装饰物等都放置正常。单位和装饰物的放置也是在war3map.j里面被执行的,就是说游戏还是对war3map.j进行了操作的。
那为什么惟独触发器没有反应呢?
首先我怀疑是在地图别的文件里面有一个开关来控制是否加载触发器,于是我删除了这个地图的war3mapj文件,直接导入了另外一个地图的war3map.j文件,进入游戏以后发现了很奇怪的现象,地图竟然正常,所有触发器都被正常读取了(这次是我第一次直接把一个地图的war3map.j换成另外一个地图的war3map.j文件,没想到竟然不报错,我相当惊讶)。这说明在别的文件里面并没有一个开关来控制是否加载触发器。这样就可以肯定是war3map.j出了问题。
然后开始进入代码的研究阶段,因为主要是触发器不能读取而不是功能问题,所以代码一路无视,直奔入口函数
main而去。下面是它main部分的代码(无用的环境设置部分已去除):
call CreateAllDestructables( ) 在地图上创建装饰物
call CreateAllItems( ) 在地图上创建物品
call CreateAllUnits( ) 在地图上创建单位
call InitBlizzard( ) 系统初始化
call InitGlobals( ) 变量初始化
call InitCustomTriggers( ) 注册自定义触发器
call RunInitializationTriggers( ) 运行事件为“地图初始化”的触发器
既然装饰物、单位等创建正常,那么最开始的3个语句应该没有什么问题
游戏中不好调试,不能设置断点,那么只好找个明显的标志来判断语句被执行没有。
我选用了EndGameBJ这个函数,作用是退出游戏(作用很明显,是非常好的标志)
首先我把它加到了InitBlizzard的下面,来判断是不是InitBlizzard出了问题
结果是正常进入后退出,证明InitBlizzard并没有问题。
call InitBlizzard( ) 系统初始化
call EndGameBJ()
call InitGlobals( )
接着我把EndGameBJ移动到了InitGlobals( )的下面,进入游戏,问题出现了
游戏竟然没有退出!!!!
这说明函数InitGlobals出了问题,游戏没有顺利执行完它。
接着自然是顺藤摸瓜找到函数InitGlobals,下面是它的代码
function InitGlobals takes nothing returns nothing
local integer x= 0
set udg_YINGXIONG = CreateGroup()
set udg_player = 0
set x= 0
loop
exitwhen (x > 88)
set udg_SHISHI[x] = CreateGroup()
set x= x + 1
endloop
set udg_lv = 1
set udg_lv2 = 1
set udg_lv3 = 1
set udg_lv4 = 1
set udg_lv5 = 1
set udg_lv6 = 1
set udg_lv7 = 1
set udg_LV8 = 1
set i = 0
loop
exitwhen (x> 7)
set udg_money[x] = 0
set x = xi+ 1
endloop
set x = 0
loop
exitwhen (xi> 7)
set udg_LEVE[x] = 0
set x = x+ 1
endloop
set xi = 0
loop
exitwhen (x> 8192)
set udg_diqu1[x] = CreateGroup()
set x = x + 1
endloop
set x = 0
loop
exitwhen (x > 7)
set udg_RODOM[xi] = 0
set xi = xi + 1
endloop
set udg_YXgeshu = 0
set x = 0
loop
exitwhen (x> 7)
set udg_KILL[x] = 0
set x = x+ 1
endloop
set udg_sidahufa = CreateGroup()
set udg_lv9 = 1
set udg_LIANGONG = CreateGroup()
set udg_MUTOU = CreateTimer()
set udg_CMUTOU = CreateTimer()
set udg_jianzhenFAC = 0
set udg_lieyanFAC = 0
set udg_SPAO = CreateTimer()
set udg_A1 = 0
set x = 0
loop
exitwhen (x> 8192)
set udg_diqu2[x] = CreateGroup()
set x= x+ 1
endloop
set udg_A2 = 0
set xi = 0
loop
exitwhen (x> 8192)
set udg_diqu3[x] = CreateGroup()
set x = x + 1
endloop
set udg_A3 = 0
set x = 0
loop
exitwhen (x > 7)
set udg_FUHUO[x] = CreateTimer()
set x = x + 1
endloop
endfunction
大致上一看结构也没有问题,在郁闷中我继续翻看代码。。。
忽然发现想到平时写程序的时候也发生过同样的问题,一般原因都是在某个地方陷入了死循环。。。
重点观察了几个loop以后发现结构也很好啊,退出条件很明了,不象是会死循环的样子。。。
在郁闷中继续看代码,忽然发现有3个循环的退出条件竟然是exitwhen (i > 8192)。。。
难道是这里出了问题?难道是创建8192*3个单位组的时候没有成功
于是游戏卡在这里等待单位组分配成功?
于是把那几个8192改成了1~~导入游戏以后忐忑不安的进入游戏。。。。
呵呵,成功了,触发器正常了
这个是我第一次遇到地图竟然会出现这种问题,其实解决的时候没这么顺利
因为对JASS了解还不是非常好,走了不好弯路
大家设计地图的时候一般遇到的都是效果太华丽而显卡承受不住当机了,所以都会在这方面注意
而内存方面却注意不够,我记得我把答案给地图作者的时候,作者很郁闷的说,我在地图初始化的时候又没有用到那几个单位组变量,为什么会卡啊。。。
单位组是引用型变量,在初始化的时候必须给它分配空间。。。。。。
希望大家在遇到奇怪问题的时候能够冷静分析,不要慌,毕竟电脑是按程式工作的,它出错的几率很小,大部分应该是你自己某个小错误而没有发现。
希望对大家有所帮助,有兴趣可以和我交流。
通魔作坊·宝宝暴暴
QQ:105070429
PS:发帖的手发现一个更郁闷的东西,i竟然是斜体的标志,没办法,只能把i都换成x拉。。。。
[ 本帖最后由 onlyxuyang 于 2006-2-21 13:40 编辑 ]
责任编辑:admin
进入论坛参与针对本文章的讨论
