![]() |
|||||||||||||||||||||||||||
|
[wiki系列] openmp/samp脚本基础 - 打印版本 +- samp | open.mp 联机社区论坛 (https://open-mp.cn) +-- 板块: SA-MP (https://open-mp.cn/forumdisplay.php?fid=12) +--- 板块: 教程 (https://open-mp.cn/forumdisplay.php?fid=17) +--- 主题: [wiki系列] openmp/samp脚本基础 (/showthread.php?tid=19) |
|||||||||||||||||||||||||||
[wiki系列] openmp/samp脚本基础 - 小鸟unsigned - 03-21-2026 [wiki系列] openmp/samp 脚本基础来自 SAMP Wiki 目录
入门!下面是一个可能最简单的脚本示例: 代码: #include <open.mp>我们将逐一讲解各个部分,先从第一行开始。 Include代码: #include <open.mp>这一行会把 qawno/includes/open.mp.inc 文件中的所有代码加载到你的脚本中,这样你就可以使用它提供的一切内容。其中它还包含了:代码: #include <args>这些文件包含了 open.mp(samp) 的所有核心功能,因此只需这一行,你就拥有了 open.mp(samp) 的全部函数(函数后面会详细说明)。 调用接下来是函数调用的两部分。 main() 是你自己编写代码的函数,由外部调用;print(string[]) 是代码在别处定义、由你调用的函数。目前这个脚本只会加载、打印一行字符串(即在服务器控制台输出 “Hello World!”,不带引号——这是所有脚本语言的传统),然后结束。代码: return 1;这条语句将值 1 返回给调用 main 的地方,告诉它执行结果(具体返回值在这里不重要,但在其他地方很重要)。你现在已经写出了第一个(非常基础)的脚本。如果你在 qawno 中选择“文件 → 新建”,它会给你一个更大的模板,包含所有回调(见下文),包括 main(严格来说它不是回调,但行为类似)。语句print 和 return 行都以 ;(分号)结尾,分号表示一条语句的结束(语句是一组函数和运算符的组合,用于完成某项操作,类似自然语言中的句子)。大多数人把每条语句写在单独一行,但这不是必须的,只是为了更清晰。下面这种写法同样有效:代码: main() { {}(大括号)用于将一组语句组合在一起执行(类似自然语言中的段落)。如果你写成:代码: main() 编译器会报错,因为 return 1; 没有被括起来,不属于 main 函数。大括号将多条语句组合成一条复合语句,而函数体只能包含一条语句。没有大括号时,print 和 return 是两条独立的语句,函数只能有一条,所以第二条语句就游离在函数之外,这是非法的。不过,你也可以用逗号运算符 , 来扩展复合语句,但不推荐这样做(不是最佳编码习惯)。示例如下:代码: main() 函数函数是一段完成特定任务的代码,可以从其他地方调用。它还可以将执行结果返回给调用它的地方。 调用代码: print("Hello World!");如“入门”部分所述,这会调用 print 函数(定义在 open.mp.inc 中,所以需要 #include),并让它在服务器控制台显示 “Hello World!”。函数由函数名(如 print)和参数列表(用 () 括起来)组成。参数列表向函数传递额外数据。如果没有参数,你就需要成千上万个函数:代码: printa();函数可以有任意数量的参数(从 0 开始,至少支持 128 个): 代码: printf("Hello World!", 1, 2, 3, 4, 5, 6);现在不用关心这个函数具体做什么,只需知道它有 7 个参数,用逗号分隔。 定义除了调用已有函数,你也可以自己编写并调用函数: 代码: #include <open.mp>这段代码功能与最初的示例完全相同,只是结构不同。当模式启动时 main() 被自动调用,它再调用自定义函数 MyFunction()。MyFunction() 在控制台打印消息,然后返回 1 给 main(),main() 再把这个值返回给服务器。因为 return MyFunction(); 是一条完整语句,你也可以写成:代码: #include <open.mp>但大多数人为了清晰起见还是分开写。你也可以完全不使用 MyFunction 的返回值:代码: #include <open.mp>参数参数是一种特殊的变量,你不需要自己声明,它来自调用函数的地方: 代码: #include <open.mp>这段代码功能相同,但现在我们把要显示的内容传给了 MyFunction()。调用时把字符串 “Hello World!” 传递给函数,存储在名为 string 的变量中([] 表示这是一个数组,后面会解释)。然后调用 print,把 string 的内容传给它(没有引号,所以它是一个变量)。变量变量本质上是内存中的一块空间,用于存储数据,可以随时读取和修改。变量由一个或多个 cell 组成,一个 cell 是 32 位(4 字节),默认有符号,可存储 -2147483648 到 2147483647(注意 -2147483648 在 PAWN 中定义不完善,显示时可能异常)。由多个 cell 组成的变量叫数组,字符串是一种特殊的数组,每个 cell 存放一个字符(打包字符串每个 cell 可存 4 个字符,但这里不讨论)。 声明要创建一个新变量,必须先声明它: 代码: new这会创建一个名为 myVariable 的变量,初始值为 0。赋值代码: new声明变量并设置初始值为 7。现在打印它会显示 7。要打印非字符串变量,需要使用前面提到的 printf():代码: new现在只需知道这会在服务器控制台输出变量的值(当前是 7)。 代码: new这段代码会先打印 7,然后把变量改为 8,再打印新的值。 变量操作示例(更多运算符请参考其他章节): 代码: myVariable = myVariable + 4; // 等价于数组声明数组是一种可以同时存储多个数据、动态访问的变量。数组大小在编译时就固定了,必须提前知道需要多少个槽位。最常见的例子是 MAX_PLAYERS 数组,每个玩家一个槽位,确保数据不会互相干扰。代码: new这会创建一个有 5 个槽位的数组。不能这样做: 代码: new因为 PAWN 在编译时就分配内存,数组大小必须是常量。 访问要给数组某个位置赋值,必须指定下标(index),下标可以是变量: 代码: new数组现在的内容是: 0, 0, 7, 0, 0注意:下标从 0 开始计数,而不是 1。 如果你尝试访问 myArray[5](超出范围),可能会导致服务器崩溃。下标可以是数字、变量,甚至是返回值的函数。 代码: new数组中的元素可以像普通变量一样使用: 代码: myArray[2] = myArray[2] + 1;示例最常见的数组是 MAX_PLAYERS 数组(MAX_PLAYERS 是一个常量,默认 1000)。下面对比用普通变量和数组处理 4 个玩家数据(假设 MAX_PLAYERS 为 4):传统写法(4 个变量): 代码: new数组写法(推荐): 代码: new数组写法无论玩家数量多少,都只需要一行代码,清晰且高效。 字符串基本用法字符串是一种特殊的数组,用于存放多个字符组成文本。每个字符默认占用一个 cell。字符串以 NULL 终止(遇到 0 就结束,不是字符 '0')。 代码: new这会创建一个可容纳 15 个字符的字符串,初始值为 “Hello World!”。内部实际存储为: 代码: 104 101 108 108 111 0 x x x x x x x x x x(0 是终止符,后面的 x 无关紧要) 你可以像操作数组一样修改字符串: 代码: new结果变为 “hallo”。 更易读的写法: 代码: myString[1] = 'a';单引号表示单个字符。 把某个位置设为终止符: 代码: myString[1] = '\0'; // 或 = 0;字符串会变成 “h”。 转义字符反斜杠 \ 是特殊字符,用于创建无法直接输入的字符:代码: new常用转义序列:
标签标签是变量的额外信息,用于定义其用途和可使用范围。标签分为强标签(首字母大写)和弱标签。 示例: 代码: newFloat 就是标签,表示这是一个浮点数(小数)。代码: native SetGravity(Float:gravity);这要求参数必须是 Float 类型:代码: SetGravity(6.0);使用错误标签会产生 tag mismatch 警告: 代码: SetGravity(MyTag:7); // 错误标签区分大小写。 你可以自定义标签: 代码: new myTag: variable = 0,直接相加时需要用 _: 去除标签,否则会报标签不匹配。作用域作用域决定变量在哪里可用。主要有四种:局部、静态局部、全局、全局静态。变量必须先声明后使用。 局部(local)在函数内用 new 声明:代码: MyFunc()局部变量每次进入函数都会重置: 代码: for (new i = 0; i < 3; i++)输出: 代码: 1静态局部(static local)与局部变量作用域相同,但值会在函数多次调用间保留: 代码: for (new i = 0; i < 3; i++)输出: 代码: 1全局(global)在函数外声明,可在任何函数中使用,且永不重置: 代码: new全局静态(global static)与全局类似,但仅限声明所在文件使用: File1.pwn 代码: staticFile2.pwn 代码: MyFunc2()static 也可用于函数,实现类似“私有”函数的效果。#GTA# #圣安地列斯# #侠盗猎车手# #圣安地列斯联机# #samp# #gta联机# #gtasa联机# #openmp# #omp# #open.mp# #gtasa# 社区交流群: 673335567 论坛: https://open-mp.cn/ |