
1. 介绍
Pawn 语言是一种跨平台的脚本语言. 我们常看到两种类型的语言, 一种是"编译"语言, 例如: C 和 C++. 一种是"解释"语言, 像 VB Script. AMX Pawn 语言是两者的混合体: 将脚本编译成二进制文件, 并由 AMXx 来解释它.
当然, 在编写你的脚本之前, 你必须先知道几种结构.
第一是 "变量".
变量是一个符号或者标记用来保存数据. 例如:变量 "a" 能够保存数字 "2", "16", "0", 等等. 变量由程序创建一个空间让你保存数据. 你必须在使用它们之前先定义你的变量. 变量用 = 号来赋值:
new a,b,c,d
a=5
b=16
c=0
d=500
第二是 "函数". 函数是一个符号或者标记, 当你调用它的时候, 它就会执行一些操作. 这意味着当你调用它们的时候, 它们将会处理你提供给它们的数据.
函数有几种类型, 但是调用的方法还是类似的. 例如: "show" 函数输出几个数据到屏幕上:
show(56) //激活 "show" 函数, 并将值 56 传递给它
show() //激活 "show" 函数但是不传递数据给它
show(a) //激活 "show" 函数, 并将变量 a 的值传递给它
注意, 任何以 "//" 开头的文字都属于注释.
你所传递给函数的每一个数据都称之为 "参数". 一个函数可以有几个参数, 而你必须保证传递给函数的参数数据必须正确.
如果参数是两个数字, 你就不能传递一个单词.
函数也可以返回数据, 像这样:
new b
b = add(5, 7)
在例子中, 假设 "add" 是一个将两个数字相加并返回和的函数, 变量 "b" 的值将为 12.
第三个概念是 "代码块", 也就是结构化. 你可以将一段代码用 { 和 } 符号合并成一个代码块.
例如:
{通常我们习惯尽可能地使用代码块, 并将代码块里面的代码缩进.
here
is
some
code
}
以上是介绍 Pawn 语言的背景.
2. Pawn 语言基础
目录:
1. 变量Pawn 语言是一种可嵌入的, 几乎无类型的, 容易使用的虚拟机脚本语言.
AMX Mod X 使用 Pawn 语言传递函数到 Half-Life 引擎, 使用 Pawn 虚拟机和 Metamod (Pawn 是用 C 写的, Metamod 是用 C++ 写的).
当你写完脚本之后, 必须用 AMX Mod X 提供的编译器编译成二进制文件. AMX Mod X 小组在每一个版本都有随之分发.
用 Pawn 语言来编写脚本是很容易的, 并且不需要使用其他语言用不到的概念, 例如 指针, 向量, 结构, 类, 流, 等等.
Pawn 语言只有三种数据类型. 默认的数据类型是整数. 一个变量名不能大于 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
你也可以用 "Float" 关键字定义一个浮点数, 即带有小数部分的整数. 定义方法如下:
new Float:a //定义一个浮点数变量 "a"
new Float:b=5.3 //定义一个浮点数变量 "b" 并赋值为 5.3.
new Float:c=5 // 这样虽然合法, 但是编译器会出现一个警告信息.
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) 是一个将浮点数转换为近似整数的函数.
注意 - 空格的多少并没有什么关系, 编译器会处理. 但是也不能太离谱, 例如: "new var = 5" 和 "new var=5" 是相同的, 但是 "newvar=5" 就完全错了.
最后一个数据类型是逻辑值. 只有 "真" 和 "假" 两个值.
new bool:IsItOn //定义一个逻辑值 "IsItOn", 默认为 "假".
new bool:xyz=true //定义一个逻辑值 "xyz" 并赋值为 "真".
2. 数组
Pawn 的其中一个功能: 数组. 数组是一组数据的集合. 这样你可以在一个变量里储存多个数据!
数组的定义方法和普通变量一样, 并且类型也和普通一样. 它能包含多个数据. 用括号 [] 来定义数组的元素数量, 例如:
//定义一个 32 个元素的数组 "Players"
new Players[32]
//你可以使用数组中的任何一个元素, 每个数组的元素的位置都是由 0 到 n-1
//每一个数组的元素的位置都是从 0 开始的.
//为数组的第一个元素赋值 5
Players[0] = 5
//令数组的第二个元素的值为第一个元素的值
Players[1] = Players[0]
//以下是不合法的!
//虽然数组有 32 个元素, 但是元素的位置是 0 到 31.
//这样做会出现 AMX_ERR_BOUNDS 错误.
//或者, 无法编译.
Players[32] = 15
//这样更不合法了.
Players[-1] = 6
new a = 3
//以下这样做也是一样不合法.
//a 必须是一个常数, 在这里 a 是一个变量:
new BadArray[a]
const b = 3
new GoodArray[b]
//你也可以使用 编译器指令 (见最后一章)
#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 语言里, 他们只是一些数字!
一个字符串是一个 ASCII 字符的数组. 例如:
//定义一个字符串 "myString" 包含字符 "Hello".
//它将有 6 个元素, 因为它包含了 5 个字符.
//最后一个元素保留为数字 0, 这样 Pawn 引擎就可以知道这是一个字符串.
new myString[] = "Hello"
//注意: 任何在 /* 和 */ 之间的文字都属于注释. 你不能在 /* */ 里包含另一个 /* */.
/* 以下做法的结果和上面一样, 但是, 复杂的多, 所以我们不推荐你这样做.*/
原理是 "Hello" 的每个字符串保存在 myString 数组中.
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" //INVALID!
myString[0] = "Hello" //INVALID!
//如果你想添加一个字符串, 你可以这样做:
new goodString[6]
copy(goodString, 6, "Hello")
//copy 函数可参见 点通 AMXx 常用函数汉化小组 汉化的函数文档.:
copy(destination[], length, source[])
//最后, 为了证明字符串只是一个包含数字的数组, 请看以下例子:
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" 命令, 用来中止函数并返回值.
例如:
//这个函数没有任何参数, 并且返回 1.
//当使用的时候, 它执行了一个实际上不存在的函数 "print".
//这只是作为例子.
show()
{
print("Hello!")
return 1 //End, return 1
}
//使用方法:
show()
你也可以定义需要参数的函数.
//以下定义了一个函数 "add_two_numbers", 将两个数字相加.
add_two_numbers(first, second)
{
new sum = first + second
return sum //Return the sum
}
//你可以这样使用它:
new a,b
a = 5
a = 12
new c = add_two_numbers(a,b)
//c 将等于 5 +12 = 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 将等于 5.0 + 6.3 = 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
}
记住, 数组是使用 "引用传递" 机制.
当我们传递一个普通的值的时候, 它将先复制到内存中, 然后传递给函数, 之后删除.
但是在传递数组时, 由于数组可能非常大, 所以使用 "引用传递" 机制.
这意味着如果你在函数里改变了数组的值, 原先的数组也会改变.
例如:
//这个函数将交换数组里位置 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
//你可以通过使用 "const" 关键字来防止数组的值被改变, 像这样:
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
}
下载地址:http://www.qiannao.com/space/show/niuyanbin/上传分享/2009/5/2/1000多个SMA.rar/.page
[此贴子已经被作者于2010-5-12 12:30:41编辑过]