AMX MOD X Documentation
Scripting Tutorial (Introduction & Pawn Language Basics)
– Translated by Shaman.Kaler
介绍
Pawn是一种“脚本”语言,用于将各种功能嵌入其他程序。这种语言共有两种,一种类似C或C++,是“汇编”语言,通常是用于输出可执行二进制文件;另一种是“解释”语言,通过虚拟机动态地运行代码(VB那样的—译者注)。AMX Pawn是两者的混合体:写AMX是解释型的,但编译过程是汇编的。(说明了为什么amxx文件没法打开,因为是汇编语言—译者注)
在你开始编程之前你要知道一些重要的结构。第一是“变量”。变量可以说是含有数据的一个符号或记号(symbol or marker,中文太相似了—译者注)。比如,变量a可能会含有值2、16、0等等等等。变量是一个程序创造的存储空间,在使用前必须声明它们的名字(和类型)。给予变量数据称为“赋值”。变量的赋值使用的是一个等号:
new a,b,c,d //这里是 声明
a=5 //把a赋值为5
b=16
c=0
d=500
另一个重要的概念是函数。函数是完成某种功能时引用的符号或记号。这意味着当你使用它们时,它们会处理你所给的数据(“传递”的数据)。函数有几种,但是使用
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
是一致的。例如,”show”函数把一个数字显示在屏幕上:
show(56) //启动”show”函数, 并传递数据”56”。
show() //启动”show”函数, 没有数据(或不需要数据)。
show(a) //启动”show”函数, 并传递变量a包含的数据。
注意任何前面带有”//”符号的文字都属于“注释”,不是真正的代码。任何传递给函数的数据都被称为“参数”,一个函数可能有任意多的参数,你必须保证你所传递的每个参数的正确性。如果一个函数需要两个数字,你就不能给它两个字符串。函数可以“返回”数据,比如:
new b
b = add(5, 7)
这个例子中,如果”add”是一个把两个数字相加的函数,那么变量b的值就是12.是吧?
最后一个概念就是“大括号式”编程。你可以把程序代码用”{”和”}”括起来作为一个整体。比如:
{
这里是
一堆代码
}
一旦有可能的话就要
练习
飞向蓝天的恐龙练习非连续性文本练习把字句和被字句的转换练习呼风唤雨的世纪练习呼风唤雨的世纪课后练习
用这种方式编程,把代码括成一个个单独部分。
当你读完这些时,你应该有了一点AMXX编程的基础。恭喜。
Pawn语言基础
(这一段真是杀了人的多……翻译还在继续……--译者崩溃中)
1、变量
Pawn是一种可捆绑的,(几乎)不需要输入的,便于使用的脚本语言,为虚拟机而汇编。(定义可以直接省略,真的—译者注)AMX Mod X用Small语言使各种功能在HL引擎中实现,使用Small虚拟机和Metamod(Small是用C写的,Metamod用的是C++)。当你把Small脚本写好之后可以用“编译器”把脚本编译成AMX Mod X二进制文件(amxx插件)。AMX Mod X小组提供特殊的Small编译器(amxxpc.exe)。
Pawn的编程脚本相对简单,没有一些其他语言中的例如指针、类、数据流等等的概念。Small只有三种变量数据类型。默认的变量类型是整型(integer),就是一个整数。为了兼容以往的版本,变量名称不得超过19个字符,而且必须以字母开头。可以包含A~Z,a~z,0~9和下划线”_”。变量名是区分大小写的,”myvar”,”MyVaR”和”MYVAR”是不同的三个变量。要声明一个变量,使用new方法:
new a //声明一个空的变量"a"
new b=5 //声明一个变量"b"并赋值5.
new c=5.0
//这是错误的,5.0不是整型!(带有小数点是浮点型!)
new d="hello" //"hello"是个字符串,因此也是错误的。
//一行之内允许声明多个变量:
new e,f,g,h
new x=7, y=3
你也可以把一个变量声明为“浮点型”,这意味着变量可以储存带有小数部分的数字。也就是“浮点”数:
new Float:a //声明一个空的浮点型变量a。
new Float:b=5.3 //声明一个浮点型变量b并赋值5.3。
new Float:c=5 //这是有效的,但编译器会给你个warning。
new Float:d="hello" //这是无效的!”hello”是个字符串。
你也可以做下面的这些:
// float(n)是个把整型变为浮点型的函数。
new Float:var = float(5)
new Float:var2 = 5.0
new Float:var3 = 1.0*5
new var4 = floatround(5.0)
//注: floatround(n) 是把浮点型变为整型的函数。
//这使得通常的整型声明也有效了。
注:有没有空格通常是无关紧要的,编译器可以把符号和内容分开,但是如果你省略得非常过分,编译时就会出现error和warning了。例如”new var = 5”和”new var=5”是一样的,但”newvar=5”就是错的了!
最后一种就是“布尔型”,它的值只会有“True(真)”或“False(假)”。默认是“False”。
new bool:IsItOn //声明一个新的布尔型变量“IsItOn”,并设为“False”
new bool:xyz=true //声明一个新的布尔型变量“xyz”,并设为“Ture”
2、数组
Pawn拥有基础的“数组”。数组是存储组织数据的一种重要方法。这意味着你可以在一个变量中存储多个数据。数组和变量遵循同一规定,有同样的类型,数组只是单纯的可以多存储几个数据而已。用中括号”[”和”]”来声明数组与数组的容量(容量必须是固定的)。例如:
//声明一个Players数组,容量为32(可存储32个数据)。
new Players[32]
//现在就可以往数组的32个空间里传递数据了。
//空间的索引从0开始,到n-1结束。这里就是0~31啦。
//每个空间的默认值都是0.
//把空间0设成5.
Players[0] = 5
//把空间1设成和空间0一样的值,这里就是5
Players[1] = Players[0]
//注意下面的是无效的!
//虽然有32个空间,但最多只到31号!
//这会导致AMX Native Error 4 - AMX_ERR_BOUNDS
//或者压根就无法编译!
Players[32] = 15
//这个自然也是无效的。
Players[-1] = 6
//下面的也是无效的,a必须为常数。
new a = 3
new BadArray[a]
//这样就正确了,const代
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
常数(无法再被赋值)。
const b = 3
new GoodArray[b]
//你甚至可以使用define的数据来声明数组
#define ARRAY_SIZE 3
new Array[ARRAY_SIZE]
数组也可以直接声明并赋予所有的数据:
new Numbers[4] = {0,1,2,3}
//注: 确保数据个数与数组容量的一致!
数组也可以使用各种数据类型:
//浮点型的数组:
new Float:Numbers[4] = {0.0, 1.2, 2.4, 3.8}
//布尔型的数组:(这会把所有数据设成True)
new bool:playerHasGun[32] = true
3、字符串
你可能注意到了还有一种数据类型没说呢……没错,就是字符串。在Pawn里,字符串,也是通过数字存储的。
//下面声明了一个数组"myString"包含数据"Hello".
//有五个字母,就需要六个空间.
//最后一个空间设置成0,告诉Pawn引擎这是字符串.
new myString[] = "Hello"
//注: 在 /* 和 */ 之间的也是注释.你不能在 /* */ 里面再来一个 /* */.
/* 下面的命令也能做到存储”Hello”,但是用起来麻烦,不推荐使用。*/
new myString[6]
myString[0] = "H"
myString[1] = "e"
myString[2] = "l"
myString[3] = "l"
myString[4] = "o"
myString[5] = 0
/*你不可以使用下面的命令!这可能会在编译时产生数据溢出!*/
new myString[6]
myString = "Hello" //无效!(少了[]就是在一个变量里存一个数组)
myString[0] = "Hello" //无效!(在一个空间里存了一个数组)
//想要在字符串里添加数据,可以使用Copy命令:
new goodString[6]
copy(goodString, 6, "Hello")
//Copy共有三个参数:
copy(destination[], length, source[])
//它把源字符串的内容复制到目标数组中,但只复制最多length个字符。
//最后,为了证明字符串是用数字存储的:
new weird[6]
weird[0] = 68
weird[1] = 65
weird[2] = 73
weird[3] = 86
weird[4] = 68
weird[5] = 0
//这会把变量weird赋值”David”.
//想知道字符和数字如何换算,请访问www.asctiitable.com
4、函数
Pawn允许你定义自己的函数。这就可以在很多地方省略很多相同的语句。注意函数必须有返回值,使用return命令,将会直接停止函数运行并将处理结果传递出去(前面曾说过“可以返回数据”,这里注意是“必须”有返回值,因为返回的不一定是“数据”—译者注)。注意当return被执行后函数就会强制性停止。这里是一些例子。
//这是一个不需要参数并直接返回1的函数.
//引用时, 这个函数调用(事实上并不存在的)print命令.
show()
{
print("Hello!")
return 1 //结束,返回1
}
//像这样引用:
show()
你也可以使函数变得需要参数:
//声明一个叫做"add_two_numbers"的函数, 用于求两数之和.
add_two_numbers(first, second)
{
new sum = first + second
return sum //返回sum
}
//然后就可以引用你的函数了:
new a,b
a = 5
a = 12
new c = add_two_numbers(a,b)
//c 现在就应该等于 17.
在参数类型方面是没有限制的。当你把参数给予一个函数时,这个过程称为“传递”(这个定义居然到现在才出现—译者注)。传递的可以是数据,也可以是变量:
//声明一个叫 "add_two_floats" 的函数,对两个浮点数求和。
Float:add_two_floats(Float:first, Float:second)
{
new Float:sum = first + second
return sum
}
new Float:a
new Float:b
a = 5.0
b = 6.3
new Float:c
c = add_two_floats( a+b )
//c 现在应该等于 11.3
//你甚至可以传递数组!而且数组的大小不必确定.
//如果你确定了,那么引用函数时就必须传递相同容量的数组.
add_two_from_array(array[], a, b)
{
new first = array[a]
new second = array[b]
new sum = add_two_numbers(first, second) //使用我们之前创造的函数
return sum
}
注:当你把数组传递到函数时,使用的是“引用传递(by Ref)”,不像变量传递时是“值传递(by Var)”。这意味着你传递一个变量a时,是把变量a的值拷贝到内存,传递值,运算,然后删除值,原先的变量a不会变,而当你传递数组时,数组是直接引用过去的,函数过程之后数组会保持函数造成的变化。例如:
//这个函数把传递的数组空间a和空间b对调。.
swap_slots(array[], a, b)
{
new temp //注意你必须有个临时变量存储其中一个数据,
//否则你就不能交换!这是个经典问
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
。
//假设有a和b,让b = a后b原有的数据就被覆盖了。
temp = array[b]
array[b] = array[a]
array[a] = temp
}
new myArray[2]
myArray[0] = 5
myArray[1] = 6
swap_slots(myArray, 0, 1)
//myArray[0] 是 6, myArray[1] 是 5
//你也可以通过声明为常量来防止数组被修改:
add_two_from_array(const array[], a, b)
{
new first = array[a]
new second = array[b]
new sum = add_two_from_array(first, second)
return sum
}
//注:现在这个数组就不会变化了。.
//这个函数想要对常量赋值,自然不会工作。
bad_function(const array[])
{
array[0] = 0
}
(这个部分比较困难,多看几遍你会懂的。--译者注)
5、表达式
就像听起来那样,和数学上的表达式没什么区别。通过运算符来计算并返回一个数据,就是表达式(遵循运算法则)。你可以把表达式放在任何地方,也可以对变量进行操作。
//最简单的表达式,返回0.
0
//如果为了读起来方便,也可以写成这样:
(0)
当一个表达式不是0或False时,它除了会返回值外还会返回一个True。
//下面是一些数学表达式与符号:
// + 表示相加
// - 表示相减
// * 表示相乘
// / 表示相除
// % 表示求余数
(5+6) //返回 11
((5*6)+3) //返回33
((((5+3)/2)*4)-9) //返回5
((5*6) % 7) //返回2
//另一些表达式:
(true) //返回true
(5.0 + 2.3) //返回7.3 (浮点数)
//还可以直接对变量赋值:
new a = 5
new b = 6
//下面是前/后加减的方法:(非常之困难+有争议—译者注)
a++ //返回 a+1, 或 6. 后加加.
++a //也返回 a+1, 或 6. 前加加.
区别很简单但是很重要。a++是先使本身为a然后计算a+1最后赋值a = a+1,而++a是先使本身为a+1然后赋值a = a+1。(也就是a++的返回值是a,但会使a变成a+1;而++a的返回值是a+1,a也会变成a+1—译者注)
a-- //返回 4, 后减减
--a //返回 4, 前减减
//注:a++相当于下面的:
a = a + 1
//还有一种写表达式的方法:
a = a OP y
//其中OP 代表运算符. 这种形式可以精简为:
a OP= y
//观察:
a += 1 //a = a + 1
a -= b //a = a - b
a *= 0 //a = a * 0
a /= 2 //a = a / 2.
运算符并不只是给出的那几个,还有布尔运算符:
//&&(and,与)运算符运算左右两个布尔值.
//只有全为真时返回真.
(1 && 0) //返回false, 因为1返回true而0返回false.
(1 && 2) //两个数字都是 "true", 因此返回true.
(true && false) //false
(false && false) //false
(true && true) //true
//另一个就是||(or,或)运算符,两者有一个为true就返回true.
(1 || 0) //true, 因为1是true.
(1 || 2) //true
(true || true) //true
(false || false) //false
(true || true) //true
下面是不太常用的“按位”运算符,比较的是二进制数据。例如“按位与”运算符&比较9(1001)和8(1000)时,每一位进行比较,1and1,0and0,0and0,1and0,其结果为(1000)也就是8.
//返回8,如上面所说.
(9 & 8)
//4 (00100) 按位与 16 (10000) 返回(00000)也就是 0.
(16 & 4)
//下面是另外一个"按位或"运算符|
//对每一位二进制进行 或 运算得出结果。
// 9 (1001) 按位或3 (0011), 结果是1011, 或者 11.
(9 | 3)
这两个“按位移动”运算符<<和>>也很重要,但不常用。他们按照一定的方向移动二进制数位。
//把 3 (00011) 的二进制左移三位成为(00011000)即 (11000), 或 24.
(3 << 3)
//把 24 (11000) 的二进制右移三位成为 (00011), 即 3.
(24 >> 3)
最后的是“按位非”运算符(此时才发现前面没有说明!即感叹号代表非—译者注)。即把0变成1,1变成0,T变成F,F变成T。
//返回 false
(!true)
//返回 true
(!false)
//将 9 (二进制 1001) 变成 6 (二进制 0110).
(!(9))
6、条件
条件语句使你可以判断一个表达式是否达到一定的标准,然后根据情况执行一定的语句。最常用的条件语句称为”if…then”。它会判断条件是否为真,如果为真则执行一段代码,不为真,执行另一段代码。例如:
这是一个最基本的if…then格式,当a的值为5时执行对a赋值6:
if (a == 5)
{
a = 6
}
如果a不是5怎么办?代码就不会被执行,除非你告诉它当条件不满足时该怎么做。这里当a不是5时会被赋值7:
if (a == 5)
{
a = 6
} else {
a = 7
}
事实上if…then结构中可以使用任何形式的表达式:
//a不是 5 时返回 true
if (a != 5) {
//a 比 5 大 时返回 true
if (a > 5) {
//同理:比5小时
if (a < 5) {
//大于等于 5
if (a >= 5) {
//小于等于 5
if (a <= 5) {
//返回true 因为 11 是 true
if (5+6) {
//当a && b 为 true 时返回 true
if (a && b) {
//如果7.5 比 c 大时返回true
if ( ((5*3)/2) > c) {
//总是返回true
if (true) {
//永远不返回true
if (false) {
注意数组的比较是有严格条件的,下面是无效的表达:
my arrayOne[3]
my arrayTwo[3]
if (arrayOne == arrayTwo) {
你必须:
if ((arrayOne[0] == arrayTwo[0]) &&
(arrayOne[1] == arrayTwo[1]) &&
(arrayOne[2] == arrayTwo[2])) {
显然这种方式在比较大型数组的时候会非常繁杂,如何快速比较数组和字符串将会在后面提到。
If…then结构还可以提升到更高层次,Pawn提供了多级条件比较的方法:
//"if...else if"结构的例子
if (a == 5) {
//a 是 5 的时候执行的代码.
} else if (a < 6) {
//a 比 6 小的时候执行的代码
} else if (a == 7) {
// a 是 7 的时候执行的代码.
} else {
//以上条件均不满足时执行的代码.
}
需要注意的是If多级判断时不是从上到下一个不漏的,而是会按照顺序判断,如果有一个是true,代码会被执行然后会退出if结构,不会出现很多个true条件的代码都被运行的情况。
最后要说的是特殊的判断结构,称为”switch”结构,允许对一个列表的条件进行判断,却和if…else if…一样有效:
//switch的例子
switch (a)
{
case 5:
{
//a == 5时执行
}
case 6:
{
// a == 6时执行
}
case 7:
{
// a == 7时执行
}
default:
{
//如果其他条件都不满足
}
}
和If一样,switch最多也只会执行一块内容。
7、循环
对于任何编程语言循环都是重要的。循环允许你把一段代码一遍又一遍的运行,如果情况决定必须重复运行的话。
第一个也是最常见的循环是“For”循环,给定一个起始条件,一个结束条件,和一个步进方法,就会把一段代码重复执行直到条件不满足为止。因此你可以用”for”循环使一段代码执行固定的次数:
/*一个for循环有三个参数:
for (起始条件; 条件; 步进)
{
//代码
}
在第一个循环执行前,for会判断起始条件.
然后就以下面的步骤循环:
1. 条件是否为真,如果为真,再来一遍;如果为假,退出循环.
2. 运行代码.
3. 运行步进部分.
4. 回到第1步.
*/
//for循环的例子
new i
new sum
for (i=1; i<=10; i++)
{
sum += i
}
解释:
· 第一个参数i = 1把变量i的值赋为1. 发生在循环开始之前.
· 下一步,检查步进部分. 这个参数是个后加加,因此一个循环后i会被赋值i + 1.
· 接着检查条件. i小于等于10么? 现在是1, 因此这个条件是true.
· 由于条件是true , sum+=i被执行了,这意味着sum被赋值 sum + i.
· 代码执行完成, i++把i变成2.
· 又来了一遍.
· i小于等于10么? 没错,i是2. 现在 sum+=i 又执行了一遍, 因此sum == 3了.
· 代码执行完毕,i现在是3.
· 不断的重复直到...
· i到达了11. 条件不满足了,于是for循环结束.
· 现在sum是55. 也就是从1加到10.
这就提供了比较数组的简单方法!
sum_of_array(myArray[], size)
{
//注:确保用户提供了数组容量size,这样我们就不会产生溢出错误.
new i, sum
//这个循环从0开始到数组的容量size时结束.
//如果用户传递的容量正确,
//循环就应该从 0 到size-1
//正好是数组中所有的数据.
for (i=0; i
书
关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf
能够早日做成!
小克)