GameMaker8.0 新手教程 Part 8 -运动初步-

分类栏目:gamemaker教程

909

GameMaker8.0 新手教程 Part 8 -运动初步-

本章相关内容:GML汉化文档21-22页

1、与运动有关的GM自带变量


再次强调:

①改变GM自带的对象变量会导致对象属性改变,所以绝对不能将其作为一般变量来使用。
②GM自带的对象变量会自动染上红色,以此作为判断变量名是否可以用作一般变量。
③脚本同理,不能以GM自带的函数名或变量名作为自己的脚本名。
④帧是一个时间点概念,步是一个时间段概念,一步是相邻两帧之间的一小段时间。
⑤在GM中,左上角为原点,向右为x轴正方向,向下为y轴正方向。其中角度以正右方为0,正上为90,正左为180,正下为270。角度超出0~360的范围是允许的,比如-90和270在GM中都是指正下方。


①坐标

x :对象的实例在房间内的x坐标。
y :对象的实例在房间内的y坐标。
xprevious :对象的实例以前的x坐标。
yprevious :对象的实例以前的y坐标。

什么叫以前的坐标?
我们观察一下GM的事件执行顺序:

我们可以看到,第六步是“实例移动到新的位置”。而xprevious和yprevious就是获取这一步之前的坐标。换句话来说,只要是在第六步之前的事件,(x,y)与(xprevious,yprevious)是完全一样的,只有在第六步之后的事件,二者才不相同。

xstart :对象在房间里的初始x坐标。
ystart :对象在房间里的初始y坐标。


②速度

speed :对象的实例在房间里的速度。单位是像素/帧。
direction :速度的方向。单位是角度。默认的方向是0,即实例默认向右运动。如上所说,范围不一定是0~360之间,也可以超出。
hspeed :speed在水平方向的分速度。注意这里"h"是指"horizontal",即“水平的”,切勿记成了物理课上用h来表示高度。
vspeed :speed在垂直方向的分速度。"v"是指"vertical",即“垂直的”。

注意:speed,direction,hspeed,vspeed是连锁关系。
何为连锁关系?
即代码中写(如要亲自测试,建议写在create事件):

speed = 5;
direction = 36.8699;
show_message(string(vspeed) + "and" + string(hspeed));

会输出:-3and4
即,一旦改变speed和direction的值,vspeed和hspeed的值也会自动改变为对应的值。
同样的,一旦改变vspeed和hspeed的值,speed和direction也会自动地变为对应的值。
事实上,但凡涉及同一个方面的变量,之间都会有连锁关系。

③加速度

gravity :重力。单位为像素/帧²。默认方向为270,即正向下。实际上,由于重力方向可变,再加上GM里并没有“质量”的概念,重力直接作用给速度,所以其实“重力”理解为“加速度”才是最准确的。
gravity_direction :重力的方向。
friction :阻力。顾名思义,方向始终保持和speed相反。当speed减为0时不再起作用。

注意:gravity与friction生效早于speed生效。
如果有代码:

speed = 5;
friction = 0.7;

那么实例这一步移动4.3个像素。

2、最基本的运动函数move_towards_point

move_towards_point(x,y,spd) :以速度spd向坐标(x,y)运动。
这个函数与speed,direction,vspeed,hspeed是连锁关系。其实从本质上来说,这个函数就是通过给hspeed和vspeed赋值来实现实例的运动。
提示:
如果(x,y)是玩家的坐标——即形如move_towards_point(player.x, player.y, 5),此处假设player就是玩家可以操控的对象——那么这个函数可以生成两种最常见的弹幕类型:写在create事件中就是自机狙,写在step事件中就是跟踪弹。
原理:
如果这个函数写在create事件里,那么只有在实例刚刚创建时执行一次,之后如果没有别的代码改变direction的话,运动方向就会一直保持不变。
如果这个函数写在step里,实例每一步都会根据(x,y)的变化自动调整direction,使实例的运动方向始终保持指向(x,y)的位置。
注意:
当实例运动到(x,y)这个位置时,实例并不会停止,速度仍然保持不变,会原地无限鬼畜。。。所以如果(x,y)是一个固定的坐标,千万别写不要放在step事件里。
如果想让某个实例移动到某一个位置并在这个位置停止,move_towards_point无论是写在create事件里还是step事件里都不会在到达终点时令实例停止,但是我们以后会讲到函数mp_linear_step_object(x,y,stepsize,obj)来实现这个功能。

3、保持精灵方向与运动方向一致

如果对象的精灵是有方向性的,比如炮弹啊什么的,如果精灵的方向和运动方向不一样,看起来就会很别扭。这时候我们介绍两个GM自带的对象变量:

①旋转
image_angle :精灵的旋转角度。默认为0,即不旋转。
如果精灵方向是向右的,由于GM中坐标系是以正右作为0度,那么只要保持精灵旋转的角度和运动方向一致就行:

image_angle = direction;

由于GM的代码是按顺序从上到下运行,所以切记要写在改变了direction的代码的后面。

如果精灵方向不是向右的,就得通过计算得出image_angle和direction的关系。
如果精灵向上,则:image_angle = direction - 90;
如果精灵向左,则:image_angle = direction - 180;
如果精灵向下,则:image_angle = direction - 270;

其实就是先把精灵旋转为向右,然后再和direction保持一致。

②翻转
有的精灵并不能靠旋转来保持和运动方向一致。
比如玩家操作的角色,向左运动则精灵向左,向右运动则精灵向右,如果用image_angle来旋转精灵,那么旋转180度之后,精灵上下也会翻转
但是上下翻转显然不是我们想要的,我们只要左右翻转就行了。

所以我们应该用到:
image_xscale :在x方向上扩大/缩小精灵。默认为1,大于1为放大,0~1之间为缩小。
该变量的值可以是负数,此时先左右翻转,再放大/缩小。
于是就是我们想要的效果:

image_xscale = -1;

注意:iamge_angle和image_xscale都是相对于原精灵进行的改变,而不是叠加的。例如:

image_angle = 50;
iamge_angle = 70;

此时精灵的实际旋转角度是70而不是120。image_xscale同理。

我想,聪明的你肯定能推理出另外一个对应的函数:image_yscale。就不需要我重复讲了吧orz