@sogouwap
2019-08-13T08:51:31.000000Z
字数 7837
阅读 14665
AMXX插件全名为AMXMODX
,是基于半条命HL这款游戏开发的可扩展的模块,这个模块由国外大佬编写,可安装到到反恐精英CS
上,可通过后期编写插件来实现原本反恐精英CS
没有的效果。
可以实现的效果包括但不限于
- 火箭筒、导弹、追踪类导弹
- 游戏数据修改(生命值、攻击力、防御力等)
- 新增武器
什么是基础模块?
很多事情都必须要有基础才可以实现,比如说建立大楼需要有地基
,那么插件也是一样,如果没有基础模块就无法安装插件。
反恐精英CS1.6
~
键 打开控制台,接着输入 amxx
接下来你会看见控制台返回的信息
一般而言,控制台会返回的信息只有两种
这代表 反恐精英CS1.6
没有安装插件。
你可以 点击这里下载
- 首先下载上述文件
- 找到
反恐精英1.6
游戏所在文件夹(如X:/CS1.6
)- 将压缩包里面的文件替换到
X:/CS1.6/cstrike
,选择全部替换X:/
代表你的CS所在磁盘,并不是指定是X盘
。
至此, 你的反恐精英CS1.6
插件模块(AmxModx)
已经安装完成。
这意味着 反恐精英CS1.6
这款游戏的插件模块已经安装完成。
接下来你可以安装单独的插件了,安装独立插件的这个过程分为两步
- 打开
反恐精英CS1.6
然后找到cstrike
文件夹- 在上述位置找到并打开
addons/amxmodx/configs/
文件夹。然后找到plugins.ini
配置文件- 使用 "记事本" 打开配置文件,在该文件中最后一行通过回车新建一行写入 "插件的名字"
例如 :111.amxx
这样的名字
注意:
配置文件中,插件的名字不能写中文名,不然会无法读取插件。
我们知道插件可以安装进去,可是插件是怎么得到的?
这里我们需要先了解一下编译器
我们知道AMXX是插件文件,可是他是怎么来的呢,你也许会说:“这么简单,网上下载就是“,那有没有想过网上的插件是怎么来的呢。
其实,任何插件都是通过编译器得到的。
编译器就是将我们写的程序,比如用C, JAVA, C++, 汇编等语言写的程序,经过编译器的转换,把这些语言转换成计算机或者微型处理器能够识别的机器代码,它是由0和1以组成的序列,说白了,就是相当于英语翻译成中文的工具一样。
你可以在 [ 链接:https://pan.baidu.com/s/1c4ez9i4 密码:d1m6 ] 这里下载编译器,下载完成后可以解压到一个新建文件夹中以备用
compile.exe
文件上,然后放开鼠标compiled
文件夹。每个源代码中由不同的代码块组成,大致包含以下内容:
头文件定义通常在源代码中的最顶部,关键字为 include < 模块名>
的内容,这就是模块定义。
他至关重要,是整个源码的心脏。插件的代码由头文件所定义的代码来编写,不在头文件包含的代码,是无法被编译器编译的。
通常常见为:
#include <模块名>
插件使用什么 模块
中的代码进行工作,就在这里定义
常用模块:
基础模块,必须定义。
他内置了大量代码来让开发者无比强大
代码:
#include <amxmodx>
这个模块比较适合新手,可以用简单的代码实现常用效果
代码:
#include <fun>
不太常用的模块,他提供的代码非常复杂,不推荐使用这个
代码:
#include <engine>
这个模块我们简称为 FM (取自 FakeMeta 的大写首字母)
可实现绝大部分的功能,是一个非常常见的模块
代码:
#include <fakemeta>
此模块我们简称为 Ham (取 Hamsandwich的前三个字母)
可实现绝大部分的功能,是一个常用的模块
代码:
#include <hamsandwich>
可实现大部分功能,是一个比较常用的模块
#include <cstrike>
变量是对“值”的引用,使用变量等同于引用一个值。每一个变量都有一个变量名。
new a
上面的代码声明新建变量a
为了方便理解,我们可以把变量想象成一款水杯
当然并不是所有水杯都一样,比如 "玻璃杯",“不锈钢杯”,等等。
所以变量也分为几种可定义的类型,分别是:
这是一种在函数内部的变量,通常其他函数无法读取
临时变量看起来像这样:
public test( )
{
new abc
}
上述例子中的 abc
即为临时变量,如果不特殊处理
。将无法被其他函数获取值
全局变量不同于临时变量,他可以被其他函数所获取,通常用于变量判断,如:“是否这局已经使用过了"、"当前累计的造成的伤害是多少","保存以及存储的坐标",等等。
这种变量通常写在 注册部分
的上面,并且 不处于函数内部
一般看起来像这样:
#include <amxmodx>
new LaveSpace //定义的全局变量
public plugin_init()
{
register_plugin("test", "1.0", "Test Plugin")
}
常见位置处于
#include
和plugin_init()
的中间
上面的 `LaveSpace` 就是全局变量
而除了上面两种变量类型,还有其他一种变量类型可以来组合搭配
除了临时变量
和全局变量
,这两种外。
还有一种叫浮点变量
,他可以配合 临时变量
和 全局变量
来使用,是一种组合型的变量。
浮点是很常用的一种变量类型,和普通变量的区别是:这种变量他只能存储浮点数(带小数的数,比如 12.5
)
代码看起来像这样:
new Float:变量名
技巧:
- 浮点变量标记Float
的大小写不要写错了,不然会出现编译错误。
这种变量又不同于浮点变量,但他可以以 "临时变量"或"全局变量" 的形式存在。
此变量仅有两个标记方式:
new bool:变量名
true 代表是的、真
false 代表否定、假
我们可以通过下面的代码进行标准型判断
new bool:atp
public aa()
{
//如果atp变量为真
if(atp == true)
{
}
//反之如果atp变量为假
else if( atp == false)
{
}
}
注意:
布尔变量
和浮点变量
是独立的两个变量类型。
要么用布尔变量,要么用浮点,仅仅只能选择一种
函数的英文名为 function
,也就是功能。
打一个简单的比方:
"在超市买散装食品的时候,你需要一个口袋,将口袋把散装食品装起来,然后去称称。然后就可以得到一个标签,贴在这个口袋上,收银员会扫描这个标签上的条形码,来获取称称时的价格
理解方法:
"散装食品" 我们就可以理解为许多许多的单个代码,而 "口袋" 就是将 "单个代码" 封装了起来,变成了一个 "方便拿走" 的东西(即功能)。
在源代码中,函数一般以 public
开头,例如:
public 函数名 ()
同理,”函数名“ 也可以像 ”变量名“ 那样由你自己去定义。
函数可简单分为三种类型
这是很常见的函数类型。
比如说:
public 函数名()
函数名可以由你自己去写,但需要你自己记得住
这种变量是一种比较特殊的变量
他不同于公用函数,这种变量没有 public
定义部分
他的代码仅仅是:
函数名()
有疑惑?
不用担心,这种方式比较少见,一般不这样写
这是一种特殊的函数,他不同于非公用函数和公用函数
他只在被其他代码调用的时候才被读取,除此之外他都以注释代码段的方式存在。
stock 函数名()
注意:
- stock函数的内容,只在有其他函数调用的时才会被读取并触发。
- stock函数在没有被触发的时候,即使里面有错误也不会影响编译。
比方:
就如一个人的名字一样,可以让你知道 “他” 是谁
索引是用于函数传递信息用的一种标识。
一般由 ”触发者“ 所引用,他的位置常见处于函数名字后面的括弧内
比如说:
public test( 索引 )
因为可能函数会同时传递多个参数,所以不止一个。
比如说:
public addhealth(id, health)
{
}
提示:
"索引" 又可以称为 "参数",但参数不一定是索引。
来自 "百度百科" :
字符串或串 (String) 是由数字、字母、下划线组成的一串字符
在代码中,含有 “ “
(双引号) 的内容就是字符串
比如说:
"你好"
"Hatsune Miku"
“厉害了我的哥6666“
“你在这局已经购买了这个道具,无法再次购买“
“139659650“
提示:
对于 ”字符串“ 没什么太多限制,不过要注意的是,字符串必须两边都有""
(双引号),不然会造成编译错误。
来自 "百度百科" 的解释:
数组是一种存放一组值的集合,这组值可以是数字、字符串或者其他东西
之前我们说了变量,可以用水杯来代替,那数组怎么通过这种方式理解呢
那就是水杯里面装的 "水"。
水装的多少可以理解为 “数组” 内的大小
数组中可以存储值,而数组又是在变量基础上来存储的,所以必须要有变量才能存储 "数组"
数组的作用是来存储每个玩家或每个实体的单独数据。
为什么要单独存储?因为如果仅仅用一个变量来存储所有玩家的数据,那么就会导致,上一个玩家的数据被下一个玩家的数据所覆盖,这是无论如何也不想发生的事情。
这时候就要用到数组来解决
一个变量可以存储一名玩家的数据,如果想存储多个玩家的数据,并且同时使用这个变量,就会为这个变量添加数组来存储。
在代码里,在变量命中后面写上[ ]
,视为数组。
数组一般和变量共同使用,他的作用是让 “同一个变量存储更多的东西"
例如:
new plane[]
上例代码中 []
就是数组的容器,
这个容器可以设定一个大小,比如:[3]
数组 是一个从0开始的容器,在 [ ]
里面设定的值叫数组最大值
例如:
`ArrayTest[3]`
这个变量中的数组,最大值是 "3"
所以数组从0开始,包含了[0]
,[1]
,[2]
,[3]
在学校运动会中,有一种比赛叫:“接力跑”,由一名同学跑完规定一圈后,将手中的棒子传递给下一个待跑的同学,这位同学接到之前同学拿过来的棒子后,就会开始奔跑,为胜利而战。
就如 ”接力棒” 一样,函数之间可以传递一些数据,让其他函数跟着执行未完成的任务。
比如说:
public aaa()
{
bbb()
)
即 aaa
函数触发了 bbb
函数
像我们家里电灯开关一样,当我们打开开关的时候,电灯会发亮,反之会熄灭。这就是电灯开关触发了电灯泡,让其开启或关闭。
那在 ”反恐精英CS1.6“ 这款游戏中,有什么可以明显看出的触发吗?
有的,比如说:在 cs_assault(72街仓库)这张地图中,作为CT的你去解救人质,进入人质房后,对着人质按 “E” 键,他们便会跟随你。
除此之外,有一些地图中,会有一种开关按 “E” 才能开门或开灯。
也比如:一些道具插件,输入某些命令才能打开菜单或者得到道具。
一些相同,一些不同
触发的方式和传递无比接近,
但传递是由 "前一个函数"传递"给另一个函数",而触发时由一个"命令"或者一个"行为"来传递
在代码中可以做各种判断,来实现你需要的表达
判断是以 if
开头然后接上括号,在括号内的内为 表达式
if(表达式)
表达式 | 释义 |
---|---|
&& | 并且 |
> | 大于 |
< | 小于 |
= |
大于或等于 |
<= | 小于或等于 |
!= | 不等于 |
== | 绝对等于 |
World
变量大于4
并且小于 10
代码为:
if( World > 4 && World < 10 )
{
}
Earth
变量大于 6
或者小于 10
代码为:
if( Earth > 6 || Earth < 10 )
{
}
代码中的运算符就像计算器中的加减乘除 一样
运算符 | 释义 |
---|---|
+ | 加上 |
- | 减去 |
* | 乘以 |
/ | 除以 |
+= | 加上指定值 |
-= | 减去指定值 |
*= | 乘以指定值 |
/= | 除以指定值 |
比如要表达 5 + 4 > 6
这种判断,可配合判断写出如下代码
if( 5 + 4 > 6 )
{
}
在代码中,当函数里的内容超过一行,这时候我们需要用到大括号 { }
把内容包围起来。
比如说:
public test (id)
{
new hello
next_function()
}
但如果在一个函数中出现了多个条件,这种情况下括号就需要
出入的括号数量统一
public test(id)
{ //入1
if(abc)
{ //入2
} //出 1
} //出 2
在上述示例中,有两个 {
号,所以结尾也要 两个 }
,也就是说需要将代码内容完全包围起来
以//
开头直到行末的字符被视为行注释,被注释的代码编译器会自动忽略
//这是一行注释
if(!is_user_alive(id)) //这也是注释
除了行注释,还有一种是用 /*...*/
将多行代码包裹起来,把一大 "块" 视为一个注释
/* 从这里开始是块注释
仍然是注释
仍然是注释
注释结束 */
想一下,怎么将下面的代码注释掉,使他不再执行
public client_connect(id)
{
client_print(id, print_chat, "test")
}
TIP:
注释后的代码将不会被编译器所读取到,所以游戏中也不会有那段代码原有的效果
每个插件在游戏载入地图的时候,会初始化。
所触发的函数就是 plugin_init
,我们可以在这个初始化函数中写上需要为这个插件所注册的信息
通常我们需要注册的基本信息就是,“插件的名字”,“版本号”,"作者名字”
这里我们要用到下面这个代码:
register_plugin(注册的信息以及参数 ) //基本信息注册
这个代码拥有三个可供填写的参数,他们以字符串存在,并且每个参数会以 (,)逗号来隔开。
这三个参数分别是:
如果以字符串配合逗号来分隔,就是下面这样
register_plugin("插件名字", "版本号", ”作者名")
配合基础代码组合后
#include <amxmodx> //定义所需头部模块
//插件初始化
public plugin_init()
{
//注册插件基本信息
register_plugin(“插件名字", "版本号", ”作者名")
}
提示:
- 上面的这个就是代码的基础,任何代码都会以这种形式展开。
- 双引号是必须是切换至英文输入法才可以,不能写中文输入法的双引号,不然会无法编译插件(报错)。
变量是能赋值的,例如将 Test
变量赋值为 4
new Test = 4
当赋值后,做判断的时候就可以判断这个变量中的值,例如
if( Test > 0)
除此之外,还有另一种赋值方式,和上面的代码基本一样,区别只是 不在建立变量的时候直接赋值,看上去像这样
new Test
if(abc < 0)
{
abc = 6
}
通常来说第二种非立即赋值,大部分情况下会先做一个判断,然后再来赋值
小提示:
- 任何变量在创建后,他的值都为 "0"。如果在创建变量时直接赋值,那么这个变量在创建后值就会发生变化,而不是默认的 "0"
- 注意,不可以给 "Bool(布尔)“ 变量赋于其他的值(因为他只拥有 false以及 true)
超过两个(包含两个)的判断视为多重判断。
多重判断可以让我们写出的代码更精确的执行我们需要的效果。
常见写法有两种,一种是堆叠多重
将两个或两个以上的判断堆在一起,这种情况下就不用写 大括号 { } 来包括起来
if( iTestB > 2) //这里不需要写 {
if(TestA < 3)
{
//做些什么
}
上面代码中,由于从第二个判断后没有更多判断表达,所以需要加上 { } 大括号
除了堆叠,还有另一种是单行多重,也就是将所有的表达式都写在一个判断中
//表达式为:iTest > 2 并且 TestA < 3 或者 iTestC 刚好等于 5
if( iTestB > 2 && TestA < 3 || iTestC == 5)
{
//要做些什么
}
一般会在一些特殊的时候进行判断,例如说:
小提示:
多利用多重判断可以让判断更精确、更有效、减少BUG错误
要计算1+2+3,我们可以直接写表达式:
1 + 2 + 3; // 6
要计算1+2+3+...+10,勉强也能写出来。
但是,要计算1+2+3+...+10000,直接写表达式就不可能了。
为了让计算机能计算成千上万次的重复运算,我们就需要循环语句。
AMXX的循环有两种,一种是 for
循环,通过初始条件、结束条件和递增条件来循环执行语句块。
new i
new n = 1000
for(i=1; i<33; i++)
{
n = n - 17
}
让我们来分析一下for
循环的控制条件:
(i>=33)
而退出循环;当这段循环开始执行后,会执行32次,每次会触发 n = n - 17
,也就是 32 x 17 = 544
,而默认变量n创建时赋值为1000,也就是说这段代码将会变成下面这样计算
1000 - (32 x 17) = 456
在游戏算出来的结果:
for
循环在已知循环的初始和结束条件时非常有用。
而上述忽略了条件的for
循环容易让人看不清循环的逻辑,此时用while
循环更佳。
while
循环只有一个判断条件,条件满足,就不断循环,条件不满足时则退出循环。比如我们要计算100以内所有奇数之和,可以用while循环实现:
new x = 0
new n = 99
while (n > 0) {
x = x + n
n = n - 2
}
循环是让计算机做重复任务的有效的方法,有些时候,如果代码写得有问题,会让程序陷入“死循环”,也就是永远循环下去。AMXX插件的死循环会让游戏无法执行当前代码的逻辑,某些游戏会直接挂掉或闪退(卡死未响应等),因此,要特别注意死循环的问题。
提示:
在编写循环代码时,务必小心编写初始条件和判断条件。
你可以查看:下一章 (入门)