一、GML语言概述
Game Maker内置一款编程语言。让你在标准动作之外获得更多的自由度和控制力。这个语言我们简称它为 GML (Game Maker Language)。你可以在很多地方用这个语言编写代码。首先,当你定义脚本的时候。脚本就是一份GML程序。其次,当你在一个事件中添加新动作时。在 编写代码动作时你也同样可以使用GML。第三,如果你想在一个动作中使用指定的一个值,你同样可以使用GML来表达。一段语句如下所说,并不是完整的程 序,只是计算出结果的一段代码。
在本章中我们将向你描述GML的基本概念。当你希望学习使用GML时,这里有一些东西你需要留意。首先,你的所有资源(精灵、对象、声音、等等)你 必须使用一个以字母开头,全部由字母、数字或下划线组成的名称。不然的话你将无法在程序中正确的调用他们。确保所有资源都有不同的名字。同时也要注意不要 将资源取名为 self、global或者其他保留字,因为这些字符在GML中有特殊含义(具体有哪些保留字将在后面详细论述).
GML的相关信息可以在以下页面到:
一个程序
变量
赋值
表达式
扩展变量
在其他实例中定义变量
数组
If 语句
Repeat 语句
While语句
Do语句
For语句
Switch语句
Break语句
Continue语句
Exit语句
函数
脚本
With结构
注释
GML中的函数和变量
一个程序
一个程序包括一套完整的指令,称为语句。一个程序必须以'{ '开头,以'} '结尾。之间是 语句文本。每行语句必须以'; '分号结尾。所以语句的通常形式应该是这样的 :
{
  <statement>;
  <statement>;
  ...}
