前言 jass语言概述
0. 辣白菜做法教程对象
本教程适用于没有接触过计算机语言的人。由于jass祝福语格式非常简单,所以对学过一种中高级语言的人完全没有难度,而本教程对j语言的各部分都介绍的比较详细,所以没有必要学。如果只会用行号的basic(不包括vb、vbscript、ASP)的话,那还是看看这篇教程吧(不过可以略过很多部分)。
如果是完全没有接触过编程的话,建议第一遍通读,大体掌握jass语言的结构,然后再由基础到高级一步步的提高。
基础篇是对于语言的基本结构的介绍,首先要掌握好里面的关键部分,打好这个基础后,可以跟随高级篇里面的范例一步步的学jass的应用。
1. jass的特点
jass语言是一个语法非常简单的语言,语法结构上比较接近basic,同时也引用了许多c的东西。
2. 如何学习和使用jass
在trigger editor窗口中,我们可以很容易的把一个t转成j,方法是Edit(alt+e)->Conver to Custom Text(x),然后我们就可以在已有的j的基础上进行编辑。
由于we里的文本编辑器功能不够丰富,另外,we的容错机制比较差(j的错误太多容易导致直接关闭),所以这里推荐两个专门用于jass编辑的工具:jass editor(汉化版)和jass workshop(by soarchin)。两个工具各有各的特点,后面会在涉及到的部分提到。
另外还需要得到cj和bj两个接口函数库,这个在je和jw中均有提供
3. jass和trigger的关系
在地图编辑过程中,绝大多数用j能够完成的东西也能够用t来完成。事实上,所有的t最后都会转化成j,trigger只是面向we的独特体系。具体的说,war3提供的API有common.j和blizzad.j两个文件,其中com.j是纯粹的接口,而blz.j是对cj里面接口函数的封装,主要面向trigger editor,t生成的j代码中,绝大多数函数都是bj里的。
4. 为什么要学习j
a.用heavylock等工具压缩后,trigger和j面向we的部分被删除了,只留下script.j里面干净
的j部分,为了研究别人的map,就要能读懂别人的代码;
b.t虽然能完成几乎所有的功能,但是对于内存释放和另外一些功能实现的能力太差;
c.虽然t看似是一个语法结构完整的可读性比较高的语句,但是因为常常语句太长导致可读性大大下降,而j可以更方便的体现逻辑性,事实上j的可读性更强;
d.用j可以写出比t效率高很多的代码,当然这是在对计算机工作原理比较了解的前提下。
第一章 jass基础
0. 本章概述
本章介绍jass语言的最基本内容,包括注释、基本数据类型、变量、数组、基本运算符、运算的优先级、常量、基本运算法则
首先在这里说明一点,jass是区分大小写的,也就是说,jass不会认为“a”和“A”是同一种东西
-----------------------------------------
1. 注释(comment)
注释符号://
不论是we的语法检查器还是war3,“//”之后该行的内容将被忽略
----------------------------------------
2. 数据类型:
jass虽然不大,但是提供的功能足够丰富,共提供了6种基本数据类型:
1) integer : 32位有符号整数型(4byte) 取值范围:[-2147483648, 2147483647] (2^31+符号位)
2) real : 实数型(单精度浮点型,4byte) 取值范围:[1.5*10^(-45), 3.4*10^38]
3) boolean : 布尔型(1byte) 记录 true(真)或 fal(假)
4) string : 字符串型(不定长) 用来记录字符
5) handle : 数据指针型 是jass语法的一个基础类型,相当于passcal中的pointer类型,由它可以派生出其他数据类型的指针。用来指向内存中的一个数据地址
6) code : 函数指针型 用于指向内存中的函数地址
* 其他数据类型: 1.16有81种,1.17又新增5种,都是由继承handle而来,在common.j最
开始的部分,声明形式如下:
type ****** extends handle //此处即使不是handle,也是其他由handle继承而来的类型
-----------------------------------------
3. 变量:
知道了jass的基础数据类型,下面我们要了解如何使用这些数据。首先就是要对数据进行存取,基本的办法就是使用变量。什么是变量呢?就是war3在运行的时候在内存中申请一块数据空间,用来存取数据的。
1) 变量的类型:分全局变量和局域变量两种,在j中最常用的是局域变量
2) 变量的命名:
首先要给变量一个独特名字,作为这个变量的标志,以便在以后的使用过程中访问。
变量名称必须以英文字母开头,变量名中可以包括:大小写英文字母(A~Z, a~z)、数字(0~9)、下划线(_),其它符号会被认为非法(不要用中文命名变量名)。
we会自动给全局变量加上“udg_”前缀,在jass中使用全局变量的时候直接手动输入“udg_”前缀即可访问全局变量。
变量不得以关键字或已注册的名称来命名,例如:
jass: Copy code
local location local
//与关键字相同
jass: Copy code
local item item
//与已注册的变量类型重复
jass: Copy code 大小七孔旅游攻略
local force GetPlayersAll=GetPlayersAll()
//与已注册的函数重名
3) 变量的声明:在使用一个变量前,首先要告诉war3:“我要一块内存来存放数据啦!”这个时候就是对变量的声明。
在we中对全局变量的声明,是在edit(编辑)菜单中点击Variablies(变量),或者直接点快捷菜单按钮中的“X”按钮,添加、删除、定义数据类型的,而实际在map文件中,这部分变量会放在.j文件最开始的部分声明,形式如下:
globals
//说明:<>中的是可有的参数,()中的是必须的参数,之后还要用到这种形式鱿鱼须怎么做好吃
(type) (变量名) <= 初始值>
...
endglobals
对局域变量的声明,必须放在一段...(函数或过程)的最开始的部分,用location关键字开头来声明,全部局域变量声明结束后,才可进行函数的实体部分(这点和passcal比较类似):
... ***** takes **** returns ****
location (type) (变量名) <= 初始值>
...
4) 变量的优先级:
我们知道,可以在声明局域变量的时候增加udg_前缀,以便在t中方便访问。那么如果与
全局变量重名了会怎么样(可以与全局变量数据类型不同)?这个时候,在这个...中,在使用这个变量名的时候会代表location变量,也就是说,局域变量的优先级更高。所以不要使局域变量的变量名称与全局变量重名。
5) 变量的命名原则:
a、b、c、d都可以用来命名变量,但是当变量比较多的时候,怎样来在后面方便知道变量储存的东西呢?其实这个完全是个人习惯的问题,不过有一定的通用规则,可以帮助你方便的识别自己的变量的含义。
一般来说,首先要使变量名称有意义,例如,假如我们用一个integer变量来储存hero的strength(力量,强壮,不知道中文版怎么翻译的)值,我们可以把这个变量命名为strength。
第二步,通过大小写、前缀、后缀的差别来命名函数。一般用前缀来标示变量的类型,个人的习惯不同,命名的方式不同。例如刚才那个变量,按照通用的习惯,可以命名为intStrength,“int”前缀表示是整数型,大写的S用来区分词义。我个人的习惯是,integer型用i打头,real型用f(float,浮点类型)打头,string用s打头……
再次重复一遍,命名是个人习惯问题,如果你喜欢用a b c d dhfla tyy等等无意义的字母命名,也不会出现任何问题。但是不推荐这种方法,这样在有错误的时候给自己的阅读也带来很大的不便。当然,如果觉得自己英文不大灵的话,汉语拼音也完全ok小提琴音阶。
6) 变量的赋值:
声明好了变量之后,如何给变量设定一个值呢?有两种办法给变量赋值:
a. 在声明的时候加“=”,后面接变量值,在jass中,赋值的传递方向是把等号右边的传给左边,如:
jass: Copy code 晚安的说说
location integer i = 0
b. 在其他位置使用t关键字:
jass: Copy code
location integer i
t i = 1
* 补充:
在jass中,除了关键字和前后的空格与""中的空格外,其他的空格将被忽略。使用空格纯属个人编程风格的问题,为了美观或者区分括号(“(”“)”)的对应。在后面相关章节,我也会陆续介绍一些好的编程习惯。
A) 对integer(整数)型的赋值:可使用10进制、8进制、16进制和asc字符,如:
jass: Copy code
t i=65//十进制
t i=0101//8进制
t i=0x41//16进制,以0x或0X开头(10进制65)
t i='A005'//asc字符,写在单引号“"”之中,由4个字符组成,这个值是1,093,677,109
* 补充1:asc字符的命名主要是用来获取object editor(对象编辑器)中的内容,有两种方法看值,一种是在View(查看)菜单中选中Display Values As Raw Data(sorry我没有中文版不知道这个怎么翻译的)或者按ctrl+d,这时在oe的左边列表中的名称都变成了“****:XXXX (....)”(出现:XXXX为自定义的东西,XXXX是源ID,括号中的内容是那个技能的名称),这里的****就是这个东西的整数id。另外一种情况是,例如一个单位如果有技能,我们想知道这个技能的id,那么我们可以选中那栏,shift+enter,然后我们就看到了这个单位的技能id,中间是用“,”隔开的,例如locust技能(caster经常使用,用来取消caster的pathing(碰撞),使该单位不能被选去或击中)的id就是Aloc(注意区分大小写)
* 补充2:观察oe我们会发现,这些unit、item梦到车等等的id非常有规律,例如ability(技能)一定是A开头,buff(不知道怎么翻译更好)一定是B开头,upgrade一定是R开头等等。前面已经说过,integer是32bit的整数,这意味着这些ID的值一定会大于65*256*256*256,也就
是说,低30位的integer不会被表示成这些特有的id,符号位(表示正负号的,对于整数来说都在最高位)不会被这些id占用(z的asc码为122,小于128,即2^32这位不会被占用)。说的可能有点多了,而且对于实际来说可能没有什么意义,但是这里也充分说明了blz在做jass时的严谨性
B) 对real(实数)型的赋值:
t f=1 或 t f=1.0 //可以不输人小数点和小数位男性肝不好有哪些表现
C) 对boolean(布尔)型的赋值:只能去true(真)或fal(假两个值),注意区分大小写
jass: Copy code
t bool=true
t bool=fal
* 补充:在common.j(以后简称cj)中有如下声明
jass: Copy code
constant boolean FALSE = fal
constant boolean TRUE = true
这意味着全用大写也可以。
D) 对str型的赋值:写在双引号("")之间;如果想在字符串中使用双引号“"”,需要用\",如
jass: Copy code
t s="abc\""
3. 基本运算符与运算规则:
jass支持四则混合运算、逻辑运算、字符串运算,具体如下:
a. 四则混合运算: + - * /
适用与integer型与real型,其中/(除法)运算对整数来说,将表示整除,即返回整数部分,如7/2得到3,(-5)/2得到-2。另外,要小心0除数错误,war3有一定的容错机制,出现除数为0的时候,不会导致fatal,但是该语句之后的语句将不会被执行。
b. 逻辑运算: > < == >= <= != and or not
分别是 大于 小于 等于 大于等于 小于等于 不等于 与(且) 或 非
返回类型为boolean类型,即true或fal
现在用0代表fal,1代表true,讲解一下后三种运算:
and 0 1 | or 0 1 | not
0 0 0 | 0 1 | 1
1 0 1 | 1 1 | 0
*注意:后3种运算只用于boolean型,jass不支持位运算
c. 字符串运算:
使用“+”连接两个字符串
jass: Copy code
t s="a"+"b"
4. 运算的优先级:
a.对于四则运算:
与人们日常习惯相同,* /优先
b.对于逻辑运算:
符号 > not > and or
c.对于混合四则运算的逻辑运算:
四则运算 > 逻辑运算
如:15+4>9-1
d.提高运算的优先级:
使用括号“()”,在j中只能适用圆括号来表示提高运算优先级,方括号([])表示其他含义,花括号({})无意义。
* 注意:j只支持asc码,不支持中文字符(全角字符),如aB(=1等等,所以在使用j的时候,请尽量不要用输入法,如果使用,请确保不处于全角状态(一般快捷键时shift+空格,输入法有个图标会变圆,正常应该是月牙形)
最后要说明的是,使用括号不会降低运算速度,所以适量的使用括号可以提高代码的可读性。
-----------------------------------------
5. 常量:
顾名思义,就是用一个字符来表示一个固定的值,如PI(π=3.141592653589793)。jass
不支持居于的常量,而且也不支持手动添加全局常量,所以这里只做一个简单的介绍。
常量是只读的,换句话说,无法改变已定义常量的值。查看已定义的常量,可以用je或者jw选 constant 或 常量 来查看。常量也写在globals/endglobals之间,如blz.j的第一行:
jass: Copy code
constant real bj_PI = 3.14159
-----------------------------------------