GameMaker函数说明(1)帮助文件

分类栏目:gamemaker教程

443

GameMaker函数说明(1)帮助文件

常数

true 等同于1.
false
 等同于 0.
pi
 等同于 3.1415...

实数函数

random(x) 返回一个随机的实数,范围从 0 到 x 。数值总小于 x 。 
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) 返回 x 的冥方指数 e 。 
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 路径结束时必须执行的行为。可以使用最上面的函数介绍的值 。

运动设计

运动设计帮助你在避免与另一实例(比如:墙)碰撞的情况下将某实例从给定位置移动到另一位置。运动设计是一个有难度的项目。几乎不可能给出一些能够在任何情况下正常运作的普通函数。同时,计算碰撞运动非常耗费系统资源。所以使用这些函数时必须非常小心仔细。当你使用以下任一函数时请将这些建议记到心里。

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 函数只能使用局部信息。所以它只能在局部信息足够确定正确的运动方向时寻路成功。举例来说,走出迷宫就找不到路了(大部分情况下)。

第二种类型函数为实例计算路径是否碰撞。一旦路径经过计算,你可以分配给实例让它朝目标移动。计算路径会花一些时间但接下来完成路径会非常快。当然只会在其间情况没有改变时才有效。举例来说,如果障碍物改变了,你可能需要重新计算路径。再次注意,这些函数可能不起作用

开始的两个函数使用了线形运动,潜在域方法照例是用在 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* 算法)。寻路更容易成功(尽管还是有失败的可能)并且路线更短,缺点是需要很多操作。以下都是全局概念。首先我们在房间内放入一网格(相应的部分)。你可以选择精致的网格(较慢)或是粗糙的网格。接下来,我们要探测所有的相关对象与网格单元交叠的地方(不管是碰撞盒或是精确检测)并且对这些单元作禁止的标记。即使只是和障碍物部分交叠,单元会全部被标记为禁止通行。最后我们指定一个开始和一个目标位置(必须放在空白单元上),函数就会计算他们之间的最短路径(实际上是最接近最短路径)。路径会在中间空白的单元上行进。所以如果单元足够大到能在中心完全放下实例,函数就会成功。接下来你可以把这个路径给一个实例 。

基于网格的方法 十分强大(在很多专业游戏中使用)但是要求你仔细的考虑如何使用。你必须决定哪个区域以及单元大小比较合适。同样必须决定哪个对象必须避开并且决定精确检测是否必要。所有这些参数都强烈影响到寻路的效果。

特别需要注意,单元的大小十分重要。要记住单元必须要足够的大,大到能将移动的对象完全放入单元的中心。(注意对象原点的位置。同样要了解如果对象的原点不在它的中心,你就可以移动路径)另一方面,单元越小路径越容易存在。如果单元和障碍物之间的开口太大路径会闭合,因为所有的单元都和一个障碍物交叠。

基于网格方法的实际函数如下 :

mp_grid_create(left,top,hcells,vcells,cellwidth,cellheight) 这个函数建立网格。返回一个索引用于其它函数调用。你可以在同一瞬间创建并维持多重网格结构。参数 left 和 top 指定网格左上角的位置。参数 hcells 和 vcells 设置水平和垂直单元的数量。参数 cellwidth 和 cellheight 是单元的大小。 
mp_grid_destroy(id) 销毁指定网格结构并释放空间。如果不再用到结构时记得调用这个函数。 
mp_grid_clear_all(id) 将网格中的所有单元都标记为空。 
mp_grid_clear_cell(id,h,v) 清除指定单元。单元 0 , 0 在最左上角。 
mp_grid_clear_rectangle(id,left,top,right,bottom) 清除和指定矩形交叉的所有的单元(在相应的房间里)。 
mp_grid_add_cell(id,h,v) 标记指定的单元为禁止通行。单元 0 , 0 在最左上角。 
mp_grid_add_rectangle(id,left,top,right,bottom) 标记和指定矩形交叉的所有的单元为禁止通行。 
mp_grid_add_instances(id,obj,prec) 标记所有与指定对象的实例交叉的单元为禁止通行。你可以通过参数 obj ,实例的 id 名来使用一个单独的实例。同样也可以使用关键字 all 表示所以对象的所有实例。参数 prec为是否使用精确检测(只有当实例使用的精灵打开精确检测时才有效)。 
mp_grid_path(id,path,xstart,ystart,xgoal,ygoal,allowdiag) 计算一条通过网格的路径。参数 path 必须指定一条已经存在的路径用来被电脑路径替代。参数 xstart 和 ystart 为路径的开始点, xgoal 和 ygoal 为目标点。参数 allowdiag 为是否允许使用斜角移动替代水平和垂直移动。函数返回值为是否寻路成功。(注意路径不受当前实例影响;是一条穿越网格的路径,不是某特殊实例的路径) 
mp_grid_draw(id) 这个函数将空的单元绘成绿色,禁止通行的单元绘成红色。这个函数运行起来很慢这是用来做 debug 工具。

