一、GML语言概述
Game Maker内置一款编程语言。让你在标准动作之外获得更多的自由度和控制力。这个语言我们简称它为 GML (Game Maker Language)。你可以在很多地方用这个语言编写代码。首先,当你定义脚本的时候。脚本就是一份GML程序。其次,当你在一个事件中添加新动作时。在编写代码动作时你也同样可以使用GML。第三,如果你想在一个动作中使用指定的一个值,你同样可以使用GML来
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
达。一段语句如下所说,并不是完整的程序,只是计算出结果的一段代码。
在本章中我们将向你描述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个字符)。当你在当前例程中使用新的变量时,在其他例程的程序中是不可见的(即使是同一个对象的不同例程)。你仍然可以通过某种
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
调用其 他例程里的变量,接着往下看。
赋值语句
一段赋值语句将一个值放入一个变量。形式如下 :
<变量名> = <表达式>;
一个表达式可以是一个简单的数值,也可以是复杂的运算式。除了向一个变量赋值以外,同 样可以在当前变量值的基础上再次赋值,使用'+='的格式。当然,还有 -=,*= /= 或者更 加复杂的格式如 |=、&\、^=.
表达式
表达式可以是数字(比如: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 ,,, ... ;
一旦这样的声明被执行, 变量将一直是全局形式不需要再加全局变量前缀“global.”了. 而这仅仅只需要声明的代码块已被执行.之后其他地方的这些变量就都会成为全局的.
有些时候你希望变量只在当前的代码段或者语句中使用。这种时候你必须避免浪费内存,并且确信这些变量名称不会带来混淆。同时这种变量也比全局变量速度更快。要使用这种变量
你必须在变量名前加入保留字 'var'和一个空格。这种声明看起来应该是这样的.
var ,,, ... ;
程序示例:
{
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;
global.message = '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赋值给了一个变量,并使用这个变量加在句点前面构成定位符。这样的用法是完全正确的。让我们用更精确的用法。一个句点就是一个分隔符。它的左边是一个数值,右面是一个变量(或者说变量的地址),然后返回特定对象或者例程中的特定变量的具体地址。所有对象的名称,以及特殊对象都会有一个简单的数字编号,可以和其他数值一样被处理。举个例子,以下的几个语句都是正确的 :
{
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 () else
语句同样可以是一整段语句,表达式会进行运算。如果括号内的结果 <=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)
{
case vk_left:
case vk_numpad4:
x -= 4; break ;
case vk_right:
case vk_numpad6:
x += 4; break ;
}
Break 语句
The break 语句有如下格式
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]'表示是一个数组变量。索引号的有效长度前面已经提到过了.
二、数学运算单元
Game Maker包括很多用来完成计算任务的函数。这儿是完整目录.
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个参数。必须全部是实数数值 .
point_distance(x1,y1,x2,y2) 返回位置1(x1,y1)到位置2(x2,y2)的距离.
point_direction(x1,y1,x2,y2) 返回从位置1(x1,y1)到位置2(x2,y2)的方向角度.
lengthdir_x(len,dir) 返回指定长度及方向的矢量线在 x 轴上的投影长度.
lengthdir_y(len,dir) 返回指定长度及方向的矢量线在 y 轴上的投影长度.
is_real(x) 返回 x 是否为真实数值(否则就是字符串).
is_string(x) 返回 x 是否是一个字符串(否则就是一个真实数值).
字符串处理函数
以下都是负责字符及字符串处理的函数。
chr(val) 返回字符串中包含参数指定的 ASCII码字符的字符串。
ord(str) 返回字符串中第一个字符的 ASCII 码。
real(str) 将字符串转换为真实数值。字符串可包含负号,小数点甚至是指数部分。
string(val) 将真实数值转换为标准格式的字符串(整数时没有小数点位置,否则在小数点 后留两位)。
string_format(val,tot,dec) 将 val 以你自己的格式转换为字符串:tot 指定总的数字位 置,dec指定小数点后有几位数字。
string_length(str) 返回字符串中字符的个数。
string_pos(substr,str) 返回字符串 substr 在字符串 str 中的位置(0 代表完全不符)。
string_copy(str,index,count) 返回字符串 str 的一部分,从 index 指定的位置开始, 长度为count 。
string_char_at(str,index) 返回字符串 str 中索引为 index 的字符。
string_delete(str,index,count) 返回删除了部分内容的字符串 str,从 index 开始,长度为count 。
string_insert(substr,str,index) 返回在位置 index 处添加子串 substr 后的 字符串str。
string_replace(str,substr,newstr) 返回字符串 str 的一份拷贝,为字符串中 子串 substr第一次出现的地方开始被字符串 newstr 替换后的内容。
string_replace_all(str,substr,newstr) 返回字符串 str 的一份拷贝,为字符串中 子串substr 所有出现的地方开始被字符串 newstr 替换后的内容。
string_count(substr,str) 返回子串 substr 在字符串 str中出现的次数。
string_lower(str) 返回小写格式的字符串 str。
string_upper(str) 返回大写格式的字符串 str。
string_repeat(str,count) 返回由 count 个字符串 str 组成的新 字符串 str。
string_letters(str) 返回只包含字母的字符串 str。
string_digits(str) 返回只包含数字的字符串 str。
string_lettersdigits(str) 返回包含字母和数字的字符串 str。
以下为处理系统粘贴板内容的相关函数。
clipboard_has_text() 返回粘贴板中是否存在任何文本。
clipboard_get_text() 返回当前粘贴板内文本内容。
clipboard_set_text(str) 将字符串 str 送入粘贴板。
日期及时间处理
在Game Maker中有许多函数是专门处理日期和时间的。一个日期-时间格式是一组实数。整
数部分代表日期,最早到12/30/1899。小数点后的部分代表一天之中的24小时。现有有以下 函数 :
date_current_datetime() 返回当前系统日期-时间。
date_current_date() 返回当前系统日期(不包括时间)。
date_current_time() 返回当前系统时间(不包括日期)。
date_create_datetime(year,month,day,hour,minute,second)建立一个指定的日期-时间 数据。
date_create_date(year,month,day) 建立一个指定的日期数据。
date_create_time(hour,minute,second) 建立一个指定的时间数据。
date_valid_datetime(year,month,day,hour,minute,second)返回给定的日期-时间是否正 确。
date_valid_date(year,month,day) 返回给定的日期是否正确。
date_valid_time(hour,minute,second) 返回给定的时间是否正确。
date_inc_year(date,amount) 返回指定日期后 amount 年的新日期。amount 必须为整数
date_inc_month(date,amount) 返回指定日期后 amount 月的新日期。amount 必须为整数。
date_inc_week(date,amount) 返回指定日期后 amount 星期的新日期。amount 必须为整数
date_inc_day(date,amount) 返回指定日期后 amount 天的新日期。amount 必须为整数。
date_inc_hour(date,amount) 返回指定日期后 amount 小时的新日期。amount 必须为整数。
date_inc_minute(date,amount) 返回指定日期后 amount 分钟的新日期。 amount 必须为 整数。
date_inc_second(date,amount) 返回指定日期后 amount 秒的新日期。amount 必须为整数。
date_get_year(date) 返回 date 对应的年份。
date_get_month(date) 返回 date 对应的月份。
date_get_week(date) 返回 date 对应的星期。
date_get_day(date) 返回 date 对应的天数。
date_get_hour(date) 返回 date 对应的小时。
date_get_minute(date) 返回 date 对应的分钟。
date_get_second(date) 返回 date 对应的秒。
date_get_weekday(date) 返回 date 对应一星期的哪一天。
date_get_day_of_year(date) 返回 date 对应一年中的哪一天。
date_get_hour_of_year(date) 返回 date 对应一年中的哪一小时。
date_get_minute_of_year(date) 返回 date 对应一年中的哪一分钟。
date_get_second_of_year(date) 返回 date 对应一年中的哪一秒。
date_year_span(date1,date2) 返回两个日期 date1 和 date2 之间相隔多少年。此函数只报告年数片断。
date_month_span(date1,date2) 返回两个日期 date1 和 date2 之间相隔多少月。此函数只报告月份片断。
date_week_span(date1,date2) 返回两个日期 date1 和 date2 之间相隔多少星期。此函数只报告星期片断。
date_day_span(date1,date2) 返回两个日期 date1 和 date2 之间相隔多少天。此函数只报告天数片断。
date_hour_span(date1,date2) 返回两个日期 date1 和 date2 之间相隔多少小时。此函数只报告小时片断。
date_minute_span(date1,date2) 返回两个日期 date1 和 date2 之间相隔多少分钟。此函数只报告分钟片断。
date_second_span(date1,date2) 返回两个日期 date1 和 date2 之间相隔多少秒。此函数只报告秒数片断。
date_compare_datetime(date1,date2) 比较两个日期时间的大小,返回-1,0,1,分别代表前者小于,等于,大于后者。
date_compare_date(date1,date2) 比较两个日期的大小,返回-1,0,1,分别代表前者小于,等于,大于后者。
date_compare_time(date1,date2) 比较两个时间的大小,返回-1,0,1,分别代表前者小于,等于,大于后者。
date_date_of(date) 返回指定日期-时间数据的日期部分,时间部分设定成0。
date_time_of(date) 返回指定日期-时间数据的时间部分,日期部分设定成0。
date_datetime_string(date) 按照给定的数据,返回系统默认的字符串格式日期-时间。
date_date_string(date) 按照给定的数据,返回系统默认的字符串格式日期。
date_time_string(date) 按照给定的数据,返回系统默认的字符串格式时间。
date_days_in_month(date) 返回指定日期-时间所在月份的天数。
date_days_in_year(date) 返回指定日期-时间所在年份的天数。
date_leap_year(date) 返回指定日期-时间所在年份是否为闰年。
date_is_today(date) 返回指定日期-时间是否为今天。
三、游戏运行
你可以使用大量的变量和函数来定义游戏运行。 这些特别的函数可以改变运动和创建的实例,定时器,房间,还有事件的操作
在接下来的几页可以找到游戏运行的资料:
移动
路径
运动设计
碰撞检测
实例
解散实例
定时
房间
分数
产生事件
复杂的变量和函数
移动
很明显,游戏的一个重要方面就是对象实例的四处移动。每个实例拥有两个内建的变量 x 和 y用来指出实例的位置。(更精确的说,它们显示的位置是精灵原点摆放的位置。)( 0 , 0 )的位置在房间的最左上角。你可以通过改变实例 x 和y 变量的值来改变实例的位置。你如果想要对象进行复杂运动,这是个可行的方法。把有关的代码放在对象的并行( step )事件里。
如果对象以固定方向及恒速移动,实现起来就很简单。每个对象实例都有一个水平速度( hspeed )和一个垂直速度( vspeed)。两个速度都是以像素每步( pixels per step)为单位。一个正的水平速度就是向右的运动,负的水平速度意味着向左的运动。正的垂直速度是向下,负的垂直速度是向上。所以你必须给这些变量初始化(比如在创建事件里)使对象实例有一个恒速。
自定义运动的方法和之前不同,使用了方向( direction )( 0-359 度),和速度( speed)(必须是非负数)。你可以设定并读取这些变量来自定义一个任意运动。(内部处理实际上是把值转换成 hspeed 和 vspeed。)当然还有阻力( friction )和重力( gravity )和重力方向( gravity dirction)供你使用。最后要说的是函数 motion_add(dir,speed) 用来给现有对象增加速度 。
完整来说,每个实例由以下变量和函数来处理它们的位置和运动:
x 对象的 x 坐标 .
y 对象的 y 坐标 .
xprevious 对象以前的 x 坐标 .
yprevious 对象以前的 y 坐标 .
xstart 对象在房间里的初始 x 坐标 .
ystart 对象在房间里的初始 y 坐标 .
hspeed 速度的水平部分,即水平速度 .
vspeed 速度的垂直部分,即垂直速度 .
direction 对象当前方向( 0-360 度,逆时针, 0 = 朝右) .
speed 对象当前速度(像素每步) .
friction 当前阻力(像素每步) .
gravity 当前重力(像素每步) .
gravity_direction 重力方向( 270 朝下) .
motion_set(dir,speed) 以参数(方向,速度)设定运动 .
motion_add(dir,speed) 以参数(方向,速度)对当前运动做改变 .
这儿有大量可利用的函数帮助你定义你的运动 :
place_free(x,y) 返回实例在( x , y )位置是否与固体实例碰撞的值。这个函数用来在实际移动到新位置前检测。
place_empty(x,y) 返回实例在( x , y )位置是否与任何东西碰撞的值。所以这个函数还把非固体实例加入计算范围。
place_meeting(x,y,obj) 返回实例在( x , y )位置是否与对象( obj )碰撞的值。与 obj
对象的实例遇到时,函数返回真( true )。也可以用实例名做 obj 参数,实例名都意味着是对象的一个实例。
place_snapped(hsnap,vsnap) 返回实例是否与网格对齐的值。 //hsnap 水平网格, vsnap 垂直网格
move_random(hsnap,vsnap) 移动实例到一个随机空闲并且是网格的位置,和其对应的动作效果一样。
move_snap(hsnap,vsnap) 将实例对齐网格,和其对应的动作效果一样。
move_wrap(hor,vert,margin) 离开房间到另一边时卷动实例。参数 hor 为是否水平卷动( 1 或 0 )参数vert 为是否垂直卷动( 1 或 0 )。参数 margin为卷动前离原点多远时实例必须离开房间。等于围绕房间的一圈留白。这个函数在离开事件( outside event)中使用非常具有代表性。
move_towards_point(x,y,sp) 以速度( sp )朝( x , y )位置移动实例。
move_bounce_solid(adv) 遇到固体实例反弹,和其对应的动作效果一样。参数 adv ( 1 或 0)为是否使用高级反弹,高级反弹将倾斜面加入计算范围。
move_bounce_all(adv) 遇到所有实例反弹,不单单对固体反弹。
move_contact_solid(dir,maxdist)朝某方向移动实例直到接触固体对象。如果在当前位置没有碰撞,实例在碰撞发生前将不停的移动。如果当前位置已经发生碰撞了,实例就不再移动。你可以指定移动的最大速(距离未定时可以使用负数)//dir 设定方向, maxdist 设定速度
move_contact_all(dir,maxdist) 和上一个函数类似,不过这次接触到任何对象时都会停止,不单是固体对象。
move_outside_solid(dir,maxdist)朝某方向移动实例直到离开固体对象。如果在当前位置没有碰撞,实例不移动。你可以指定移动的最大速(距离未定时可以使用负数) //用于分开重叠的实例
move_outside_all(dir,maxdist) 和上一个函数类似,不过这次是离开任何对象时都会停止,不单是固体对象。
distance_to_point(x,y) 返回当前实例的碰撞盒离( x , y )的距离。
distance_to_object(obj) 返回实例离最近的对象( obj )的距离。
position_empty(x,y) 返回在( x , y )位置是否有任何实例的布尔值。
position_meeting(x,y,obj) 返回( x , y )位置是否有实例 obj 的布尔值。参数 obj可以是对象,实例名,或是其他关键字等等.
路径
在 GameMaker 里你可以定义路径并且命令实例跟随路径。尽管你可以使用动作库,变量和函数可以使你更灵活的运用 :
path_start(path,speed,endaction,absolute)为当前实例开始一段路径。参数 path是你想开始的路径名。参数 speed 是跟随路径的速度。负的 speed 意味着实例沿着路径往回移动。参数 edaction是设定当实例到达路径的终点时发生的事件。 有以下几个值可供使用 :
0: 停止路径
1: 从开始点继续(如果路径没有闭合,直接跳到开始点)
2: 从当前点继续
3: 反转路径,改变速度的符号
参数 absolute 应该是 true 或是 false ( 1 或 0 )。设为 true 时和路径是绝对的关系(
absolute )。设为 false 时路径和实例的当前位置是相关的关系( relative )为了更精确地设定,如果 speed是正的,当前位置就是路径的开始点,路径沿着当前位置而行。 speed 为负值时,当前位置就是路径的终点,路径沿着当前位置往后移动。
path_end() 当前实例结束跟随路径。
path_index* 当前实例跟随路径的索引。你不可以直接改变它,必须使用上面的函数。
path_position 当前路径的位置。值为 0 时在路径的开始位置。值为 1 时在路径的结束位置。值必须在 0 到 1 之间。
path_positionprevious 当前路径的前一个位置。可以使用碰撞事件( collision events)里的例子来设置在路径上位置使它回到前一个位置。
path_speed 设置跟随路径的速度(像素每步)。负值时向后移动。
path_orientation 路径处理时的方位(逆时针)设定。值 0 时为正常方向。
path_scale 缩放路径。增加值使路径变大。 1 是默认值。
path_endaction 路径结束时必须执行的行为。可以使用最上面的函数介绍的值.
运动设计
运动设计帮助你在避免与另一实例(比如:墙)碰撞的情况下将某实例从给定位置移动到另一位置。运动设计是一个有难度的项目。几乎不可能给出一些能够在任何情况下正常运作的普通函数。同时,计算碰撞运动非常耗费系统资源。所以使用这些函数时必须非常小心仔细。当你使用以下任一函数时请将这些
建议
关于小区增设电动车充电建议给教师的建议PDF智慧城市建议书pdf给教师的36条建议下载税则修订调整建议表下载
记到心里。
Game Maker
提供了一些不同形式的运动
计划
项目进度计划表范例计划下载计划下载计划下载课程教学计划下载
。最简单的形式允许一个实例朝某特定目标方向步进,可能的话尽量走直线但是如果有要求的话可以取不同的方向。这些函数应当在实例的并行事件
(step event) 中使用。对应的运动计划动作库也是可用的 :
mp_linear_step(x,y,stepsize,checkall) 这个函数作用为让实例朝指定位置( x , y)直线步进。每一步的大小由参数 stepsize 设置。如果实例已经到位,实例不再移动。如果参数 checkall 为 true (1 ),实例遇到任意对象的实例都不会停止。如果为 false ( 0),实例碰撞到另一固体实例时就会停止。注意这个函数遇到障碍时不会试着绕路。它只会简单的停止。函数返回值为是否到达目标位置.
mp_linear_step_object(x,y,stepsize,obj) 除了参数 obj 实例为障碍,其他效果同上。参数obj 可以是对象或是实例名。
mp_potential_step(x,y,stepsize,checkall)和先前的函数类似,这个函数也是让实例朝指定位置步进。不同处是这个函数会试着绕过障碍物。当实例快撞上某一固体实例(或任何实例,
checkall 为 true时)时,会改变运动方向来避开实例并且绕开它。这个方法不能保证有效,但是在大部分简单应用中会非常有效的让实例朝目标移动。函数返回值为是否到达目标位置。
mp_potential_step_object(x,y,stepsize,obj) 除了参数 obj实例为障碍物,其他效果同上。参数 obj 可以是对象或是实例名。
mp_potential_settings(maxrot,rotstep,ahead,onspot)先前的函数利用的一些参数可以使用这个函数改变。以下方法都有全局性。首先试着朝目标直线移动。可以使用参数 ahead (默认值为 3)设置前面有多少步。减少这个值意味着实例将在延后开始改变方向。增加这个值意味着提前开始改变方向。如果检测到将要碰撞,实例会开始朝向最佳方向,偏右或是偏左。根据参数rotstep (默认值为 10 )的大小决定在多少步中改变朝向。减少 rotstep的值会使得实例有更多移动的可能性但速度也会更慢。参数 maxrot 解释起来有一点难度。实例有一个当前方向。参数 maxrot(默认值为 30)为在一步里面允许改变当前方向的最大值。所以说即使实例可以直线移动到目标,只要不超过改变方向的最大值,它就会这样执行。如果你把maxrot设得很大,实例就可以在每一步都改变很多方向。这样可以使它更简单的寻找一段短路径,但同时整个路径会变得非常丑陋(路线歪七歪八的 …)。如果把值设得很小,路线就会很平滑但同时它可能会绕很远的路费很多时间(有时候甚至找不到到目标的路)。没有创建步时,实例的行为会建立在参数onspot 上。如果 onspot 值为 true (或 1 ,为默认值),实例会根据 maxrot的大小在自己的位置上旋转。如果值为 false (或 0 )实例就不再移动。如果实例为车辆时,设为 false比较好,但同时会减少寻路成功的机会。
请注意 potential函数只能使用局部信息。所以它只能在局部信息足够确定正确的运动方向时寻路成功。举例来说,走出迷宫就找不到路了(大部分情况下)。
第二种类型函数为实例计算路径是否碰撞。一旦路径经过计算,你可以分配给实例让它朝目标移动。计算路径会花一些时间但接下来完成路径会非常快。当然只会在其间情况没有改变时才有效。举例来说,如果障碍物改变了,你可能需要重新计算路径。再次注意,这些函数可能不起作用。
这些函数只有在 Game Maker 注册后才能用
开始的两个函数使用了线形运动,潜在域方法照例是用在 step 函数里的 。
mp_linear_path(path,xg,yg,stepsize,checkall)这个函数使用指定步大小计算实例从当前位置到( xg , yg )的直线路径。使用步的方法和函数 mp_linear_step()一样。指定的路径必须已经存在并且会被新路径覆盖。(参考后面的章节怎样建立和销毁路径。)函数返回值为是否找到路径。函数在寻路失败前不会停止,开始和目标之间不存在直线路径为失败的情况。如果失败,路径仍然会被创建直到运行到实例到达封闭的位置。
mp_linear_path_object(path,xg,yg,stepsize,obj) 除了参数 obj实例为障碍物,其他效果同上。参数 obj 可以是对象或是实例名。
mp_potential_path(path,xg,yg,stepsize,factor,checkall)这个函数计算指定步大小让实例绕过障碍从当前位置和方向到(xg , yg )的路线。函数使用了潜在域步骤,类似于函数 mp_potential_step() 当然参数可以用函数
mp_potential_settings()来设置。指定的路径必须已经存在并且会被新路径覆盖。(参考后面的章节怎样建立和销毁路径。)函数返回值为是否找到路径。为了避免函数不停的计算下去,你需要给出一个大于1 的参数 factor 。如果找不到比开始和目标之间的距离更短的路径,函数就会停止并报错。参数 factor 为 4是正常够用的值了,但是如果想绕远点的话可能需要加大数值。如果失败,路径仍然会被创建并且在目标方向运行,但是到达不了目标。
mp_potential_path_object(path,xg,yg,stepsize,factor,obj) 除了参数 obj实例为障碍物,其他效果同上。参数 obj 可以是对象或是实例名.
另一些函数使用了更复杂的机构使用了一种基于网格的方法(有时候称它为 A*算法)。寻路更容易成功(尽管还是有失败的可能)并且路线更短,缺点是需要很多操作。以下都是全局概念。首先我们在房间内放入一网格(相应的部分)。你可以选择精