JASS

时间:2023-05-23 06:26:30编辑:优化君

以下function会创建一个string内容为 "Hello, censing!"显示给所有玩家:

functionTrig_JASS_test_Actions takes nothing returns nothingcall DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Hello, censing!") //在屏幕位置0,0处对本地玩家显示文本消息Hello, censing!endfunction

或者你只想发送给某个玩家:

functionTrig_JASS_test_Actions takes player p returns nothingcall DisplayTextToPlayer(p, 0,0, "Hello, censing!")endfunction

还有你想递增式连续显示90次的话:

functionTrig_JASS_test_Actions takes player p returns nothinglocal integer i=0loopexitwhen i==90call DisplayTextToPlayer(p, 0,0, "Hello, censing! "+I2S(i))set i=i+1endloopendfunction

某些功能只靠GUI Trigger无法完成,必须用JASS来实现。例如对指定玩家播放音效,或者替单位加上永不消失的被动物品技能等。

JASS可以定义局部变量及自定义函数,增加设计的便利性,也提供更简单可行的演算法。

GUI虽然能完成几乎所有的功能,但是对于内存释放的能力太差,容易增加电脑不必要的负担。

用JASS可以写出比GUI效率更高的代码,对执行速度有不小的帮助。一定要学JASS吗?

当然不一定。即使是官方的战役,其程序员也只使用了GUI来完成制作。一般来说,单纯使用GUI Trigger,就可以达到大多数的功能。但是笔者还是建议对Trigger有相当了解的人学些基本的JASS写法,可以省下不少力气,且能让你的地图更不lag!!

触发编辑器中的 Edit =>Convert To Custom Text 将触发转成文字型态。

在触发编辑器下面选 Actions =>Custom Script 可以插入单行JASS叙述。

此外,如果要定义所有触发都能调用的函数

JASS语言的基本函数和常量都是直接调用游戏的函数,他们被存放在war3patch.mpq内的Scriptscommon.j中,另外还有一些扩充函数放在war3patch.mpq内的Scriptsblizzard.j中。war3patch.mpq内的Scriptscommon.ai则包含了用于设计AI的内部函数和扩展函数,虽然AI也是用JASS码编成,但本文不探讨关于AI的设计,有兴趣者请自行研究。

地图中的触发以及物件的摆设情形等,都会被编译成JASS并储存在war3map.j文件中。读者可以到WE中的 File =>Export Script 将它导出。

JASS语言以列为基本单位。每一行的代码必须有完整的意义,不能把一行的代码分两行写;也不可把两行的代码写在同一行。

JASS语言是区分大小写的,该大写就要大写;该小写就要小写。

写在//后面,直到该行结束的文字都是注解内容,这也是JASS唯一的注释语法。后面的例子会多处用到这个注释符号,这个符号和后面的注释只是用于解释代码的功能,并不会被执行到。

在JASS中,空格的使用限制很宽松,除了某些必要的地方一定要有至少一个的空格以外,其它的地方都是可空可不空。此外,要空几格都无所谓,电脑不会因为你空了很多格就说有错。因此,使用者应多多利用空格作缩进,以使代码更易读。

和数学一样,()内的代码优先被执行。不过请注意,JASS中只有小括号()有用,中括号[]和大括号{}不可作为改变执行顺序之用。

与一般高级语言一样,Jass语言具有定义变量、赋值运算、函数调用、条件语句、循环语句、定义函数等最重要的功能。见下表

功能

示例或语法

变量定义与赋值local integer i=1local real a=i+0.3set i=i-100函数调用call BJDebugMsg( "A problem has occurred" )call BJDebugMsg( I2S( 5000 ) )// I2S把整数转化为字符串,从而输出"5000"条件语句if ( ... ) then....elseif ( ... ) then... // 支持多个elseif分支else...endif循环语句loop...exitwhen ( ... )// exitwhen可以出现在循环下任何位置,一般情况下至少要有一个exitwhen...endloop定义函数function takes returns // 参数不存在或不返回值时写nothing...return endfunction

语法错误:少写一个字母,少空空格,或者把大写写成小写等,都是写JASS常犯的错误。一般来说,如果语法有问题,在存档时电脑会显示编译错误的信息,并指出是哪一行有问题,依它的指示修正即可。不过当电脑指出某行有误时,也可能是前面的几行出了问题(范围大概约1~5行),所以如果你怎么检查都看不出某行到底错在哪里的时候,检查前面的代码。此外,某些错误会导致存档时WE当掉,导致先前的辛苦付诸流水,所以请随时存档并尽量小心。

执行错误:一般会发生这种问题是指定的变量没有赋值,当电脑找不到变量的值时,由于无法继续执行,因此会无条件跳出目前的函数,如果该函数是要传回值的函数,它将不会传回值(也是无任何返回),因而可能导致调用它的函数也跳出。此外如除数为0也会造成类似的结果。

无限循环:一般这种事都是人为疏忽(忘了写exitwhen,或是触发的动作引发同一个触发,而造成无限循环等),发生机会不大。不过一旦发生可是会让War3当掉的喔。

数据系统,顾名思义,就是用来储存数据的。好的数据系统要求存得下、存得多、找得到、找得快。以下是Jass里常用的几种数据系统。

1. 全局变量(global variables)

全局变量可以是单个的,也可以是数组形式,后者常被作为数据系统。全局变量的形式为:变量名[索引]。变量名以字母开头、由数字字母和下划线组成,索引是0-8191的整数。Jass里的变量一经申明为数组,数组大小永远都是8192。它的优点是,只要知道索引,可以立即访问到对应变量的值;缺点恰恰是,不知道索引就访问不到。全局变量的声明有两种,一种是直接在变量里创建,另一种是写在文件头,只是触发编辑器里直接在触发创建的全局变量会被系统添加udg_的前缀。

2. 游戏缓存(gamecache)

游戏缓存本来是用于在单机战役的不同地图之间传递数据的。但是由于有一些与哈希表类似的非常好的特性,在1.24之前的版本里,游戏缓存一直扮演着哈希表的角色,returnbug+gamecache曾是最流行的数据系统,而ruturnbug也是利用的War3本身所拥有的bug。它的用法与哈希表差不多,只不过它的母键和子键却不是整数,而是字符串。由于War3里字符串不可避免的泄漏,以及游戏缓存本身的效率问题,它还是远远不及哈希表优秀的。该系统由于JASS的不安全因素被hashtable所取代。(虽然这部分漏洞被修正,不过依然存在漏洞)

3. 哈希表(hashtable)

这个是1.24的新玩意儿,用SaveXxx和LoadXxx两个系列的函数完成数据的储存和读取。哈希表的容量是无限的,而且什么都可以存,即使存了很多东西以后,存取效率也不会变低。不仅如此,它的母键和子键可以是任意的整数,与GetHandleId函数配合,比数组变量方便很多。一个示例:

call SaveInteger(udg_ht, GetHandleId(udg_unit), 'ABCD', 123456789)set i=LoadInteger(udg_ht, GetHandleId(udg_unit), 'ABCD')//此时i的值就是123456789

如果你想使用一个哈希表你需要在全局变量里声明。

除了以上三种数据系统以外,还有location链、rect矩阵等等,当然你也可以自己编写更适用的hash算法,把这几种数据系统相互组合,构造出适合你的、你需要的最佳数据系统。

哈希表语法结构:

a=SaveInteger(pv,key1, key2, b)

pv是一个表格

key1自定义数值

key2自定义的值

b是你的变量

b=LoadInteger(pv,key1,key2,a)

上一篇:常汝言

下一篇:长沙绕城高速