碰撞检测

计划运动或是要决定具体行动时,察看实例是否与其它对象在确定的地点碰撞是一件十分重要的事。为此需要用到下面的程序。所有的这些函数有三个共有参数:参数 obj 是某对象,关键字 all ,或是某实例的 id 名。参数 prec 是是否启用精确检测或是仅仅使用实例的碰撞盒。精确检测只有当实例的精灵设定了精确碰撞检测时才有效。参数 notme 可以设为 true ( 1 ),使调用的实例不会被检测。所有的这些函数返回值为被碰撞实例的 id 名,如果没有碰撞就返回一个负值 。

collision_point(x,y,obj,prec,notme) 这个函数测试在( x , y )位置是否和实体对象obj 有碰撞。 
collision_rectangle(x1,y1,x2,y2,obj,prec,notme) 这个函数测试指定对角的矩形(已填充)是否和实体对象 obj 有碰撞。举例来说,你可以使用这个函数测试某个区域里是否没有障碍物。 
collision_circle(xc,yc,radius,obj,prec,notme) 这个函数测试指定圆心( xc , yc )的圆(已填充)是否和实体对象 obj 有碰撞。举例来说,你可以使用这个函数测试某对象是否靠近某特点位置。 
collision_ellipse(x1,y1,x2,y2,obj,prec,notme) 这个函数测试指定对角的椭圆(已填充)是否和实体对象 obj 有碰撞。 
collision_line(x1,y1,x2,y2,obj,prec,notme) 这个函数测试线段( x1 , y1 )到 (x2,y2) 是否和实体对象 obj 有碰撞。这是个强大的函数。你可以这样使用这个函数,通过检测线段是否与他们之间的墙相交来测试某实例是否可以看到另一实例。

实例

游戏中,最基本的单位就是各种不同对象的实例。游戏进行时可以替换许多实例的外貌。同样你也可以通过创建新实例并摧毁实例达到替换的效果。除了先前讨论的运动相关变量和下面将要讨论的绘制相关变量,每个实例都有如下一些变量 :

object_index* 对象的索引。这个变量不可以改变。
id* 实例的统一标识符( >= 100000 )。(注意,定义房间时,鼠标指定的实例 id 名总会显示出来。) 
mask_index 遮照精灵的索引,用来碰撞检测。值为 -1 时效果和 sprite_index 一样。 
solid 实例是否为固体。可以在游戏进行中改变。
persistent 实例是否持久显示并且移动到另一房间时再现。某些时候经常需要把持久的效果关掉。(举例来说,要回到第一个房间的时候)

处理实例时有个问题。分辨单个的实例不是很容易。他们没有名字。只有某特点对象的某个实例时你可以使用对象名,否则需要实例的 id 名。实例有一个统一的标识符。你可以在 with 语句中当做对象标识符使用。幸运的是有大量的变量及程序帮助你定位实例 id 名。

instance_count* 房间中现存实例的数量。 
instance_id[0..n-1]* 特定实例的 id 名。这里的 n 为实例的编号。

注意,实例对实例 id 名的分配每一步都改变,所以你不能使用上一步的值。我来举个例子。设想你游戏中的每个单位都有特别有力量,你想找到最强壮的那个,可以使用以下代码 :

{

  maxid = -1;

  maxpower = 0;

  for (i=0; i<instance_count; i+=1)

  {

    iii = instance_id[i];

    if (iii.object_index == unit)

    {

      if (iii.power > maxpower)

        {maxid = iii; maxpower = iii.power;}

    }

  }

}

做完循环, maxid 就是那个最强的单位了。(循环时不要销毁实例,因为他们会自动从数组中移除)