语句的样式可以有很多种,将在以下各章节论述 .
变量
和其他语言一样,GML中也有变量。变量是存储信息的一段内存空间。他们各有不同的名字 以便于你去调用他们。GML中的一个变量既可以存储一个真实数字,也可以存储一个字符串。 变量并不需要像其他语言一样需要预先声明。这里有大量内置的变量类型。一些相
当常见比 如 mouse_x 和 mouse_y 定义鼠标当前位置。其他一些则定义我们扩展程序时使用的当前对 象例程。比如 x 和 y 定义当前例程的位置。一个变量的名称必须以字母打头,由字母、 数字或下划线组成(最长不超过64个字符)。当你在当前例程中使用新的变量时,在其他例 程的程序中是不可见的(即使是同一个对象的不同例程)。你仍然可以通过某种方法调用其 他例程里的变量,接着往下看.
赋值语句
一段赋值语句将一个值放入一个变量。形式如下 :
<变量名> = <表达式>;
一个表达式可以是一个简单的数值,也可以是复杂的运算式。除了向一个变量赋值以外,同 样可以在当前变量值的基础上再次赋值,使用 '+='的格式。当然,还有 -=,*= /= 或者更 加复杂的格式如 |=、&\、^=.
表达式
表达式可以是数字(比如:4、3、5、6、等等),十六进制数字,或者是 $ 打头的标签( 比如 $00FFAA),单引号或双引号括起来的字符串(比如"Hello"或'hello')或者其他更复 杂的表达式。表达式中有下列双标识符(优先度较高 ):
&& || ^^: 组合是否值 (&& = 和, || = 或, ^^ = 异或)
< <= == != > >=: 比较,结果为 true (1) or false (0)
| & ^: 二进制计算 (| = 二进制或, & = 二进制并, ^ = 二进制异或)
<< >>: 二进制加减 (<< = shift left, > > = shift right)
+ -: 加减
* / div mod: 乘,除,整除,取模
要注意,x div y 的值是 x/y 后的结果中跟0最接近的整数值。 mod 操作符返回调用者的 运算域。也就是说,x mod y = x - (x div y) * y。同时还有以下几个运算符 : 
!: 否, true 转换为 false 和 false 转换为 true
-: 否定后面的数值
~: 否定后面的数值进行二进制位取反(1变0,0变1)
数值中你可以使用数字、变量、或者返回一个值的函数。 子程序可以在括号内书写。所有运算符都是为真实存在的值工作的。比较运算符同样可以对 字符串进行操作, + 可以连接字符串(在这里要注意,和其他语言不同,相加时参数和布 尔变量总是会被计算,即使第一个参数已经决定了结果)。
举例
一个使用子程序的例子.
{
  x = 23;
  color = $FFAA00;
  str = 'hello world';
  y += 5;
  x *= y;
  x = y << 2;
  x = 23*((2+4) / sin(y));
  str = 'hello' + " world";
  b = (x < 5) && !(x==2 || x==4);
}
扩展变量
你通过对一个变量赋值来创建新的变量(不需要事先进行声明)。如果你只是使用一个变量 的名称,它只会存储当前对象例程的内容。所以不用担心它会包含其他对象的内容(或者同 一对象的另一个例程)。你可以在另一个对象中设置和读取变量,通过在变量名前面
添加对 象名称和一个句点'.'。 .
要创建一个全局变量,就是全部对象例程都可以调用的变量,使用'global.变量名'的格式。 以下是一个示例:
{
  if (global.doit)
  {
    // do something
    global.doit = false;
  }
}
或者你能声明全局变量,形式如下.
globalvar <varname1>,<varname2>,<varname3>, ... ;
一旦这样的声明被执行, 变量将一直是全局形式不需要再加全局变量前缀“global.”了. 而这仅仅只需要声明的代码块已被执行. 之后其他地方的这些变量就都会成为全局的.
有些时候你希望变量只在当前的代码段或者语句中使用。这种时候你必须避免浪费内存,并且确信这些变量名称不会带来混淆。同时这种变量也比全局变量速度更快。要使用这种变量 你必须在变量名前加入保留字 'var'和一个空格。这种声明看起来应该是这样的.
var <varname1>,<varname2>,<varname3>, ... ;
程序示例:
{
  var xx,yy;
  xx = x+10;
  yy = y+10;
  instance_create(xx,yy,ball);
}
在其他例程中定位变量
如前所述,你可以在当前例程中使用如下语句设置变量
x = 3;
但有些时候你希望在另一个例程中定义变量。比如,你可能希望停止所有皮球的活动,或者 你可能想移动主要角到一个指定的位置,又或者,在一次碰撞种,你可能希望牵涉进另一 个例程的精灵。这些都可以通过"对象名.变量名"的格式进行声明。例如,你可以这样书写
ball.speed = 0;
这条语句将改变所有ball对象的移动速度为0。这里有几个比较特殊的“对象”。
self: 当前例程中正在执行动作的对象。
other: 其他例程中涉及碰撞事件的对象。
all: 所有例程。
noone: 不属于任何例程(听起来很诡异,但在后面迟早会用到它)。
global: 不属于某个例程,而是整个程序的全局变量。
举个例子,你可以用下面的方式进行变量定义 :
other.sprite_index = sprite5;
all.speed = 0;
ssage = 'A good result';
global.x = ball.x;
你会注意到最后一条语句是在有许多ball的情况下使用的。这样第一个ball.x的值就被新定 义的全局变量global.x取代了。
但如果你希望单独设置一个指定皮球的速度,而不是所有皮球呢?这稍微有点难度。每个例 程有一个独立的ID。当你在编辑器里把例程放入一个房间后,这个例程的ID就会在鼠标置于 例程之上的时候显示出来。这些ID都是从100000开始增加的数字,同样可以用到句点的左边。 但要注意,句点可能会被辨认成小数点,为了避免这种事情发生,需要给ID数字加上括号以 示区别。举个例子,假设这个皮球的ID是100032,你就可以这么写 :
(100032).speed = 0;
如果你在程序中创建了一个例程,call语句会返回例程的ID,所以一个完整的程序段应该是 这样的
{
  nnn = instance_create(100,100,ball);
  nnn.speed = 8;
}
这会创建一个皮球并设定好它的速度,要注意我们把例程的ID赋值给了一个变量,并使用这 个变量加在句点前面构成定位符。这样的用法是完全正确的。让我们用更精确的用法。一个 句点就是一个分隔符。它的左边是一个数值,右面是一个变量(或者说变量的地址),然后 返回特定对象或者例程中的特定变量的具体地址。所有对象的名称,以及特殊对象都会有一 个简单的数字编号,可以和其他数值一样被处理。举个例子,以下的几个语句都是正确的 :
{
switch函数用法举例  obj[0] = ball;
  obj[1] = flag;
  obj[0].alarm[4] = 12;
  obj[1].id.x = 12;
}
最后一个语句比较特殊。我们使用id作为第一标签。这样在那个ID的例程中的x就被赋值为 12了。
对象名称,特殊对象,以及例程的ID都可以在一些函数中使用。他们实际上在程序中被当 作常量使用.
数组
你可以在GML中使用一维或二维数组。只需要使用方括号将数组索引号括起来即可,二维数 组则在两个索引号之间加上逗号分隔。一旦你使用数组索引号,数组即被创建。每个数组 都从0开始编号。所以在建立超长的数组时要小心,因为内存占用会比较巨大。不要使用负 数索引号。系统最大支持到32000的索引,以及总共1000000个最大索引尺寸。举个例子先:
{
  a[0] = 1;
  i = 1;
  while (i < 10) { a[i] = 2*a[i-1]; i += 1;}
  b[4,6] = 32;
}
If 语句
if 后紧跟如下格式
if (<expression>) <statement>
if (<expression>) <statement> else <statement>
语句同样可以是一整段语句,表达式会进行运算。如果括号内的结果 <=0 (或者是false) ,else 后面的语句就会执行。除此之外(表达式为true的时候),另一个语句就会执行。 在语句前后加上大括号是个很好的习惯。如下所示

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。