Game Maker Language.docx
- 文档编号:14228077
- 上传时间:2023-06-21
- 格式:DOCX
- 页数:168
- 大小:126.22KB
Game Maker Language.docx
《Game Maker Language.docx》由会员分享,可在线阅读,更多相关《Game Maker Language.docx(168页珍藏版)》请在冰点文库上搜索。
GameMakerLanguage
一、GML语言概述
GameMaker内置一款编程语言。
让你在标准动作之外获得更多的自由度和控制力。
这个语言我们简称它为GML(GameMakerLanguage)。
你可以在很多地方用这个语言编写代码。
首先,当你定义脚本的时候。
脚本就是一份GML程序。
其次,当你在一个事件中添加新动作时。
在编写代码动作时你也同样可以使用GML。
第三,如果你想在一个动作中使用指定的一个值,你同样可以使用GML来表达。
一段语句如下所说,并不是完整的程序,只是计算出结果的一段代码。
在本章中我们将向你描述GML的基本概念。
当你希望学习使用GML时,这里有一些东西你需要留意。
首先,你的所有资源(精灵、对象、声音、等等)你必须使用一个以字母开头,全部由字母、数字或下划线组成的名称。
不然的话你将无法在程序中正确的调用他们。
确保所有资源都有不同的名字。
同时也要注意不要将资源取名为self、global或者其他保留字,因为这些字符在GML中有特殊含义(具体有哪些保留字将在后面详细论述).
GML的相关信息可以在以下页面找到:
一个程序
变量
赋值
表达式
扩展变量
在其他实例中定义变量
数组
If语句
Repeat语句
While语句
Do语句
For语句
Switch语句
Break语句
Continue语句
Exit语句
函数
脚本
With结构
注释
GML中的函数和变量
一个程序
一个程序包括一套完整的指令,称为语句。
一个程序必须以'{'开头,以'}'结尾。
之间是语句文本。
每行语句必须以';'分号结尾。
所以语句的通常形式应该是这样的:
{
...}
语句的样式可以有很多种,将在以下各章节论述.
变量
和其他语言一样,GML中也有变量。
变量是存储信息的一段内存空间。
他们各有不同的名字以便于你去调用他们。
GML中的一个变量既可以存储一个真实数字,也可以存储一个字符串。
变量并不需要像其他语言一样需要预先声明。
这里有大量内置的变量类型。
一些相当常见比如mouse_x和mouse_y定义鼠标当前位置。
其他一些则定义我们扩展程序时使用的当前对象例程。
比如x和y定义当前例程的位置。
一个变量的名称必须以字母打头,由字母、数字或下划线组成(最长不超过64个字符)。
当你在当前例程中使用新的变量时,在其他例程的程序中是不可见的(即使是同一个对象的不同例程)。
你仍然可以通过某种方法调用其他例程里的变量,接着往下看.
赋值语句
一段赋值语句将一个值放入一个变量。
形式如下:
<变量名>=<表达式>;
一个表达式可以是一个简单的数值,也可以是复杂的运算式。
除了向一个变量赋值以外,同样可以在当前变量值的基础上再次赋值,使用'+='的格式。
当然,还有-=,*=/=或者更加复杂的格式如|=、&\、^=.
表达式
表达式可以是数字(比如:
4、3、5、6、等等),十六进制数字,或者是$打头的标签(比如$00FFAA),单引号或双引号括起来的字符串(比如"Hello"或'hello')或者其他更复杂的表达式。
表达式中有下列双标识符(优先度较高):
&&||^^:
组合是否值(&&=和,||=或,^^=异或)
<<===!
=>>=:
比较,结果为true
(1)orfalse(0)
|&^:
二进制计算(|=二进制或,&=二进制并,^=二进制异或)
<<>>:
二进制加减(<<=shiftleft,>>=shiftright)
+-:
加减
*/divmod:
乘,除,整除,取模
要注意,xdivy的值是x/y后的结果中跟0最接近的整数值。
mod操作符返回调用者的运算域。
也就是说,xmody=x-(xdivy)*y。
同时还有以下几个运算符:
!
:
否,true转换为false和false转换为true
-:
否定后面的数值
~:
否定后面的数值进行二进制位取反(1变0,0变1)
数值中你可以使用数字、变量、或者返回一个值的函数。
子程序可以在括号内书写。
所有运算符都是为真实存在的值工作的。
比较运算符同样可以对字符串进行操作,+可以连接字符串(在这里要注意,和其他语言不同,相加时参数和布尔变量总是会被计算,即使第一个参数已经决定了结果)。
举例
一个使用子程序的例子.
{
x=23;
color=$FFAA00;
str='helloworld';
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)
{
//dosomething
global.doit=false;
}
}
或者你能声明全局变量,形式如下.
globalvar
一旦这样的声明被执行,变量将一直是全局形式不需要再加全局变量前缀“global.”了.而这仅仅只需要声明的代码块已被执行.之后其他地方的这些变量就都会成为全局的.
有些时候你希望变量只在当前的代码段或者语句中使用。
这种时候你必须避免浪费内存,并且确信这些变量名称不会带来混淆。
同时这种变量也比全局变量速度更快。
要使用这种变量你必须在变量名前加入保留字'var'和一个空格。
这种声明看起来应该是这样的.
var
程序示例:
{
varxx,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;
global.message='Agoodresult';
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赋值给了一个变量,并使用这个变量加在句点前面构成定位符。
这样的用法是完全正确的。
让我们用更精确的用法。
一个句点就是一个分隔符。
它的左边是一个数值,右面是一个变量(或者说变量的地址),然后返回特定对象或者例程中的特定变量的具体地址。
所有对象的名称,以及特殊对象都会有一个简单的数字编号,可以和其他数值一样被处理。
举个例子,以下的几个语句都是正确的:
{
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(
或
if(
语句同样可以是一整段语句,表达式会进行运算。
如果括号内的结果<=0(或者是false),else后面的语句就会执行。
除此之外(表达式为true的时候),另一个语句就会执行。
在语句前后加上大括号是个很好的习惯。
如下所示
if(
{
}
else
{
}
示例
一下一段程序可以让对象向屏幕中心移动.
{
if(x<200){x+=4}else{x-=4};
}
Repeat语句
一个repeat语句有如下格式
repeat(<表达式>)<语句>
这样语句会重复运行与括号内表达式的值相同的次数。
示例
以下一段程序会在随机位置创建5个皮球.
{
repeat(5)instance_create(random(400),random(400),ball);
}
While语句
while语句有如下格式
while(<表达式>)<语句>
只要表达式的值为真(true),语句就会一直运行下去。
要注意你的while循环。
你很容易会导致无限循环发生,那样的话你的游戏会永久挂起并失去任何用户输入的响应。
示例
以下一段程序会将对象置于随机的位置(这和把对象移动至随机位置的动作效果是一样的).
{
while(!
place_free(x,y))
{
x=random(room_width);
y=random(room_height);
}
}
Do语句
do语句有如下格式
do<语句>until(<表达式>)
语句(当然也可以用大括号包裹一长段程序)会一直重复执行,直到表达式为真(true)。
语句至少会被执行一次。
小心你的do循环。
你可能会不小心弄出无限循环来,后果同while语句。
示例
以下一段程序会将当前对象移动到一个随机的位置(效果同移动一个对象到一个随机位置的动作):
{
do
{
x=random(room_width);
y=random(room_height);
}
until(place_free(x,y))
}
For语句
for语句有如下格式
for(<语句1>;<表达式>;<语句2>)<语句3>
运行方式如下:
首先语句1被执行。
然后表达式进行运算。
如果表达式为真,则语句3开始执行,然后语句2和表达式进行重新运算。
循环将一直执行至表达式为假。
听起来有点头晕~~你可以用这种方式去理解:
语句1初始化for循环。
表达式测试这个循环是否要执行。
语句2负责循环让循环进入下一轮。
最常见的用法就是进行某些事件的计数。
示例
以下一段程序会建立一个长度为10,内容为1到10的10个元素的数组.
{
for(i=0;i<=9;i+=1)list[i]=i+1;
}
Switch语句
有些时候你希望让你的行动由某些特定的值决定。
你可以使用一串if语句来实现。
但这里有一种更加简单的方式,switch语句。
switch语句有如下格式:
switch(<表达式>)
{
case<表达式1>:
<语句1>;...;break;
case<表达式2>:
<语句1>;...;break;
...
default:
<语句>;...
}
这段语句的效果如下:
首先表达式进行运算。
然后结果会同case后面的表达式的结果进行比较。
相同的结果就会执行后面相应的语句。
如果没有一个相同,则执行default后的语句。
当然,break不是必须的。
如果里面没有break语句,程序会简单的进入下一个case语句。
示例
如下一段程序的效果是在不同的按键被按下后执行相应的动作.
switch(keyboard_key)
{
casevk_left:
casevk_numpad4:
x-=4;break;
casevk_right:
casevk_numpad6:
x+=4;break;
}
Break语句
Thebreak语句有如下格式
break
如果在for循环、while循环、repeat循环、switch循环、或者是with语句中使用,它会停止这些循环或语句。
如果在一个语句外部使用则会停止执行当前程序(注意不是游戏本身).
Continue语句
continue语句有如下格式
continue
如果在for循环、while循环、repeat循环、或者with语句中使用,它会继续让循环或者with语句进入下一轮.
Exit语句
exit语句有如下格式
exit
这段语句会停止脚本或一段代码的执行。
(这不会停止整个游戏的运行!
要想这样你需要使用game_end();函数,后面会讲到)
函数
函数的格式里要有个函数名,跟着是括号内的空参数或多个参数,用逗号分隔。
如下
<函数名>(<参数1>,<参数2>,...)
有两种类型的函数。
一种是大量的内建函数,控制你的游戏中的各个方面,另一种是你自己编写的脚本代码,作为函数在游戏中调用。
要记住,即使这个函数没有参数也不能漏掉后面的括号。
有些函数会返回数值,可以在表达式中使用。
其他则只是简单的执行指令。
注意,函数不能出现在语句的左边。
例如,你不能这样写instance_nearest(x,y,obj).speed=0,二要写成这个样子:
(instance_nearest(x,y,obj)).speed=0.
脚本
当你创建了一个脚本,你想给它加上参数(比如决定什么时候使用脚本动作,或者什么时候将这段脚本作为函数进行调用,又或者是这段脚本自己。
)这些参数将存储在变量参数0、参数1、参数2、。
。
。
参数15。
所以最多会有16个参数。
(记住当在一个动作中调用脚本时,只能声明前5个参数。
)当然你也可以使用参数[0]的方式。
脚本同样可以返回一个值,所以也可以用在表达式中。
你可以使用如下格式:
return<表达式>
脚本的运行会在return语句处停止!
示例
这段代码会返回参数的平方值:
{
return(参数0*参数0);
}
使用脚本就是使用函数一样.如,写下脚本名字并添加上所需要的参数(argument)传入.
With结构
前面有提到,读取和改变其他例程的变量值是可以的。
但很多时候你希望在其他例程中进行多项操作。
例如,假设你希望将所有皮球向下移动8个像素。
你可能想以下面的语句执行这一动作
ball.y=ball.y+8;
但这并不正确。
语句的右边是第一个皮球的纵坐标y值,现在加上8。
下一次调用时所有皮球的纵坐标y值就会和第一个球一样了。
所以这就让所有皮球的纵坐标y值变成一样了。
相当于
ball.y+=8;
我们会得到同样的结果,只是前一个语句的缩写形式。
那么怎样才能做到我们当初设想的动作呢?
你可以使用with语句,常用格式如下
with(<表达式>)<语句>
表达式指明一个或几个例程。
你可以在这里放上例程ID,对象的名称(在所有例程中的同一对象),或者是一个特殊对象(all、self、other、noone)。
语句会在每个指定的例程中执行,跟当前例程一样。
所以,为了移动所有皮球向下移动8个像素,你应该这么写
with(ball)y+=8;
如果你希望运行多行语句,加个大括号。
举个例子,如果你希望将所有皮球移动至一个随机位置,你可以这样用
with(ball)
{
x=random(room_width);
y=random(room_height);
}
要注意,使用上面的语句后,指定例程就会变成self例程。
而这个时候原先的self例程就会变成other例程。
所以举个例子,为了移动所有皮球到当前例程的位置,你可以这么写
with(ball)
{
x=other.x;
y=other.y;
}
with语句的作用是非常强大的。
让我们举出更多的例子。
要摧毁所有的皮球你可以这么写
with(ball)instance_destroy();
如果一个炸弹爆炸了,然后你希望摧毁所有临近的例程你可以这么用
with(all)
{
if(distance_to_object(other)<50)instance_destroy();
}
注释
你可以在自己的程序代码中加入注释。
同一行中'//'后的内容都不会被执行。
你也可以放置多行注释,前后分别放上'/*'和'*/'。
(代码着色可能在这里工作不太正常!
如果出现错误请点击键盘F12重新进行代码着色.)
二、GML中的函数和变量
GML包含许多数量的内建函数和变量。
借助这些东西你可以控制游戏的所有方面。
每个动作都会有对应的函数,所以实际上你如果你偏好编写代码的话你不需要用到任何现成的动作(意思是完全可以自己编写动作代码)。
但是这里也有更多的控制游戏各种方面的函数和变量是无法用现成动作去完成的。
所以如果你希望制作更加高级的游戏,可能的话你最好还是阅读一遍以下各个章节的内容。
要注意,这些函数和变量同样也可以用在动作数值上。
所以即使你不准备通过使用代码或者自己编写脚本,你仍然会得益于这项信息。
这里有一个语法约定,变量名前加上星号'*'表示只读,也就是说这些数值不会再变化了。
变量名后加上'[0..n]'表示是一个数组变量。
索引号的有效长度前面已经提到过了.
数学运算单元
GameMaker包括很多用来完成计算任务的函数。
这儿是完整目录.
GML语言相关的信息在以下几页:
常数
实数函数
字符处理函数
日期及时间处理
常数
以下几个系统中存在的常数:
true等同于1.
false等同于0.
pi等同于3.1415...
实数函数
以下函数都是处理实数变量的.
random(x)返回一个随机的实数,范围从0到x。
数值总小于x.
random_set_seed(seed)设置种子(整数)用于随机数生成。
可以用来重复相同的随即序列(注:
也可以是也些行动或者系统自身使用的随机数).
random_get_seed()返回当前种子.
randomize()设置种子到一个随机数.
choose(val1,val2,val3,...)随机返回其中一个参数。
最多可以有16个参数.
abs(x)返回x的绝对值.
sign(x)返回x的符号(-1,0,或1)。
round(x)返回与x最接近的整数.
floor(x)返回比x小的最大整数.
ceil(x)返回比x大的最小整数.
frac(x)返回x的小数点以后的部分.
sqrt(x)返回x的开方。
x不能是负数.
sqr(x)返回x的平方.
power(x,n)返回x的n次方.
exp(x)e的n次方.
ln(x)返回x的自然对数.
log2(x)返回x的2的对数.
log10(x)返回x的10的对数.
logn(n,x)返回x的n的对数.
sin(x)返回x的正弦(x单位为弧度).
cos(x)返回x的余弦(x单位为弧度).
tan(x)返回x的正切(x单位为弧度).
arcsin(x)返回x的反正弦.
arccos(x)返回x的反余弦.
arctan(x)返回x的反正切.
arctan2(y,x)计算arctan(y/x),然后返回结果在正确象限内的角度值.
degtorad(x)转换角度到弧度.
radtodeg(x)转换弧度到角度.
min(val1,val2,val3,...)返回参数中的最小值。
最高支持16个参数。
必须全部是实数或全部是字符串.
max(val1,val2,val3,...)返回参数中的最大值。
最高支持16个参数。
必须全部是实数或全部是字符串.
mean(val1,val2,val3,...)返回所有参数的平均值。
最高支持16个参数。
必须全部是实数数值.
median(val1,val2,val3,...)返回参数的中间数(如果参数数目为偶数,则两个中间数中最小的那个作为返回值)。
最高支持16个参数。
必须全
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Game Maker Language