instance_find(obj,n) 返回值为参数 obj 的第 (n+1) 个实例 id 名。参数 obj 可以是某对象或是关键字 all 。如果不存在,返回特殊对象 noone 。注意,实例对实例 id 名的分配每一步都改变,所以你不能使用上一步的值。 
instance_exists(obj) 返回值为 obj 的实例是否存在。参数 obj 可以是某对象,实例 id 名或是关键字 all。 
instance_number(obj) 返回 obj 实例的编号。参数 obj 可以是某对象或是关键字 all 。 
instance_position(x,y,obj) 返回值为 obj 在( x , y )位置上实例的 id 名。同一位置有多个实例时,返回第一个实例。参数 obj 可以是某对象或是关键字 all 。如果不存在,返回特殊对象 noone 。 
instance_nearest(x,y,obj) 返回值为最接近( x , y )位置的 obj 的实例 id 名。参数 obj 可以是某对象或是关键字 all 。 
instance_furthest(x,y,obj) 返回值为离( x , y )位置最远的 obj 的实例 id 名。参数 obj 可以是某对象或是关键字 all 。 
instance_place(x,y,obj) 返回值为遇到当前( x , y )位置上实例的 obj 的实例id 名。参数 obj 可以是某对象或是关键字 all 。如果不存在,返回特殊对象 noone 。

下面的函数用于创建销毁实例 。

instance_create(x,y,obj) 在( x , y )位置创建 obj 的实例。函数返回新实例的 id 名。 
instance_copy(performevent) 创建当前实例的复制品。参数performevent 为复制品的创建事件( creation event )是否必须执行。函数返回新复制品的 id 名。 
instance_destroy() 销毁当前实例。 
instance_change(obj,perf) 改变 obj 的实例。参数 perf 为是否执行销毁和创建事件( destroy and creation events )。 
position_destroy(x,y) 销毁所有包含( x , y )位置精灵的实例。 
position_change(x,y,obj,perf) 在( x , y )位置改变所有 obj 的实例。参数 perf 为是否执行销毁和创建事件( destroy and creation events )。

解散实例

当你创建大房间时,比如在平台游戏中,在一个小视野里,很多实例在视野的外面。这些实例仍然是激活状态并且会执行他们的事件。同样,计算碰撞检测时这些实例也会加入计算。这样会浪费大量的时间,通常也没有必要。(举例来说,视野外的实例移动一点都不重要。)为了解决这个问题, Game Maker 内含了一些函数来解散和激活实例。使用前你必须清楚地明白他们是怎样运作的 。

解散实例时,它们会被判断为从游戏中移除。他们不再可见也不会执行任何事件。所以对大部分动作库和函数来说,它们不再存在。这样节省了大量的时间,但使用时要非常小心。举例来说,当你删除了某特别类型的所有实例,已解散实例没有被删除(因为它们不存在)。所以不要认为一串角色捡到的钥匙可以用来打开一个已解散的门。

最容易犯的错误是解除了一个激活的实例。为了避免下面的一些程序,要求你强调被调用的实例不会解除它本身

这儿有些可用的程序 :

instance_deactivate_all(notme) 解除房间内的所有实例。如果参数 notme 为 true ( 1 )正在调用的实例不会解除(通常是你想要的效果)。 
instance_deactivate_object(obj) 解除房间内的所有 obj 的实例。你也可以参数 obj 改为 all 来使所有的实例解除或者指定实例 id 名解除一单个的实例。 
instance_deactivate_region(left,top,width,height,inside,notme) 解除指定区域内的所有实例(那些碰撞盒部分在区域内的也算)。如果参数 inside 为 false ( 0 ),完全露在区域外的实例会被解除。如果参数 notme 为 true ( 1 )正在调用的实例不会解除(通常是你想要的效果)。 
instance_activate_all() 激活房间内的所有实例。 
instance_activate_object(obj) 激活房间内的所有 obj 的实例。你也可以参数 obj 改为 all 来使所有的实例激活或者指定实例 id 名激活一单个的实例。 
instance_activate_region(left,top,width,height,inside)激活指定区域内的所有实例。如果参数 inside为 false ( 0 ),完全露在区域外的实例会被激活。

举例来说,视野外的实例都解除,视野内的实例全激活,你可以将下面的代码放到移动角色的并行事件中( step event ) r:

{

  instance_activate_all();

  instance_deactivate_region(view_xview[0],view_yview[0],

                        view_wview[0],view_hview[0],false,true);

}

特别注意, 你可能需要让区域比视野稍微大一些 。

定时

一个好的游戏要求精确的时间控制。幸运的是 Game Maker 有许多时间方面的函数。使事物恒速( rate )发生。这个速度( rate )在定义房间的时候设置。你可以用全局变量 room_speed 来改变它。举例来说,通过每一步对 room_speed 增加一个很小的量(比如 0.001 ),你可以缓慢增加游戏的速度,使它难度更高。如果你的电脑很慢,游戏速度可能不能达到。可以使用变量 fps 来不断监测实际每秒的帧数。最后,一些高级定时使用时可以用变量current_time ,电脑开始时的毫秒数。这儿是所有可用的变量(只有第一个可以改变) :

room_speed 当前房间的游戏速度(单位为步每秒) 。 
fps* 实际每秒的帧数。 
current_time* 系统开始时经过的毫秒数。 
current_year* 当前年。 
current_month* 当前月。 
current_day* 当前日。 
current_weekday* 当前星期几( 1 为星期日, …,7 为星期六)。 
current_hour* 当前小时。 
current_minute* 当前分钟。 
current_second* 当前秒。

有时候你需要将游戏停止一小会儿。使用 sleep 函数 。

sleep(numb) 睡眠( numb )毫秒 。

如你所知,每个实例有 12 个不同的定时器可以设置。使用下面的变量改变(或获取)不同定时器的值 :

alarm[0..11] 指定定时器的值。(注意只有在对象的定时器事件包含动作时,定时器才会更新!)

复杂的时间问题可以使用时间轴资源。每个实例都有一个时间轴资源关联。下面的函数是处理时间轴的 :

timeline_index 实例关联时间轴的索引。可以设定为一个特定的时间线然后使用它。设为 -1 时停止使用时间轴。 
timeline_position 当前时间轴位置。可以改变它的值来跳过部分内容或是重复部分内容。 
timeline_speed 一般来说,时间轴上的位置每步都增加1。可以改变为不同的值。你可以用一个实数比如0.5。如果值比1大,同样的时间步内会发生更多的事件。他们会根据正确的命令允许,所以不会跳过任何动作。

房间

游戏是在房间中运行的。每个房间都有一个索引名。当前房间保存在变量 room 中。你不要将房间想象成连续的。所以不要增加或减少 room 变量的值。而应该使用下面的函数和变量。你可以使用下面一行典型的代码 :

{

  if (room != room_last)

  {

    room_goto_next();

  }

  else

  {

    game_end();

  }

}

下面变量和函数用来处理房间 .

room 当前房间的索引。不能通过改变就进入一个不同的房间,要用下面的函数。 
room_first* 游戏中第一个房间的索引。 
room_last* 游戏中最后一个房间的索引。 
room_goto(numb) 进入索引为 numb 的房间。 
room_goto_previous() 进入先前的房间。 
room_goto_next() 进入下一个房间。 
room_restart() 当前房间重新开始。 
room_previous(numb) 返回先前房间的索引 numb ( -1 为空),但是不能去那里。 
room_next(numb) 返回下一个房间的索引 numb 。 
game_end() 结束游戏。 
game_restart() 游戏重新开始。

调用下面的函数来改变房间或结束或重新开始游戏时,请认识到房间的改变不会立刻实现。当前的动作全部执行完才开始改变。所以剩下的脚本仍然会执行,同样的应用可能调用脚本。

房间有这些附加属性 :

room_width* 房间的宽度。(单位为像素) 
room_height* 房间的高度。(单位为像素) 
room_caption 显示在窗口的房间名。 
room_persistent 当前房间是否持久显示。

很多游戏要求玩家保存游戏以及读取游戏。 Game Maker 中 F5 保存游戏 F6 读取游戏。也可以用一行代码保存和读取游戏(注意,读取只在当前步的最后发生)。

game_save(string) 保存游戏为文件名 string 。 
game_load(string) 读取文件名为 string 的游戏 。

请认识到,只是最基本的游戏数据被保存。如果播放一段音乐,在音乐的精确位置是不能保存的。同样改变过的资源也不能保存。另外未保存的是数据结构内容,粒子,还有多人设置 。

得分

很多游戏的另一个重要方面是得分,生命值,以及生命。 Game Maker 保留得分为全局变量 score ,生命为全局变量 lives 。生命值和生命同样如此。所有的实例如果生命大于 0 ,并且要小于等于 0 ,没有生命事件( no-more-lives event )就会执行。如果你不想在标题上显示得分和生命,设置 show_score 为 false 。同样也可以改变标题。更复杂的游戏最好自己显示得分 。

score 当前得分。 
lives 生命数量。 
health 当前生命值( 0-100 )。 
show_score 是否在窗口标题中显示得分。 
show_lives 是否在窗口标题中显示生命数量。 
show_health 是否在窗口标题中显示生命值。 
caption_score 用于得分的标题。 
caption_lives 用于生命数量的标题。 
caption_health 用于生命值得标题 。