GMS2官方教程系列5/8——绘制文字
这节教程的目的是在游戏画面中绘制文字,我们在游戏中经常会使用一些文字性的内容,比如生命值、人物等级、游戏分数等等,当然有一些游戏中可能会用图片直接取代文字,或是用图片绘制出一些华丽的文字效果,但还是有一些场合更适合直接写字,毕竟文字更灵活可变,并且消耗性能也更低一些。这个教程将以绘制积分为例来介绍文字绘制的操作以及如何调整字体。首先我们要创建一个对象,不过这个对象不同以往,我们不需要指定关联的精灵,因为这个对象并不需要被玩家看到,这是一个不可见的对象,它存在的意义只是为了触发和控制绘制文字,创建好这个对象以后,我们先设置一个“create”事件,然后在其中定义一个分数变量,并设置为0:
这个变量是我们用来记录游戏中玩家取得的积分的,这样我们在绘制文字的时候才有一个确切的内容可以去写。
可能会有人注意到,我一直都是在说“绘制文字”,因为在游戏中所有可见的内容都是被”绘制“出来的,因此我们要想在游戏中绘制文字,就需要用到”绘制“事件,绘制事件有很多,而我们在这里需要用的是最基本的”绘制事件“如下图:
我们在这个绘制方法中写入以下内容:
var cx = camera_get_view_x(view_camera[0]);
var cy = camera_get_view_y(view_camera[0]);
var cw = camera_get_view_width(view_camera[0]);
draw_text (cx+cw/2,cy+25,string(thescore))
在这里我们又定义了三个变量,但是我们在定义变量时在前面使用了“var”这个方法,这样定义出来的变量只在当前方法中有效,这样可以尽可能节约内存占用提升性能。然后我们所定义的cx、cy和cw都是根据上节教程中所使用的镜头“view_camera[0]"的不同属性而来的
- cx就是镜头在场景中的x坐标值
- cy就是镜头在场景中的y坐标值
- cw就是镜头本身的宽度属性
我们设置这样三个变量,是为了确认我们积分文字绘制的位置,看上图最下方,我们使用了一个“draw_text”的方法来绘制文字,而这个方法在下方的参数提示区中可以看到一共需要三个参数,分别是绘制文字位置的x、y坐标和需要绘制的文字内容。而我们设定的三个值就是为了用来确定这个绘制位置的,因为我希望将分数放在画面中央靠上的位置,而且上节课我们已经设定过镜头,知道游戏画面会随着游戏镜头滚动,但我们不希望这个积分也跟着滚动,我们希望积分永远固定在镜头中的某个位置,这样不管我们控制飞船跑到什么地方,都能随时观察自己获得的积分。所以我们要把文字的绘制坐标关联到镜头的坐标上,确保积分相对于镜头的位置是固定不变的。
- x : cx + cw/2
因为镜头的原点在左上角,因此相对于游戏场景而已,镜头的x在0的位置,而我们希望文字能在水平方向上位于镜头的中央,所以需要加上镜头宽度的一半来作为文字绘制的x坐标
- y : cy + 25
同样的,镜头在游戏场景中的y坐标也是0,我们希望积分稍微向下而不是完全贴在边上,所以加了25个像素的偏移量因此我们用这两个算式计算出了文字的绘制位置,然后把他们填到了参数中,当然我们也可以单独写一个变量定义到这两个算式上,然后子啊参数中填入我 们自己定义的变量,这个视频中没有,但是自己可以尝试操作一下,并不难。而最后的文字,只要是字符串(String)类型的内容都可以任意书写,而我们因为希望绘制分数,但是分数并不是字符串类型的变量,而是数字类型的,所以要用“String”这个方法先把数字类型的分数转换成字符串类型才可以使用。
小TIPS时间之前说了一下,所有的可见元素都是被“绘制”出来的,所以其实在游戏中所有的可见对象其实都默认自带了一个绘制方法来把自身绘制到游戏中:
虽然你在对象里看不到这个方法的存在,但其实都是默认存在的
在完成以上的内容后,理论上我们已经可以绘制出一个积分的文字,但是这个文字所对应的分数默认设置为0,那我们怎么才能让分数增加呢?首先,我们要设定一个规则,这里我们希望在玩家摧毁敌人的时候获得积分,每个敌人5分,那我们就可以想到,要在敌人被摧毁的时候去执行一个命令来增加分数是最合适不过了,那我们就要去敌人对象中找到摧毁自身的那个方法:
如上图,我们当时在敌人对象的“step”事件中写过一个if的判断,判断敌人的hp小于等于0时就自动摧毁,那我们就要在它被摧毁之前再做一个增加分数的操作:
with (obj_score) thescore = thescore + 5 ;
在之前的教程中曾经说过,如果我们要在A对象中修改B对象内的变量就需要用“with”这个方法,这里我们就可以用这个方法来修改分数对象中的分数值了,每次增加5。然后我们测试一下游戏,就会看到在游戏画面的中央靠上的位置已经有了一个十分难以辨识的分数文字了,下图放大处理便于确认。
我们会发现这个分数很难被发现的原因是两个,第一是字体太小,第二是黑色的文字在这个深色背景上太不显眼了,因此下面我们要学习如何设置字体和字体颜色。
首先我们要在右侧资源树中新增一个字体文件,如下图所示:
图中我已经大致标注了一些关键区域的简要说明,如果想详细了解字体编辑器的各项功能可以去看我翻译的官方文档,起码字体编辑器这一块已经翻译完了:)
在这里,我们可以从系统字体中随便挑一个喜欢的字体来用,然后把尺寸设置到24,这样文字就会显得比较大了,在字体创建好后就可以去设置使用了:
回到我们刚才绘制分数的方法里,在绘制之前增加了两行代码
draw_set_font(fnt_score) ;
draw_set_colour(c_white);
这两行方法分别是用来设置文字字体和颜色的,其中字体就使用了我们刚才新创建的那个,而颜色这里使用的是GameMaker Studio 2自带的颜色,不光又"c_white",同样还有"c_blue","c_red"等常见的颜色,当然如果你对颜色有明确的要求,也可以在这里直接指定RGB值。最后测试一下游戏就大功告成啦!
本节视频解说地址:【中文教程】GameMaker Studio 2官方教程5/8——添加文字
这部分内容虽然简单但是却很常用,这里其实还有一个没说就是中文字体的设置,因为GMS中是不能直接绘制中文的,需要在创建字体的时候单独选择文字编码范围,不过这套教程是跟着官方教程走的就不多说明了,以后另外单独说一下中文字体的设置和使用。
GMS2官方教程系列4/8——瓷片&镜头
大家好,第四节教程我们介绍的是如何给游戏构建背景,跟所有可见元素一样,首先我们要创建一个精灵,用来存储我们用来做背景的图像元素,如下图:
你会注意到我们导入的图片有些特别,这其实是一张由九个单元格组成的素材图,因为后续我们要用这个精灵来制作瓷片组,用于绘制背景图,但是这个图的左上角是透明的,这是因为GameMaker Studio 2在处理瓷片图时会忽略出左上角单元格的内容,因此我们需要在准备素材的时候提前把左上角的位置空出来。
在创建好精灵之后,我们就可以开始创建瓷片组了,如下图所示:
创建好瓷片组后,同样要将刚才创建的精灵关联过来,然后就会出现下图:
初始的瓷片尺寸是16x16的,而我们的素材是128x128的瓷片,因此需要进行调整,在右侧的属性中把单元格的宽和高改成128后就会显示正常了,这时候就会看到左上角的格子默认是无边框的,所以我们才需要提前准备左上角为透明的素材。
现在一个基本的瓷片组已经完成了,我们要开始用它来绘制背景,首先我们要切换到场景编辑器中,然后我们看左上角的图层列表,跟专门放置object的instance图层类似,瓷片也有自己专属的图层类型:
并且我们这个图层是用来绘制背景的,所以它应该位于敌人、子弹和玩家控制的飞船下方,所以在创建之后还需要调整图层的顺序。然后我们选中瓷片图层就会出现以下画面:
原本是如左侧显示空白画面,此时我们需要去选择关联一个已经创建好的瓷片组,一旦选择就会如右侧所示,直接预览出瓷片的图像内容,此时鼠标可以选择任意一个单元格的画面,然后在左侧游戏场景中进行绘制,跟使用画笔画图一样,可以根据自己的喜好来绘制自己需要的背景图样,而我们的示例则大致如下图,你可以自己尝试一下怎样能画出这个背景(或看视频学习)。
此时预览游戏你会发现游戏已经很有样子了,起码看起来很像是一艘飞船在一个很有金属感(虽然不知道是啥)的场景里跟敌人来回厮杀的游戏了……不过还有一个问题,那就是当你控制飞船移出画面后,飞船就不见了(都出画面了当然看不到啊!),但是我们平时玩游戏应该都知道,很多游戏虽然画面不大,但是游戏地图是十分庞大的,而画面都会跟着我们的主角跑来跑去,那如何才能实现这样的效果呢?答案就是使用镜头视角——View首先我们回到场景编辑器中,看左下角,你会看到下图的内容:
这里有给“room0 properties”——场景属性,里面还有一个“Room Settings”——场景设置,这里面有我们熟悉的宽高设置,调整这个数值,就可以任意调整我们游戏场景的大小,这个场景就是我们一般理解的游戏地图,这里设置的越大,那我们在游戏中可以探索的范围也就越大,在这个示例中我们把宽度设置成了2048,预览一下游戏你会发现游戏的窗口变得很宽,甚至有一小块已经超出了屏幕(如果你是2k屏当我没说T_T),因为这个屏幕分辨率宽度只有1920,小于游戏场景的2048,所以会出现这种情况。那我们如果希望游戏画面还是1024x768,但是游戏场景又是2048x768又该如何设置呢?请看下图
还是在刚才的地方,勾选了“Enable Views”以后就可以开启镜头视角了,然后下面会出现“View0”到“View7”等多个镜头选项,我们这里只需要使用一个镜头,因此展开“View 0”即可,然后里面有一个“View Visible”的选项,勾选后,右侧的场景中就会显示出一个白色边框,用来示意这个镜头的画面,而在下方还可以设定这个镜头的大小。然后我们这个镜头还需要设定一个跟随的对象,这样镜头才知道自己要跟着谁走,而通常在游戏中我们的画面都是跟着主角走的,因此我们这里要设定成我们玩家控制的飞船——“obj_player”
同时下面还有几个参数是用来设置横纵向移动的单元格尺寸和速度的,因为我们画面的背景单元格是128,我们这里也设置为128比较合适。然后我们测试一下游戏,就会看到已经可以正常跟随镜头移动了
本节视频解说地址:【中文教程】GameMaker Studio 2官方教程4/8——瓷片&镜头
GMS2官方教程系列3/8——制造敌人
本节教程是讲解如何生成敌人和以及销毁实例等操作,不过在最开始我们先介绍一下如何设置游戏的帧数,游戏的帧数决定了游戏画面的流畅程度,一般每秒的帧数(FPS)与画面流畅性成正比,当然消耗的资源也会同步增加,但是在性能足够的情况下,用些许性能换取更流畅的画面是值得的,因为这样可以给用户以更好的游戏体验。
在右侧的资源树底部有个“Option”的选项,双击其中的“Main”就会弹出一个设置框,其中可以看到有个“Game Frames Per Second”就是游戏的FPS设置项了。
另外在“Main”选项下方还有个“Windows”的选项,该选项是指针对“Windows”平台编译发布游戏时可以根据平台特性进行一些定制化设置(如果发布iOS、Android或MacOS等平台也会有对应的选项),现在我们要在“Windows”的平台设置中选择“Graphics”图像设置项,在其中勾选“Interpolate colours between pixels”的选项,这个选项可以提供像素差值平滑过渡的功能,使得图形边缘过度更自然,对非像素风格的游戏而言是很有必要的。
在完成以上的设置之后可以运行一下游戏看看效果,应该能发现移动起来更加“丝般顺滑”了:)然后我们开始正式学习敌人的生成,首先还是要创建一个敌人的精灵(并关联图片)和对象(关联刚创建的敌人精灵),这个操作应该已经非常熟练,就不再配图赘述了。(也可以从视频中观看)然后我们在敌人的对象中添加一个“Create”事件,然后在事件中添加以下内容:
hp = 5 ;
spd = 1.5 ;
这里的“hp”就是我们给敌人定义的血量,稍后如果HP降为0敌人就会被摧毁,下面的“spd”则是我们给敌人定义的运动速度,可能一些朋友会觉得奇怪,为什么不用上节课中的“speed”属性,那个“speed”是对象自带的一个速度属性,在这我们不想修改其自身属性,因此单独定义了一个变量,然后会在后续的过程中使用这个值来使敌人进行运动,也可以通过这个学习新的移动的方法。然后我们再给敌人对象添加一个“step”事件,让它真正动起来的代码就要在这里写了:
简单的说,我们希望敌人能追着玩家控制的飞船跑,那我们的代码里就需要判断玩家控制的飞船是否存在,如果存在,就要朝着它所在的方向前进了。
if (instance_exits(obj_player))
{
move_towards_point(obj_player.x,obj_player.y,spd);
}
image_angle = direction;
其中"instance_exits"是内置的一个函数,用来判断某个对象是否存在,因此在其参数括号内填入的就是我们需要判断的对象“obj_player",这意味着只有飞船存在时才会执行下方花括号中的命令。而花括号中也是一个新的内置函数“move_towards_point(obj_player.x,obj_player.y,spd)”,这个函数是命令当前对象朝着某个点前进的,它需要三个参数,前两个是目标点所处的X、Y值,最后一个参数则是这个前进动作的速度,在这里,我们命令它以玩家控制的飞船对象的x、y坐标点为目标,以之前定义的spd速度前进运动。最后我们还设置了敌人对象的图片角度(使其等于运动方向),这样才能保证敌人是一直面朝玩家控制的飞船进行运动。因此我们可以这样来理解上述代码
假如(后面括号中的对象存在(obj_player对应的对象)){ 当前对象朝着括号中的前两个参数作为xy坐标的点以第三个参数为速度前进(obj_player的x坐标,obj_player的y坐标,spd对应的值)}当前对象的图片角度 = 当前对象的运动方向
在完成以上内容后可以去场景编辑器中,用第一节课中学到的在场景中添加玩家对象的方法,同样添加一些敌人的对象,然后就可以启动游戏运行测试一下了,此时你会发现你放置的敌人都会朝着你控制的飞船前进,直到与飞船重叠为止。
但是还有几个问题,首先敌人碰到我们的飞船也没有发生任何事情,敌人好好的,我们的飞船也好好的,另外我们对着敌人倾泻子弹,但是子弹纷纷穿过了敌人,没有造成任何伤害。这是因为我们还没有创建相关的事件和逻辑代码。我们之前给敌人在创建时就设置了一个叫hp的属性,并且hp默认为5,这个hp就是敌人的血量,我们希望当hp变成0时敌人会自动摧毁,那我们首先要在敌人的step事件中添加一段新的代码,就是要时刻检测自身的hp属性,如果变成0就要自我摧毁,只需要一行代码即可实现:
if (hp <= 0) instance_destroy();
就是当hp小于或等于0时,运行一个内置的函数“instance_destroy",这就是把当前的实例销毁的意思。那我们要怎么让敌人的hp降低呢,我们希望当子弹打到敌人身上时这个hp降低,所以我们需要判断子弹有没有撞到敌人,这里我们需要在子弹对象中添加一个碰撞事件,而碰撞的对象则是敌人对象:
创建好碰撞事件后,我们在对应的代码编辑器中填入以下内容:
with(other){
hp = hp - 1 ;
}
instance_destroy() ;
有了之前学到的知识为基础的话,大概能看出来大概是让敌人的血量hp持续降低,然后把自己也销毁了的意思。那这个“with”又是什么呢?因为我们目前在编辑的是子弹对象,而hp则是敌人对象的属性,一般来说在子弹对象中是不能直接去操作编辑其他对象的属性(变量)的,而这个with就是把二者关联起来的方法,一旦关联后就可以跨对象编辑属性了。在with后的参数可以填写具体的对象名称“obj_enemy”,也可以直接填写一个通用的“other”,视不同的情况和个人习惯而定。然后最后的instance_destroy则是让子弹在接触到敌人以后自我销毁,因为我们不希望子弹在击中敌人以后还继续穿透飞行,要让子弹有一种被消耗掉的感觉,因此在接触到敌人以后就让其自己销毁掉了。那完成以上两段代码的编辑以后,我们就知道当子弹接触到敌人以后,敌人的hp会减1,而当敌人的hp降低到0时,就会自动消灭,这就基本上满足了我们对子弹击中敌人这个事件的预期。然后我们要编写当敌人接触到玩家控制的飞船以后的事件代码:
如上图,因为是敌人接触玩家控制的飞船,因此在敌人的事件列表中新增了一个碰撞事件,碰撞对象为“obj_player”,然后其中的代码只有一行:
game_restart() ;
这个代码的意思就是英文字面意思,游戏重新开始,这意味着当敌人接触到玩家控制的飞船以后游戏就会重新开始,这样就可以让玩家重新挑战这个游戏了,虽然很简单,但是基本能实现一个小的闭环了。如果完全按照以上的内容进行编写,你就可以启动游戏进行测试了,你可以让飞船定住不动等着敌人冲过来观察游戏是否重新开始,也可以控制飞船发射子弹去攻击敌人,看敌人是否按照代码所写的被摧毁了,而子弹是不是也在击中敌人以后原地消失了。在以上一切正常运行的情况下,还是会觉得有一点不对劲,因为好像子弹还没打到敌人的身上,子弹就消失了,然后敌人跟我们的飞船还有一点距离的时候游戏就已经重置了,这是什么原因呢?这里就要再给大家介绍一个概念——碰撞遮罩,打开编辑器窗口,选择我们的飞船精灵双击可以看到以下内容:
上面图像上的黑色半透明就是碰撞遮罩,碰撞遮罩就是一个物体的碰撞检测范围,而目前这个区域明显是比飞船本体要大的,所以才会发现还没有完全接触但碰撞事件已经触发的情况,这个遮罩的范围可以用鼠标选中四个角来进行手动调节,或在左侧进行调整,在左侧的“Type”下拉选项中还可以调整遮罩的形状,包括圆形、菱形甚至直接匹配图片的边缘(但是会消耗较多的性能),然后我们依次把飞船、子弹和敌人的遮罩调整至下图的样子:
然后我们再次启动游戏进行测试,此时就不再会有之前那种看画面还没接触到但是碰撞时间已经被触发的现象了。
至此,本节内容已经结束,这一段介绍了如何自定义变量,并通过变量去控制实例销毁,以及如何重置游戏让玩家可以在失败之后反复挑战,另外还有如何通过控制碰撞遮罩来使得碰撞事件看起来更加自然合理。
GMS2官方教程汉化完毕~撒花!
从开始翻译文档,到汉化官方教程视频,差不多一个月的时间了,今天刚好把教程最后两个章节也都上传了(全套视频直达),所以今天发个月度总结。
这套教程内容不算特别难,如果之前有一些其他语言的代码基础应该会更容易理解,我在翻译的过程中也尽量介绍了一些基础知识,希望零基础的朋友也能尽量明白其中的含义,不知道是否有效,如果有问题还希望可以提出,在后续的内容中我会加以改进。
第一次看这套教程觉得不难,但是不跟着视频自己做又总是会卡壳,这次为了翻译真的是一步一步的看了很久,才发现之前看的时候还是有些浮躁,有的点都没有在意到,也算有了不小收获。
另一个让我惊讶的是,在B站的视频居然有人给我充电!而且有两个人!虽然不多,但很受鼓舞,让我觉得做这个事情确实有了价值,也许帮到的人不多,但切实存在,起码给我充电和投硬币的朋友一定是有派上用场吧。
接下来的话应该会从YouTube继续搬运一些教程,或者是根据一些GMS1代的教程看看是不是可以改录GMS2版的,目前来Heartbeast大神正在制作一套平台射击游戏(横版射击)的教程,目前已经有6课了,不过我还没有开始看,准备后面边看边学边翻吧~
最后,在启用公众号第一天发了一个在reddit上的五月挑战,不知道有没有朋友尝试去完成,我自己是做了一个简单的Demo的,六月的挑战又要来咯~一起加油!
GMS2官方教程系列2/8——发射子弹
视频解说直达——【中文教程】GameMaker Studio 2官方教程2/8——发射子弹
跟之前创建飞船一样,我们也需要给子弹新建一个精灵,创建的过程不再赘述,但是要强调一点,子弹的原点位置应当设置在头部,因为头部才是子弹本体,后面的尾焰只是画面效果。
你可以直接在图片上点击设置为原点的位置,也可以调整左上角的坐标值来设定。
在创建完子弹精灵以后我们需要创建一个子弹的对象,然后吧子弹对象跟刚刚创建的精灵关联起来即可,暂时不需要在子弹对象中写任何的事件和逻辑代码,因为我们的目的是让飞船来发射子弹,所以我们要去飞船对象中写生成子弹的代码,下面我们打开子弹对象,并在其中添加一些内容如下:
首先我们会注意到其中有两行注释,即两个“/”后的绿色文字,这些注释是不会被执行的纯文字内容,我们通常用这种方法在代码中进行一些备注,以便于我们在日后回来看代码时能更快明白这些代码的用途,只需要在任意行开头输入两个“/”即可,后面的文字内容可以任意填写。
然后我们会看到我们在之前的运动代码下方添加了一段这样的内容
if (mouse_check_button(mb_left))
{
instance_create_layer(mouse_x,mouse_y,layer,obj_bullet)
}
这段代码的意思是
假如 (后面括号中的鼠标按钮被按下了(鼠标左键))
执行下方花括号中的命令
{
按照后方括号中的条件创建一个对象实例(鼠标的X坐标,鼠标的Y坐标, 当前对象所在的图层,子弹对象)
}
就是说,当鼠标左键被按下时,在飞船对象所在的图层中,在鼠标指针所在的位置上,立刻生成一个子弹对象的实例。
也许有朋友不太明白实例是什么意思,你可以把我们创造的对象理解成一个一个的模版,而实例则是用这个模版做出来的直接在游戏中看到的物体,对象是相对抽象的概念,实例才是在游戏中我们真正发生交互的东西。所以当这段代码被执行以后,我们可以用子弹这一个对象,在游戏中生成无数个实例,如下图:
上述只是为了生成子弹而进行的一个小小测试,我们当然不是希望子弹跟着鼠标生成,而是希望子弹被飞船给射出去,因此它应该在飞船所在的位置生成,那我们只需要在上述代码中做一个微小的改动,即把生成位置的X、Y值进行修改,改成飞船对象自身的X、Y值即可
而且你会发现刚刚我们生成的子弹都是静止不动的,它只是生成了,但是完全不会飞,所以我们还需要给子弹增加一些运动的代码:
如上图所示,我们首先给子弹添加一个“Create”事件,这个事件跟之前飞船的“Step”事件不同,这是只在对象的实例创建的一瞬间才触发的,并且只会触发一次。
我们看到在这个Create事件中我们填入了以下代码:
direction = point_direction(x , y , mouse_x , mouse_y )
direction = direction + radom_range(-4,4);
speed = 16 ;
image_angle = direction;
其中第一个“direction”是对象自带的运动方向的属性,这个方向实用的point_direction这个方法我们在上一节课控制飞船图像时曾经用过,这意味着子弹的运动朝向也是朝着我们的鼠标所在的位置的,这就能确保这个方向与飞船正面朝向一致。
在第二行还有一个第一次出现的“radom_range”函数,这是用来获取随机数的,给这个函数一个数字区间参数,分别传入范围的最小值和最大值,然后这个方法就会从这个范围中随机获取一个数字作为结果给出来,这是为了模拟枪炮发射子弹时的抖动效果,为了让发射角度发生轻微的变化,使用了这个随机函数就可以使角度发生随机正负4度以内的变化。
然后我们还用内置的“speed”属性给子弹设置了一个速度,而上面那个“direction”则是自带的运动方向的属性,因此这两者结合以后就代表子弹会朝着direction所设置的方向以16的速度进行直线运动。
最后我们也要调整子弹图片本身的方向,因为之前我们已经确保运动的方向朝着鼠标,因此这里我们只需要把“image_angle"(图像角度)直接等于“direction”即可。
完成以上内容后我们就可以运行一下游戏看看效果如何了:
基本上已经如我们所想,在按下鼠标左键时,飞船会在正中央的位置生成子弹,然后生成的子弹会朝着鼠标坐在的位置飞射出去,但是我们会发现这些子弹会挡住我们的飞船,这会看起来很奇怪,我们应该都希望这些子弹从飞船下方出现,这样能确保不影响用户操作飞船的视野。
这需要运用场景编辑器中的图层,如果你没忘记上次的教学内容,应该还记得我们的飞船对象是在一个叫做“Instances”的图层上的,而刚才我们给子弹设定的生成图层就是飞船所在的图层,因此他们都在一个图层上,然后根据生成的先后顺序显示了出来,所以我们首先要做的事情是新建一个子弹的专属图层“BulletsLayer”,然后我们把这个图层放到“Instances”的下方,如下图所示:
在图层列表中,越靠下的图层就越显示在下方,在列表上方的图层会遮挡下方的图层,然后我们需要在代码中进行修改,让子弹生成到这个新的图层上:
我们把之前的layer改成了“BulletsLayer”,注意这里要用双引号,然后我们运行游戏进行测试,就会发现子弹已经被飞船盖住了:
到此为止,飞船已经能够正常发射子弹了,不过子弹的发射速度看起来稍微有点快,如果我们想要调整子弹的发射速度该怎么办呢?
我们可以定义一个新的变量——冷却时间(cooldown)
如下图,因为发射子弹的操作是由飞船进行的,因此我们首先给飞船添加一个“Create”事件,然后在其中给飞船定义一个自定义属性“cooldown”,然后默认设为0。
我们设置冷却时间的目的是,希望当这个值在0时按下鼠标左键飞船可以发出子弹,但是发出子弹以后这个值就不再是0,需要等待一段时间以后才会变成0,然后子弹再次发射,如此往复,就可以通过控制发射的时间间隔来控制子弹的发射速度了。
于是我们在发射子弹的代码中添加以下内容:
if (mouse_check_button(mb_left)) && (cooldown < 1)
{
instance_create_layer(x , y ,"BulletsLayer",obj_bullet)
cooldown = 3;
}
cooldown = cooldown - 1;
你会发现在“if”的后方条件中,我们多了一个“&&”和一个新的条件“(cooldown < 1)”。
这个"&&"代表现在需要同时满足前后两个条件,才会触发下方花括号中的命令,任何一个条件不符合都不会触发,因此冷却时间就可以控制子弹是否发射了。
而因为cooldown默认是0,永远都小于1,那如果我们不对这个冷却时间做任何的修改,那就依然会连续发射子弹,所以我们需要在发射子弹后把冷却时间修改一下,这段代码中我们把冷却时间改成了3,因此当子弹发射以后冷却时间就变成了3,3比1大,就导致子弹不会继续发射了。
但是,如果冷却时间永远都是3,那飞船在发射了第一次以后就再也发不出子弹了,所以我们要在后面再增加一个代码“cooldown = cooldown - 1”让冷却时间逐渐变小,直到小于1可以再次触发子弹的发射,就能确保子弹能连续发射但是发射的速度又是可控的了。
此时再运行游戏进行测试就会发现子弹的发射间隔已经好一些了,如果对速度依然不满意可以继续调整冷却时间的值,即发射子弹后冷却时间设置的数字,数字越大则冷却时间越长,子弹发射也就越慢。
以上就是第二课的内容,主要就是如何创建子弹,然后利用自带的运动方向和运动速度设置了子弹的移动方式,并且学习了自定义属性(变量)的方式,以及一些简单的图层位置关系,下一次会讲解如何生成敌人,以及如何销毁实例:)
GMS2官方教程系列1/8——角色移动
今天开始准备翻译一下官方教程的GML版,这套教程虽然简单,但是对于初学者而言是不可多得的入门教材,一步一步的指导新手通过基本的一些操作来完成一个具有一定完成度的游戏,游戏是一个90度俯视视角的射击类游戏。这套教程是全套一共8章,今天第一章的内容主要是介绍如何创建精灵、对象,以及操作对象进行运动。
这里还有我配的中文版视频——GameMaker Studio 2官方教程1/8——角色移动(GML 中文配音版)
第一次做视频问题多多,希望大家包涵
精灵和对象创建
首先我们创建一个玩家的精灵(Sprites),如上图所示,只需要在右侧资源树中选中Sprites菜单然后单击右键选择Create即可新建一个精灵,然后GMS2会自动打开一个精灵编辑窗口,如下图:
这个窗口可以按住鼠标随意拖放合适的位置,也可以按住Ctrl健然后是用滚轮来进行缩放查看。首先我们要给精灵起一个名字,通常我们会给不同的资源设定一些前缀用于区分,在这里我们使用“spr”作为精灵的前缀,同时用“_”分割前缀和名称,要注意起名的时候只能使用字母、数字和下划线。然后我们要给这个精灵设置用于展示的图片,点击“Import”按钮会打开一个窗口,可以在其中选择需要指定给这个精灵的图片
我们也可以导入GIF动画或多张序列帧图片来给精灵设置动画效果,不过在本章暂时不使用这个功能,在后续的教程中会教导大家使用动画功能。我们还可以设置精灵的原点,这个原点就是之后在场景中生成时所设置点的位置,可以直接在图片上用鼠标指定,或通过下图的下拉选项菜单选择预设的位置,在这里我们选择“Middle Center”,就是在图片的最中央。
接下来我们需要创建一个玩家对象,同样在右侧资源树中找到Object的菜单然后右键选择Create
然后会在刚才的精灵编辑窗口下方弹出一个对象编辑窗口:
跟精灵一样,我们首先命名这个对象,同样为了便于区分使用“obj”作为前缀,然后我们要把这个玩家对象跟之前创建的玩家精灵关联起来,点击“No Spite”处会出现一个窗口,可以从中选择项目中已经创建的精灵,这里我们选择刚刚创建单位“spr_player”的那个精灵
现在我们的玩家对象基本已经有了个雏形,虽然还没有处理任何的逻辑,但是一个基本的对象已经完成了,我们可以把它放到我们的游戏中实际看看到底是怎样的,我们回到右侧资源树中找到room这个选项,然后展开,我们会看到已经有一个默认的“room0”存在了,这是因为GMS2游戏全部基于游戏场景,因此默认至少会有一个场景存在,我们双击这个“room0”就会进入场景编辑器的界面
场景是整个游戏的基础,我们会在场景中设置背景图片,组织各种对象来生成我们所看到的游戏,现在我们用鼠标从右边把刚刚做好的玩家对象直接拖入场景中,如果按住Alt键直接在场景中单击鼠标会直接生成当前选中的对象。
放置好我们需要的玩家对象之后,我们可以单击左上角的Play按钮来运行一下游戏试试看效果:
经过短暂的编译之后游戏就会自动启动,这时候我们只能看到一个黑色的背景上有一个孤零零的飞船,而不能进行任何的操作,因为我们没有写任何有关的代码。
动起来
让我们回到GMS2中,打开玩家对象的编辑窗口,现在要开始添加一些事件和功能性代码让我们的飞船动起来。我们可以看到在对象编辑窗口的右侧有一个事件窗口,而所谓的事件就是我们用来进行逻辑判断最基本的元素,而我们在游戏中所说的逻辑就是:
当某件事情触发时,执行某个特定的命令
单击“Add Event”会打开一个事件列表,这些是GMS2默认的事件列表,其中我们这次要使用的是Step这个事件,这个事件比较特殊,它会在游戏每一帧都自动触发一次,可以理解成在游戏过程中在不断触发,如果你在游戏设置中把FPS设置为60帧/秒,那就意味着这个事件会在一秒之内连续触发60次。当我们选择Step事件后,会自动在右侧打开一个新的较大的窗口,这个窗口就是用来编写执行的命令的代码的窗口
在这里我们写下一行:
x = x + 4 ;
你会发现这个x是绿色的,这说明这是对象的自带属性,这个x就是对象在场景中所处位置的水平位置,我们首先要让这个对象发生一个水平向右的位移,那就是要让这个对象的x值越来越大,所以这一行就代表着每个step事件被触发时,对象的x值都会增加4个像素,而由于step事件会不断触发,这个对象也就会不断向右进行移动了。当写完这行代码以后你可以再次运行游戏来预览一下这个运动的效果,你会发现游戏启动后飞船会一直向右移动,直到飞出画面,因为我们没有设置任何停止或控制的命令,这个对象就会永远向右移动下去。
可操作
但刚才的移动我们依然无法操作,接下来我们要增加一些代码,以确保我们可以控制这个精灵的移动。我们的目的是写一段内容,确保当我们在键盘上按下向右的方向键时,飞船向右进行移动,当我们松开按键时,飞船就停住不动那么我们就需要引入”if“这个函数,如下图所示:
if (keyboard_check(vk_right)) x = x + 4 ;
这一行内容代表
假如 ( 检测到被按下 ( 右方向键 ) ) x = x + 4 ;
再直白的翻译就是
假如 ( ( 右方向键 ) 检测到被按下时 ) x = x + 4 ;
在这里我们把需要执行的命令”x=x+4“直接放在了if的条件之后,这在GML语言中是可行的,另外还有一种写法,是把命令用“{}”包围起来放到if方法下方:
if (keyboard_check(vk_right)) { x = x + 4 ;}
这时候我们再启动游戏测试一下,就会发现已经达成了我们的目标,只有在按下右方向键的时候飞船才会向右移动了。接下来我们重复刚才的步骤,把上下左右的方向操作全部完成即可:
这个操作我们可以直接复制刚才的代码,然后在其中进行一些修改,首先把按键的判断分别指向上下左右四个不同的方向键,然后把按下方向键以后需要执行的命令进行调整。这里我们要明确一个概念,游戏中场景的x,y的原点默认是在左上角的,因此x越大意味着越向右,越小则越向左,y值越大意味着越向画面下方,越小则越向上,因此数值的加减关系务必定义正确。
if (keyboard_check(vk_right)) x = x + 4 ; if (keyboard_check(vk_left)) x = x - 4 ; if (keyboard_check(vk_up)) y = y - 4 ; if (keyboard_check(vk_down)) y = y + 4 ;
当以上代码都完成后,再次启动游戏进行预览,我们会发现现在可以通过上下左右四个按键来任意控制飞船的移动了。
飞船的角度
最后我们要设置让飞船能时刻保持正面朝着鼠标所处的位置,这意味着我们需要随时调整精灵图像的角度,在GMS2中我们有一个默认的属性“image_angle"来控制这个角度,然后还有一个自带的函数”point_direction"(点对点夹角)可以设置点对点的夹角来实现我们需要的效果:
如上图所示,image_angle是对象自身图像的角度,我们把这个角度用“点对点夹角”的函数来进行控制,当我们输入这个函数以后,在输入参数时,在代码编辑器底部我们会看到一个提示“point_direction(x1,y1,x2,y2)”,这代表这个函数需要4个参数,分别是x1、y1、x2、y2,这是两个点的x、y值,这个函数计算的是两点所连成的直线与水平线之间的夹角,而我们现在要设置的两个点就是对象自身的原点和鼠标所处的位置,因此我们填入以下内容
image_angle = point_direction(x,y,mouse_x,mouse_y)
其中x,y分别是对象自身原点的x,y值,mouse_x和mouse_y则是自带属性中鼠标所处的位置的x,y值,因此这就意味着这个对象的图片的角度要时刻与这两点的夹角保持一致,就刚好能满足我们所要达成的目的——让飞船的正面时刻朝向鼠标所在的位置。
这是官方系列教程中的第一章,只是简单介绍了物体运动的操作方式,后续还会有更多内容陆续赶来~
GameMaker Studio 2中的脚本编辑器
脚本编辑器(Script Editor)
在GameMaker Studio 2中有许多地方都可以编写代码,无论是对象、场景还是各个实例,并且GML和拖放编程模式都内置了大量函数来让降低编码的难度。但是你仍然会需要自己创建一些特殊的方法来进行调用,或是有个别方法你会在许多地方都要复用,为了方便管理而需要把一部分代码单独存放,这就是脚本存在的意义。
注意:本节所涉及的脚本,在脚本中编写的代码与“事件”、“场景”或“实例”中创建的代码相同,本节所说的功能适用于所有脚本。注意:本页面介绍的都是用GML语言编写脚本,但你也可以用拖放模式来创建脚本。无论用什么方式编写代码,本页介绍的编辑器本身的功能全部适用。
脚本都是用GML语言编写的(详细的GML介绍可参考GML概述),这是GameMaker Studio 2内置的编程语言。一旦你逐渐熟悉了GameMaker Studio 2,并希望能做些更复杂的东西时,建议你开始学习GML语言,因为这可以更大扩展了制作游戏的可能性。你还可以使用拖放编程的方式来编写脚本,但是这需要另一套编辑器,这会在“操作脚本”的章节进行介绍,同样可以使用不同的输入变量、字符串、布尔值和各种特殊的值,这些值通常被称为实参,偶尔也被称为形参。如果你需要在对象中调用这个脚本,你可以把脚本名称作为GML语言的函数名来使用。你可以在资源树中右键单击并选择重命名来给脚本重新命名,需要注意,脚本名称必需符合函数的脚本规则,必需以字母开头,并且名称中只包含字母、数字以及下划线“_”符号。如上所述,你可以通过参数把一个数字传递给一个脚本,并使用这个参数来执行你所编写的任务代码。为了便于理解举一个例子,设想一个拖放操作(或是用GML写的代码),仔细想想它是如何工作的……你把它放在一个事件的代码区中,指定一些参数,它的实例就会根据你的要求行动。其实代码是完全一样的,唯一的区别是这是你自己编写的。我们不仅可以向脚本传递参数,同时也可以要求脚本返回某些值(使用return方法),因此我们可以用这个方法来构建复杂的计算方法(数学方法)或是进行一个复杂的碰撞检测或其它任意事情。但务必注意,返回方法应该在脚本最末的地方,确保在返回值之后没有任何需要执行的代码,因此你需要提前想好脚本的代码结构。当你首次创建资源时,会打开脚本编辑器,其中包含以下选项:
脚本标签
脚本编辑器的窗口顶部有一个标签选项卡,这让你可以同时打开编辑多个脚本(也可以在首选项中修改设置,改为每个脚本一个独立窗口)。你可以单击脚本标签,然后拖放进行排序操作,或者也可以将选项卡从窗口中拖出来形成一个独立窗口并单独放置到工作区中。如果将脚本标签直接拖出IDE窗口,则会生成一个独立的新的IDE窗口来存放该脚本,与主窗口的使用完全一致。
编辑操作
这里是创建脚本编写代码的主要区域,脚本需遵循GML语法规则进行编写(详细需参阅“GML概述”部分),而且编辑器自带补全提示功能:
当你编写代码时,编辑器内会弹出(一般会有少许延迟,可在首选项中设置)提示窗口,其中会以首字母顺序依次排列可能相关的方法、参数等内容,您可以从中选择您需要的那项。在使用代码编辑器时,你还可以选中一行代码,然后使用Ctrl+C,Ctrl+X和Ctrl+V等标准的快捷键来进行复制、剪切和粘贴的操作。在编写代码的过程中,你可能会不小心写错,这时候IDE就会警告你犯错了,它会在出错的那一行前标记红色然后还有一个红色的感叹号“!”图标,此时你把鼠标放到错误提示区可以看到简单的错误描述,在输出窗口则会有完整的错误信息:
另外,你可以在代码中进行注释。注释对代码而言十分重要,它能把代码进行分割,保持更清晰的结构,让人一目了然为什么这些代码会在各自的位置。另外如果你与团队其他成员一起协作时,注释可以作为有效的笔记,让其他人能明白你已经做了些什么。即使你是独自一人进行开发,保留代码注释也十分重要,特别是你有其它事情导致你暂时放下了这个项目,一段时间后再回来看它时,能更快回忆起当初的工作内容。为代码做注释非常简单,你只需要在任何文本行的开头敲下“//”即可,或者也可以用段落注释,格式是“/* 注释内容 */”。另外也可以用快捷键直接操作Ctrl+K是标记注释,Ctrl+Shift+K则是取消注释格式,下图是两种注释格式示例
脚本中还可以支持JSDoc类型的注释,这样你就可以现在JSDoc中定义好一些通用的内容,然后在编辑代码时会显示在自动完成提示列表中。
你可能已经注意到了,脚本中的文本颜色有些是彩色的。这是脚本编辑器在解析了对象中内置的变量、函数等内容,然后根据配置对不同内容进行了颜色编码,这种颜色编码有助于你看的更加清晰不容易出错,假如你拼写了错误的名称或关键词就会立刻得到提示,但如果你不喜欢这种颜色编码也可以在首选项中选择关闭(或使用F10),其中也可以自定义不同的颜色编码。
在编辑器中任意位置右键单击可以打开以下菜单
除了常规的剪切、复制和粘贴等功能外,你还可以选择将选中的文本设置为注释格式,添加或删除缩进,或将代码窗口分割为1、2、3行来显示。最后的这些选项可以让你把窗口分割显示以方便在其中拖放不同的脚本来比对其中的内容:
这种浏览方式在比对或需要同时查看两个脚本时会非常有效,可以避免再开一个窗口或在几个标签之间来回切换。菜单里还有一个在Debug模式下使用断点的选项,最后是一个将脚本在GML代码模式和DnD拖放模式下切换的选项。要注意,如果把代码转换为DnD拖放代码块时,并不会为每一行代码单独创建独立的操作,而是用一个专门的区块把原先所有的代码都存放在其中。在编辑脚本时,你还可以使用代码片段的功能来提高效率。按下F4(译者注:官方手册写的是F2但已经过时了,现在应该是F4)键就会弹出一个代码片段窗口,你可以自定义自己需要的代码片段,只需要把他们保存到GameMaker Studio 2的目录下:\GameMaker Studio 2\TextEditor\snippets.txt中即可,你可以用任何文本编辑器来编辑这个文件:
- 每个代码片段都是单独的一行(不能有空行)
- 每个代码片段都以片段名称为开头(会显示在弹出列表中),名称后跟一个冒号“:”,后面再接具体的代码段
- 使用"#"号作为换行符,并把需要被选中的文字放到两个"|"号之间(译者目测无效)
请参考文件中现成的代码段例子,以了解该如何按照上述规则来编写自己的代码段,强烈建议你在进行修改操作之前首先备份一下该文件,并备份你所做的任何修改操作,因为一旦重新安装或更新GameMaker Studio 2都会重置该文件,此时你可以用你备份的文件来恢复你之前所做的修改。
译者注:下面贴出来的这段是目前默认的snippets文件中的预设内容
1 - block:{# |STATEMENT|;#}#
2 - if:if (|CONDITION|)#{# STATEMENT;#};#
3- if-else:if (|CONDITION|)#{# STATEMENT;#}#else#{# STATEMENT;#};#
4 - for:for (|INITIALISATION|; CONDITION; INCREMENT)#{# STATEMENT;#};#
5 - for i:for (i=0; i<|CONDITION|; i+=1)#{# STATEMENT;#};#
6 - while:while (|CONDITION|)#{# STATEMENT;#};#
7 - do:do#{# |STATEMENT|;#}#until (CONDITION);#
8 - repeat:repeat (|EXPRESSION|)#{# STATEMENT;#};#
9 - switch:switch (|EXPRESSION|)#{# case EXPRESSION: STATEMENT; break;# default: STATEMENT;#}#0 - with:with (|EXPRESSION|)#{# STATEMENT;#};#comment:// |TEXT|multiline comment:/*************************************************# |TEXT|# *************************************************/
信息栏
IDE底部的信息栏会显示你当前编辑的行数以及所在的位置。同时也是一个代码提示器,它会以文本的形式提示你正在编辑的功能或函数所需的参数等信息。当你在编辑器中编写相关函数代码时,此处会突出显示该函数对应所需的参数。如果你在JSDoc脚本注释中自定义了帮助信息,这里也会进行相应的提示。
GameMaker Studio 2中的图像编辑器介绍
图像编辑器可以用来自己绘制创建或修改你导入的精灵图片。如果你以前使用过任何一种图像软件,那这个编辑器对你而言应该很容易上手,不过这里还有几条在刚开始使用GameMaker Studio 2的图像编辑器时很难发现的小技巧:
- 当你绘制多帧画面时,你可以直接以动画的形式去进行绘制!只要先点击“帧控制”工具栏上的播放按钮,然后选择一个笔刷在编辑器窗口开始绘图,你会发现编辑器中的画面在不停变化,而你绘制的内容会分配到不同的帧上然后串联起来。你可以尝试调整帧速率直到你满意为止,一旦你熟悉了这套工作机制你就可以随时创建各种动态精灵和的动画效果了。
- 你可以把图像编辑器的标签页从主工作区拉出来形成要给独立的窗口,如果你有多个显示器时这会很方便。
- 当你使用复制功能时,比如说你选中并复制了一张图片,这张图片会变成一个笔刷被添加到你的笔刷列表里,这意味着你可以选择图像中的任意部分然后在接下来的时间里随时取用和绘制这个图像,无论是画线还是多边形,或者随手涂鸦。笔刷同样可以缩放并着色。要注意,在这里你不能直接使用粘贴功能,因为所有复制的内容都会被添加到画笔列表,所以你“粘贴”的内容也会被添加进画笔列表。因此粘贴通常用于从其他程序中获取图片然后贴进编辑器里来。
- 这儿还有一套便利的图层编辑器,你可以给每个精灵创建很多不同图层,然后可以根据自己的需求来进行排序或分组到不同的文件夹中,这样可以很方便的创建更多复杂的图像 。
以上几条只是图像编辑器中的部分进阶功能。想了解完整的编辑功能,请阅读以下内容,将会详细说明编辑器中各部分的功能:
帧视图(Frame View)
这部分会按照动画顺序排列显示各帧画面,你可以点击左侧的“+”号按钮添加新的帧——或者也可以通过图像菜单添加——你也可以拖动任意帧来重新排列顺序。在左上角点击按钮可以切换洋葱皮肤模式,在此模式下你可以可以透过当前编辑的帧以半透明的形式查看前一帧或后一帧的画面内容,便于在绘制动画时对细节进行调整,同时在该模式下两侧会出现范围框,你可以拖动两侧的端点来控制要显示的前后帧数量。在洋葱皮肤的开关下方有一个用于设置动画循环模式的按钮,可以切换“循环播放”(到最后一帧后从第一帧开始重新播放)和“乒乓播放”(到最后一帧后反向朝第一帧方向播放)两种模式。底部还有一个播放按钮用来控制动画的开始和暂停。你可以点击任何一帧来编辑其中的画面内容,被选中的帧顶部有一个删除图标,单击即可删除该帧。你也可以按住Ctrl键然后用鼠标左键一次选择多帧画面,此时点击删除会把选中的帧全部删除。
帧信息(Frame Information)
这条工具栏包含了帧控制功能,你可以在这里设置动画播放的速度,帧动画的速度可以基于”每秒播放的帧数“或”每一帧游戏播放的动画帧数“两种单位进行设置,右侧会显示帧的总数量以及当前帧的序号,你还可以点击左侧的图标来隐藏这一栏
画布控制(Canvas Control)
本区域主要处理主画布以及其中内容的显示方式,主要有以下选项:
- 网格画布
这个选项会开启/关闭画布上的网格。GameMaker Studio 2中可以将画布划分为多个网格,网格的默认尺寸是1像素,但是你也可以点击网格菜单按钮弹出下列选项来进行修改:
这些选项允许你设置网格的颜色和透明度,以及网格的尺寸(可以设置X、Y值),你还可以开启或关闭网格吸附功能(默认是关闭的)。
- 画布缩放
这些按钮可以控制当前画布的缩放级别,你可以放大或缩小画布,点击按钮可以将正在编辑的图像画布缩放至1:1实际大小。你也可以按住“Ctrl”键然后滚动鼠标滚路来缩放图像,同时按下“Ctrl”键和“回车键”则可以将图像缩放至1:1实际大小。点击按钮则可以直接将图像缩放至符合当前编辑窗口的尺寸()
- 二分画布
单击该图标可以在单画布、水平分割以及垂直分割三种形态之间循环切换。在分割画布状态下,每个画布都会有独立的一个画布控件,你可以放大其中一个画布并缩小另一个,并且你对其中任意一个画布所做的操作都会实时反映到另一个画布上。想要修改画布的视图状态你可以点击下拉选项直接选中你想要的视图状态或持续单击该按钮直至切换到你想要的视图。
绘制画布(Draw Canvas)
这是图像编辑的主要窗口,你可以使用右侧工具栏中的各种工具来在选定的图层上进行绘制操作。你可以从编辑器右上角选择或自定义画笔,然后使用鼠标左键或右键进行绘制(可以通过取色器给左右键分别着色)。你也可以按住“Ctrl”键然后滚动鼠标滚路来缩放图像,同时按下“Ctrl”键和“回车键”则可以将画布缩放至1:1实际大小(你也可以用上面介绍的画布控件)。另外你还可以按下鼠标中键或同时按住“空格键”和鼠标左键进行拖拽操作来移动画布。
画布值(Canvas Values)
地步的这个小条中显示了编辑器中鼠标的位置以及选择工具的高宽值等信息。
画笔(Brushes)
你可以在这里选择不同的画笔用于绘画。默认的画笔是不同尺寸的方形和圆形笔刷,但你也可以在图像层自己创建自定义画笔,只需要在图像上选取你需要作为画笔的部分然后使用“Ctrl”和“C”键来复制该部分图像。这个被复制的图像会自动加入到笔刷列表中,你可以像使用其它笔刷一样来使用这个画笔,比如直接绘制线条。要注意的是默认的笔刷颜色是白色的,但如果你使用取色器修改画笔颜色,该画笔会被着色为新的颜色。如果要从列表中删除一个画笔,只需要单击这个画笔,然后按删除键即可删除。
取色器(Colour Picker)
在这个窗口你可以用使用各种滑块工具来进行颜色自定义操作,也可以直接输入RGBA值或HVS值来自定义颜色。此外在取色器中还有一个选项菜单,可以用来跨精灵管理自定义调色板。
因此你可以在创建精灵时自定义调色板,然后把资源树中其它任何精灵设置为该颜色,或者也可以打开任意一个精灵图像,然后从资源树里选其它某个精灵导入对应的调色板。
工具栏(Tools)
下面我们介绍GameMaker Studio 2自带的各类绘图工具——请注意所有的工具都可以使用鼠标左键或右键进行选取,并且大部分工具都有自己的键盘快捷键(一些重要的会在工具介绍过程中直接列出,完整列表请参阅快捷键页面)。大部分工具还有一些额外选项会显示在图像编辑器的顶部,如下所示:
图标 | 功能介绍 |
---|---|
这是铅笔工具,它可以用你所选择的画笔及颜色进行绘制操作,你还可以在顶栏中设置大小或是否开启平滑功能(插值)。请注意你也可以按住“Shift”键和“Z”键然后按住鼠标左键拖放来设置画笔尺寸,或者直接从右上角的预设画笔中选取。 | |
这是橡皮擦工具,它会使用你所选取的画笔形状来擦出你鼠标点击的区域。选择此项时同样可以使用顶部的额外工具栏来缩放画笔或开启/关闭平滑过渡效果(插值) | |
这是油漆桶工具,使用这个会用当前颜色填满图像中近似色且相连的一整块区域,你可以用顶部的滑块来调整近似色的容差值 | |
这是颜色置换工具,当你选择该项时,你可以用鼠标左键或右键点击图像中的任意像素,图中所有相同颜色的像素都会被点击鼠标设置的颜色所替换。顶部栏有一个调节容差的滑块,你可以设置像素颜色容差值——越低则取色越精确,调高则会包含更多类似所选颜色的像素点。如果之前你使用过选择工具,则只有被选中区域内的像素会被修改。 | |
这个工具可以用来绘制一条连接两点的直线。首次点击会创建出一个起始点,然后在其他任意地方再次点击鼠标左键会新建一个点然后自动绘制一条直线连接两个点。这条线会用当前选择的画笔绘制,并且可以在编辑器中修改画笔属性(尺寸、平滑度等) | |
这个工具将绘制一个矩形的线框或区域,点击左上角则绘制外框,点击右下角则是绘制填满的整块区域,在顶部的工具栏中可以选择二者兼有模式(或者按住“Shift”键然后分别点选图标的左上及右下部分),工具栏中同时可以设置画笔的尺寸以及平滑度(插值)。请注意你可以按住“Alt”键然后拖拽鼠标会以起始点为中心绘制矩形,按住“Shift”键拖拽可以绘制正方形。 | |
这个工具将绘制一个圆形的线框或区域,点击左上角则绘制外框,点击右下角则是绘制填满的整块区域,在顶部的工具栏中可以选择二者兼有模式(或者按住“Shift”键然后分别点选图标的左上及右下部分),工具栏中同时可以设置画笔的尺寸以及平滑度(插值)。请注意你可以按住“Alt”键然后拖拽鼠标会以起始点为圆心绘制圆形,按住“Shift”键拖拽可以绘制正圆形。 | |
这个工具将绘制一个多边形的线框或区域,点击左上角则绘制外框,点击右下角则是绘制填满的整块区域,在顶部的工具栏中可以选择二者兼有模式(或者按住“Shift”键然后分别点选图标的左上及右下部分),工具栏中同时可以设置画笔的尺寸以及平滑度(插值)。单击鼠标左键会添加新的点并自动闭合为新的多边形,当绘制出你所需要的多边形后你可以选取其它工具会提示你保存刚才绘制的图像。 | |
曲线工具,它可以用你所选择的画笔创建曲线,你单击鼠标会设置一个点,按住拖动鼠标会形成曲线,松开鼠标然后重复添加其它的点和曲线以完成绘制操作。绘制路径的画笔同样可以使用顶部的工具栏修改尺寸或开/关平滑过渡效果(插值)。顶部栏中还有一个“Iterations”设置项可以定义路径的平滑度(数值越低越粗糙越高越平滑,默认为10) | |
文本工具,它会创建一个文本图层,你可以输入任何文字内容。你可以从图像编辑器顶部的工具栏中选择你所需要的字体。 | |
滴管工具,使用该工具可以从你正在编辑的图像中采集你需要的颜色 | |
使用这个工具可以选取一块矩形区域。你可以用ESC键或从图像菜单中的“取消选择”功能来取消当前的选区 | |
画笔选取,使用这个工具可以用任何画笔(包括自定义画笔)来绘制选区,该工具的所有快捷键与铅笔工具相同。 | |
魔棒工具,使用这项将会根据容差值来选择相同/似颜色的区域。如果勾选了“仅颜色”选项,则不会考虑透明度因素,你可以用ESC键或从图像菜单中的“取消选择”功能来取消当前的选区 | |
旋转工具,如果你用选择工具在图像中选取了一个区域,单击本选项可以将所选区域进行从 0°到360°任意角度的旋转操作。如果你没有选取任何区域则可旋转你当前的画笔。只需按住鼠标左键然后向左或向右拖动鼠标即可,活在顶栏中输入旋转角度。你可以按下ESC键或回车键或直接选取其它工具来确认旋转角度。要注意这个旋转操作不会修改你的原始画笔或选区图像,而是以旋转后的画笔或图像为素材创建一个新的画笔。另外还要注意你可以使用快捷键“Z”来旋转任意选区或画笔,并且这个快捷操作不会创建一个新的画笔,而是只对当前画面或画笔生效。 | |
这是镜像工具,选择这项会将当前画笔沿垂直方向进行水平翻转(即左右颠倒),这个选项不会创建新的画笔,只是临时修改当前画笔的绘制方式。 | |
这是翻转工具,选择这项会将当前画笔沿水平方向进行垂直翻转(即上下颠倒),这个选项不会创建新的画笔,只是临时修改当前画笔的绘制方式。 | |
这是移动工具。当你选择该项时,可以按住鼠标左键并拖拽来移动图层中的内容。要注意所有超出画布以外的像素都会不可见,另外当你切换工具时图像会以当前画布的尺寸进行裁剪。另外如果你在图像中进行了选取操作,移动的将是选取的像素内容而非整个图层。 |
图层编辑器(Layer Editor)
你可以为图像的不同部位创建各自分离的图层,并且可以利用画笔和各类工具对这些图层进行绘制。点击图标就能创建一个新的图层,点击图标删除图层。在图层上按住鼠标左键向上或向下拖拽可以给图层重新排序以符合你的需求,你还可以使用来创建文件夹,然后用鼠标把图层拖拽放进文件夹来重新组织管理这些图层。如果你双击某个图层(或鼠标右键选择“编辑图层属性(Edit Layer Properties)”)你可以进入“图层属性(Layer Properties)”窗口:
在这个窗口中你可以给图层重新命名或设置叠加模式(即该图层与下面的图层的混合叠加方式),目前有“普通模式”、“减弱叠加”、“多重混合”三种不同模式。下面还有个透明度的滑块,但有一点需要注意,这个透明度会与像素本身alpha值相叠加显示——比如说,你的像素是50%透明度,你又将图层设置为50%,那最后呈现出来的像素是25%透明度的。
菜单栏(Context Menu)
除了图像编辑器中的这些工具外,在编译器(IDE)顶部的菜单栏中还有一些额外的菜单可用:菜单展开后有以下几项
图像菜单(Image)
图像菜单中有以下选项:
- 剪切选中帧
- 复制选中帧
- 粘贴
- 全选——选择所有图片
- 取消选择——取消所有选中的图片
- 反选——反选当前选中的图片
- 添加帧——在精灵中增加一个空白的新帧
- 插入帧——在当前选中的帧后插入一个新的空白帧
- 删除选中帧——从精灵中删除所有选中的帧(你可以使用Shift或Ctrl键配合鼠标左键选择多个帧)
- 导入图片——从硬盘中载入一张图片来生成新的一帧。你可以一次选择多张图片来生成多帧画面,当你选择导入图片后会显示以下窗口
在这里你可以对即将导入的图片进行调整来适配当前精灵,你可以修改图片尺寸、画布尺寸,也可以对图片进行裁剪,甚至可以设置放置的锚点。
- 转换成帧——这个选项可以把一张图片分离成多帧画面。首先你需要创建一个包含所有动画内容的单帧画面(或导入一个条形图),如下图所示:
当我们想要转换这样一张图片时,你可以在下面这个窗口中进行设置:
在这里你可以设置如何分割一张图片,包括帧数量、单帧图片的高宽等等。
- 导入条状图——这个选项会打开一个资源管理器让你寻找并导入一张条状图用来创建序列帧。当你选中并导入图片后,会自动打开上一条中的转换帧的窗口。
- 重设所有帧——选中这个选项会打开下面的窗口,你可以一次设置所有的帧的尺寸:
你还可以选择不同的箭头来设置锚点,按像素或比例进行尺寸调整,还有一个等比例缩放的选项。在右侧还有一个小的预览窗口。
- 缩放所有帧——这个选项允许你对所有的帧进行缩放操作,一旦选择会显示以下窗口
在这里你可以按像素或百分缩放图像,也可以选择是否等比例缩放,还可以根据需求选择开启像素平滑过度。
- 裁剪所有选中帧——这个选项只有当你在图像编辑窗口中选择了一块区域时才能使用,一旦选择会把图像按照选中的区域的包裹体进行裁剪(所有的帧都按照该区域裁剪)。
- 镜像——这个选项会把选中帧左右颠倒翻转显示。
- 翻转——这个选项会把选中帧上下颠倒翻转显示
- 顺时针旋转90度——这个选项会把所有选中帧顺时针旋转90度
- 逆时针旋转90度——这个选项会把所有选中帧逆时针旋转90度
视图菜单(View)
视图菜单主要有以下几个选项:
- 1:1——把图片缩放到实际尺寸并居中放置到编辑窗口中。
- 适应屏幕——把图片缩放到恰好填满编辑窗口的尺寸。
- 网格切换——切换像素网格,这功能与画布控制(Canvas Control)里的网格按钮功能相同。
- 洋葱皮肤设置——修改洋葱皮肤的设置,点击该选项会打开一个类似下方图示的窗口,在这里可以设置显示的前后帧数量以及显示的透明度和颜色。
效果菜单(Effects)
效果菜单可以添加你自定义的效果插件,默认只有以下一个效果:
- 灰度——根据你的选择去掉一部分图像饱和度,你可以选择把这个效果作用于当前图层、可见图层或所有图层。
GameMaker Studio 2中的对象编辑器
对象编辑器(Object Editor)
对象(Object)是我们在游戏中使用的以及用来做各种操作的一切的基础组件。大部分情况下对象都会有一个对应的精灵(Sprite),以方便我们在游戏场景中可以看到对象本身,但也有些情况下它们会被放到幕后而不显示出来,只是作为控制器来处理一些特殊的事件或用于计时之类的操作,对象可以被赋予一些行为操作,也可以与其他对象发生交互事件,事实上你在游戏中看到的大部分内容都是基于不同对象之间的交互所产生的结果。而我们说“基于”是因为我们其实并没有吧对象直接放进游戏场景中,游戏中你看到的是对象的实例,一个实例可以理解成是对象资源的副本(或克隆体)。你需要牢记这一点,因为实例和对象本身是不一样的,它们各自拥有自己的一套函数来作用于它们本身。为了搞明白这一点,请仔细思考一下GameMaker Studio 2制作的游戏。所有的角色、怪物、球、墙壁等等都只是你在资源树中所创建的对象。你可以在“场景编辑器”中把对象放进对应的游戏场景,以对象为模版创建出实例。实例会根据编辑器中书写的代码实现相应的调整,比如缩放尺寸或着色,或其它基于对象模版的其它属性。所以当我们说有些东西会影响或改变一个实例时,我们其实是说一个对象在这个场景内的一个实例会发生变化。只有那一个实例会变化,其余实例则不受影响。但是,如果我们对对象本身进行操作和修改,那意味着我们修改了资源树中的对象本身,这种操作会影响所有由这个对象所产生的实例。因此,对象其实就是实例的模版,而实例才真正参与到我们的场景中来用于制作游戏。要在游戏中创建对象,你只需要在对象资源文件夹上点击鼠标右键然后选择“创建(Create)”选项即可,这会打开下面的窗口:
详情(Details)
这这个窗口中你可以给对象起个名字,名称中不能包含空格或非法字符(仅允许字母和数字以及下划线“_”符号),并且应该简单明了容易记住,以提高之后使用过程中的辨识度,毕竟你可能会创建大量的对象。比如很多人喜欢用前缀或后缀来区分不同的资源类型,好比“obj_Ship”和“Ship_obj”之类。接下来你可以为对象选择一个用于显示的精灵,在精灵选项上点击鼠标左键会弹出一个素材选择器(Asset Explorer),里面会显示出资源树中所有的精灵组件:
当你选好指定给对象的精灵后,点击按钮就可以直接修改精灵各项属性,如果你没有事先准备给该对象实用的精灵,也可以点击图标来直接新建一个精灵并直接指定给这个对象。你还可以单击编辑图像的按钮来启动图像编辑器直接编辑精灵的图像内容。
碰撞蒙版(Collision Mask)
在精灵区域下方有一个按钮可以指定对象的碰撞蒙版。通常情况下对象的碰撞蒙版默认是与其精灵的保持一致的,但在一些特殊情况下,你可能希望设置一个不同的蒙版形状。比如说你做一个上下游戏时可能角色的精灵用了矩形碰撞蒙版,但是使用圆形的碰撞蒙版会更加平滑,这种情况下你可以单击“碰撞蒙版(Collision Mask)”然后选择一个新的精灵资源,此时这个对象的实例会表现为之前指定的精灵资源的造型,但是基于新设置的这个精灵资源的碰撞蒙版来检测碰撞事件。
属性(Properties)
这里涵盖了对象的四项基本属性
可见性(Visible)
这个属性代表了当游戏场景启动时,该实例是否可见,大多数情况下都是默认可见的,但有的时候也会用的不可见资源——比如,你可以用不可见的对象设置路径点来控制怪物的移动,或做一些计时操作。隐形的对象仍然可以正常执行各事件中的代码,如果设置了碰撞蒙版则也能正常与其他对象实例发生碰撞触发事件……你只是看不到它们,它们不尽兴任何绘制的操作。默认情况下这个选项是选中的。
固体(Solid)
当你勾选了固体的选项后,就意味着这个对象会在触发碰撞事件之前就完成碰撞行为。这其实是个很简单功能,它所做的只是在实例发生碰撞事件的瞬间,在执行任何碰撞事件中的代码之前就把它放回碰撞发生前所处的位置上,因此需要谨慎使用。
持久化(Persistent)
持久化——一个持久化的对象是不会随着游戏场景的变化而消失的,它会一直存在并跟着跳转到新的游戏场景中。如果你不明确的销毁或通过代码要求它执行销毁操作,它永远不会消失。这意味着一旦在场景中使用一个持久化对象,它就可以贯穿全程在游戏中进行使用,而且持续执行属性中各类事件里的代码,“创建(Create)”事件除外,因为这个事件只有当对象实例首次生成时才触发,变换游戏场景并不会处罚这个事件。
使用物理特性(Uses Physics)
当你勾选“使用物理特性(Uses Physics)的选项时,GameMaker Studio 2 就会使这个对象具备物理特性。勾选这个选项后会打开一个新的窗口,在该窗口中你可以定义该对象的物理属性,其生成的实例都会继承这些属性。关于这块的内容在后文中“物理特性”一节会详细说明。
选项(Option)
选项部分可以定义对象的各项属性,以及游戏场景内生成的实例的行为方式。在这里你可以添加事件——即游戏代码的“构建模块”,设置对象是否具有父类,如果需要制作带物理属性的游戏也可以在此进行配置。
事件(Event)
那么事件到底是什么?基本而言,就是在游戏过程中,你通过代码实现的触发某些操作的触发条件。在GameMaker Studio 2中,从一个游戏场景开始到结束,会不停循环监测游戏步骤进程(步骤进程是一个单位的游戏时间,单位属性可在游戏场景的速度设置中控制)来判断是否有事件被触发,然后你就可以把你的代码或拖拽代码块(DnD Action)放到这些事件中运行,让我们用一个包含事件和代码的例子来说明以上内容:
你在我们的示例中可以看到列表中有很多响应事件,但当你首次创建对象时这个列表是空白的,你必须清楚自己需要哪些事件,以及这些事件被触发时实例该作出怎样的反应。要往这列表中添加事件,你需要点击事件列表底部的”添加事件(Add Event)“按钮,会弹出下面这个窗口:
这是一个对象可以响应的基础事件列表,其中有一些事件还有更细化的子事件,比如你选择按键事件后可以进一步选择具体响应哪一个按键。一旦选择了响应事件,会在右侧创建出一个代码窗口,你可以在此编辑代码,给对象赋予针对该事件所需要作出的响应操作。在任何事件上单击鼠标右键都可以看到以下选项:
- 添加事件(Add Event)——从事件列表添加新事件
- 剪切/复制/粘贴事件(Cut/Copy/Paste Event)——剪切、复制(到粘贴板)或者粘贴所选事件,可以使用标准的快捷键:Ctrl + X ,Ctrl + C ,Ctrl + V
- 复刻事件(Duplicate Event)——复制所选事件内所有的内容并直接塞进你指定的新事件中
- 更换事件(Change Event)——这会提示你重新选择一次触发事件,选择以后触发事件会被替换成新的事件
- 转换为拖放/代码模式(Change to Drag&Drop/GML)——把当前事件的编程模式在拖放模式或GML代码模式之间进行切换
删除事件(Delete Event)——删除当前事件,还可以用Shift和鼠标左键一次选择多个事件同时删除
你还要注意,你可以重新给事件命名,或至少写个备注,备注会在编辑器旁显示,备注方式如下,把这行内容写到编辑器第一行即可:
/// @description Your text here (这里写备注)
比如你可以这样命名一个计时事件:
/// @description This is the AI Fight alarm
然后你会看到事件编辑器里是这样显示的:
请注意,以上的事件只是简要描述了工作原理,所有可用事件的详细信息需要去对象事件列表详细查看。
父类(Parent)
在使用GameMaker Studio 2操作对象时,你可以设置父/子类的层级关系。点击对象编辑器中“父类(Parent)”按钮就可以打开以下窗口,其中可以选择其它对象并赋予层级关系
因此,在游戏项目中所有的对象都可以分配一个父对象,这有什么用呢?当一个对象拥有自己的父对象时,它可以共享父对象的所有代码、事件以及行为。这种共享称为“继承”,拥有父类的对象则称为“子对象(子类)”。子类不仅共享父类的代码,而且当你在父类上对代码进行查看和修改操作后子类将自动同步这些变化,这样可以节省大量的时间和精力。
如果觉得上面说的太复杂,你可以换一种理解方式,父类就是把一些拥有相同属性、特征的对象聚合起来,把这些共有的特性集中在一起,又不影响其独有的属性特征,如果还是不太理解,来看看下面这个例子…
如下图所示,假如你有一个“玩家”的对象和四种不同的“敌人”的对象。现在如果玩家对象与任何一个敌人对象发生接触时就会死亡,通常情况下你需要给玩家对象写四个不同的碰撞事件来处理跟四种不同的敌人的碰撞事件。但是如果我们给所有的敌人创建同一个父类对象,那么我们就可以给玩家对象与这个父对象写一个碰撞事件,那么当玩家对象与任意一个敌人对象发生接触时都会沿用父对象中的碰撞事件来触发玩家死亡事件。很方便对不对!
在左侧,我们做了四个单独的碰撞事件,而右侧我们只有一个,因为我们创建了“父类对象”,并且指定给了所有敌人对象为父类,要注意不用把所有的事件和代码都写到父对象里去。
我们再举一个例子,如果你要在一个游戏中创建10种不同样子的对象,但是这10种对象的行为操作以及事件完全一致。此时你可以先创建一个父对象,并在其中写入将所有行为操作相关的事件代码,然后分别创建10个对象并把父对象设置为这个对象,只需设置不同的精灵资源而不需要处理任何的事件代码就行了。当你把这些对象放到游戏场景中创建实例后,你会发现它们看似完全不同却又能执行完全相同的操作事件,因为他们都继承了父类的事件代码。
最后,你还可以混合使用该技巧。让我们用最后一个例子来说明这一点……比如说你想创建两个怪物,一个是上下移动的,另一个则是左右移动的,但你希望这两种怪物拥有完全相同的生命值以及在与玩家发生碰撞事件后能触发完全相同的伤害事件。在这种情况下你会发现两者大部分时间都是一致的,只有少数的一两个行动不同,此时我们可以把一个对象设置为另一个的父对象,同时我们也可以定义子对象的个别事件。这些事件会覆盖父类的相同事件代码,这代表当满足该事件触发条件时,会执行新的事件代码而不是父类中的相关操作。你也可以通过“inherited”函数来强制调用原父类中被覆盖的相关代码。
上图中左侧是一个写有5个事件的父对象,右侧则可以看到对应的子对象,这个子对象中只定义了2个事件,但是他会继承父类的事件,所以他其实拥有与之一致的5个相同的事件。区别在于,子对象中“步骤(Step)”和“绘制(Draw)”这两个事件将覆盖父类中对应的事件。
如图所示,不管你在何处使用父对象,同样会作用于其衍生的对象(子对象),无论你针对任何个特定的实例进行应用都会起效。当你在代码中使用“with()”语句时也会有相同效果,当你针对父对象调用诸如“instance_position”、“instance_number”等函数时,同时也会对其子对象生效。最后,这个功能对变量的修改也是有效的,比如上图的例子中,如果把第一个对象的速度设置为10,那第二个对象的速度也会变成10,因为它是前者的子对象。
在多数情况下,创建一个最基础的基类作为父类是个好习惯,在这个基类中写入所有默认的通用代码,但绝不要在游戏中用它创建实例。比如碰撞检测、引用变量等都可以写进父类而不用在子类中单独设置。你同时应该了解父类也可以拥有自己的父类。当然,绝不可能把A设置成既是B的父类又是B的子类这种循环结构,只能创建层级对象结构,比如A是B的父类,而B是C的父类这种。这种方式对于保持游戏结构十分有效,强烈建议大家学习并使用这种机制。
物理(Physics)
当你首次创建一个新的对象资源时,你会发现这里有一个“使用物理特性(Use Physics)”的选项默认是未勾选的。一旦选中这个选项将彻底改变这个对象实例在游戏场景中的行为,因为这个选项会开启对象的物理属性,这意味着传统的运动和碰撞方法已经全部失效(前提是当前场景也开启了物理属性)。当你选中该选项后,会出现以下物理编辑器窗口:
在开始编辑对象各物理属性值之前,最后首先设置好对象的碰撞形状(Collision Shape)。在普通的碰撞系统中,碰撞事件是基于定义给对象的精灵的碰撞蒙版的,而开启了物理特性以后就不再如此了。我们需要自己重新给对象定义一个“碰撞形状”(我们称这个属性为“装置”),这个形状可以是一个圆形也可以是矩形,或是你自定义的一个多边形,单击修改碰撞形状(Modify Collision Shape)按钮就可以打开下面这个窗口
这看起来很像是路径编辑器,并且功能也大致相同,但是基于你所设定的蒙版不同,也会有如下一些限制:
- 如果你设定了一个圆形蒙版,则只能拉动路径点来放大或缩小这个圆
- 如果你设定的是矩形蒙版,则可以移动四个较重的任意一个,但整个其它三个点会自动调整位置以确保矩形造型不变
- 如果你自定义了一个多边形蒙版,这个蒙版至少需要3个点,至多只能有8个点,并且所有的角必须是向外凸起的(参见下图右侧为错误示例)
一旦你设置好碰撞形状,你就可以通过修改以下的参数来定义你的对象的基本物理属性了:
密度(Density)
密度是指物体单位体积的质量,这可以用于表示该物体在世界中所占据的空间以及质量的多寡。因此气球的密度很小,因为它质量很小却占据了很大的空间,而铅棒的密度很大,因为其质量大而占据空间小。在GameMaker Studio 2的物理世界中,会根据你输入的密度以及形状的面积大小来自动计算质量。这会直接影响对象的惯性以及碰撞后发生的力反馈,因此如果你创建一个很小的对象却赋予很高的密度,就会产生质量(比如铅棒),但如果你定义了一个很大的形状却密度很小,其质量就会很小(比如气球)
弹性(Restitution)
在物理世界中,弹性指的是“物体或系统在经过弹性形变后恢复到原始状态”,而在GameMaker Studio 2中的刚体(rigid bodies)是无法发生形变的,因此实际上弹性指的是刚体到底有多“弹”。这个设置会影响对象与其它对象发生碰撞时“弹跳”的次数及力度,同时会与重力和摩擦力一起作用于实例之上共同起效。
碰撞组(Collision Group)
默认情况下,所有物理对象的碰撞组都是0,这意味着这些对象都能正常进行交互操作,但也表示必须在发生碰撞事件的情况下才能发生交互,否则。但是你也可以制定对象属于某个特定的“碰撞组”。当你给对象指定碰撞组后(比如把三个对象都放进“2”号组),GameMaker Studio 2会把这些对象生成的实例都定义为持续触发碰撞事件,即便这些对象的碰撞事件里是空白的,它们也会遵循它们所处的游戏场景的物理属性。反之,当你给你的对象设定了负数的碰撞组(比如给四个对象分配到“-1”组),就是在告诉GameMaker Studio 2 这些对象永远不会发生碰撞事件,它们之间的所有碰撞事件都会被忽略。
注意:使用碰撞组功能会明显提升物理系统对性能的消耗,只有在绝对必需的情况下才该是用这个功能,并且应当用尽少的组来完成。
线性阻尼(Linear Damping)
阻尼可以降低对象实例的速度,并且不同于摩擦力,因为摩擦力只有在两个实例接触时才起效。而且阻尼比摩擦更容易实现,但要注意的是阻尼并不是摩擦力的替代品,这两个效果可以也应该一并使用。
角阻尼(Angular Damping)
如果你在现实世界中旋转任何物体时,除非有电机或在真空环境中,否则都会随着外力(比如与周围空气的摩擦力)的影响而逐渐变慢。我们可以用这个选项来模拟这种效果,降低实例的旋转速度,如果不设置这个值,所有旋转的实例都会永远旋转下去。
摩擦力(Friction)
摩擦力是不同材料元素之间抵抗相对滑动的力,而在GameMaker Studio 2的物理世界中,则是指两个实例相碰撞以后造成的动量损失。因此当两个实例碰撞时,受摩擦力影响,这个值越大损失的栋梁也越大。最后,这里还有三个额外的开关选项可以用来作用于你的对象,分别是:感应器,启动唤醒和动态化,这些功能的作用如下:
感应器(Sensor)
选中该项以后,GameMaker Studio 2会“忽略”对象的物理属性,但仍可正常返回与周围其它对象的碰撞事件。通过这种方式,你可以在一个场景内创建一个不带有物理属性的实例,但使其仍然可以与其它实例触发碰撞效果,比如使玩家去开一扇门,或是与场景内其它对象进行交互产生行为。
要注意当两个对象初次接触触发碰撞事件以后感应就会自动关闭,这意味着这两个对象后续的重合不会触发碰撞事件中的事件。如果他们在接触后停止了重合行为,之后又重新接触重合会另外单独触发一次碰撞事件。
启动唤醒(Start Awake)
在默认情况下这个选项是选中的,这意味着对象所生成的实例在场景内初始化状态就是唤醒状态。通常情况你会愿意让对象在游戏一启动就处于唤醒状态(即立刻能被场景内的物理特性所影响),但有时候由于一些特殊的需求这可能并不是你所需要的效果。为此,你可以取消这个选框然后直接创建未唤醒的实例,直到你设置的事件触发唤醒它以后,才会受整个场景内的物理特性作用影响。
动态化(Kinematic)
在物理类游戏中,偶尔有一些对象实例你不希望它受重力或其它动态对象的碰撞所影响(平如横版动作游戏中的那些浮在空中的平台)。对于这类对象,如果直接把密度设置为0只意味着这个对象在物理模型中是静态的,但是它也会变的无法与其它对象产生交互作用。但只要针对静态对象选中了这个选项,即便它不会受碰撞或重力的影响,也可以通过变量来使其运动或旋转起来。
GameMaker Studio 2 中的字体编辑器
字体编辑器(Font Editor)
当你想在游戏中绘制文本内容时,默认会以12号的Arial字体进行绘制,但是你可能希望使用不同的字体来制作出更有趣或独特的文字内容。为此你需要利用你电脑中的字体来创建在GameMaker Studio 2中可以使用的字体资源。你可以在资源树的“字体(Fonts)”文件夹上单击右键,然后单击“创建(Create)”来完成该操作。每一个你创建的特殊类型的字体,都可以在后续游戏开发过程中进行使用。
首次创建字体资源时,将会打开字体编辑器窗口,其中有以下几项内容:
字体详情(Detail)
在这里你可以给你的字体设置一个唯一的名称(仅可使用字母和数字以及下划线“_”号)。字体必须是具有使用许可并已经安装在你的电脑中的,GameMaker Studio 2在默认情况下是不会在项目中存储字体文件的,而是将字体以纹理页的形式来预渲染字形。如果你想把字体文件(仅限TTF格式)打包到GMX/GMZ包中进行发布,你必须勾选“编译时包含字体(Include Font In Build)”选项。这个操作会打开一个文件管理器,你可以在其中选中字体文件,然后将其添加到游戏文件中,当对游戏进行编译时这些文件会直接用来生成字形而不是纹理页。
重要提示:你在游戏中只能使用法律上具备许可的字体文件。
字形(Presets)
在这里你可以设置字体尺寸(默认12号)以及是否使用粗体、斜体或开启抗锯齿(边缘平滑)功能。在右侧的预览窗口会根据你的修改操作实时做出响应。在此处你可以选择将字体添加到哪个纹理组进行管理,当游戏进行编译时这个字体将会先被添加到临时纹理中以创建一个包含所有字形的图像,然后将其添加到主纹理组中进行导出。要注意,如果你勾选了将字体文件直接打包的选项,此处的选项将无法操作。
纹理组(Texture Group)
如上文所述(字体详情部分),默认状态下所有的字体将以纹理组的一部分直接显示在纹理页面内,以转换为可用的图形资源。
范围(Ranges)
当创建字体资源时,极少数情况你会想要为某几个文字单独导入字体。因此GameMaker Studio 2默认仅使用所选字体的32到127之间的字符,因为这其中包含了所有的数字、大小写字母以及大部分标点符号的字形。但是,你也可以修改这个选取范围来优化你的游戏,比如:你只需要某个特定字体中几个特定的数字,则可以选择只要数字部分的字体。为此,你首先要单击“删除”按钮来清除当前的范围(你可能需要在预览窗口中单击鼠标左键来选择范围)然后单击“添加”按钮来定义新的字形范围,这个操作会打开下面这个窗口:
这个窗口中有几个按钮可以协助你建立标准范围:
- Normal:普通范围是32到127
- ASCII:范围是从0到255
- Digits:该范围仅包含10个阿拉伯数字
- Letters:仅包含所有大小写英文字母
你还可以通过输入起始和结尾的字符索引值来定义字形适用范围(如果某个字符不在这个范围内,就会显示为一个空格)。除了这些按钮和输入框,你还有两个选项十分重要:
- 从代码中创建:如果你点了这个按钮然后选择了“OK”进行确认,GameMaker Studio 2就会自动解析游戏代码中所使用的字符串,然后创建足以覆盖游戏中使用文字的范围。需要注意的是,这个操作只会查找所有字符串(在“”或‘’内的文字)内容,因此也有可能包含一些文件名。
- 从文件中创建:这个操作十分类似上面“从代码中创建”的功能。一旦你点击该按钮,你会被要求提供一个文件,如果你选择了一个文件然后点击“OK”。GameMaker Studio 2会自动解析这个文件,然后创建足以覆盖这个文件内文本内容的字形范围。
要注意的是你也可以添加或删除预览窗口中的字形内容来手动编辑文本范围。
预览(Preview)
在预览窗口中你可以输入任何文本进行测试,此处将会以你选择的范围作为预设值来进行字形渲染。
范围预览(Range Preview)
这里可以预览你添加的范围的字体内容,左侧显示范围值,右侧是范围内的字形预览。
[ 分享 ] GameMaker Studio 2的精灵编辑器
精灵编辑器是用于配置你所创建的精灵资源属性的地方,你可以在新建精灵时打开本窗口(在精灵资源文件夹上点击鼠标右键然后选择“创建(Create)”即可),在已经创建好的的精灵上双击鼠标左键或单击鼠标右键选择“属性”也能看到这个界面。整个界面构成如下:
精灵名称(Sprite Name)
你可以在此给精灵命名,这个名字是你在整个游戏工程中调用这个精灵的唯一标识,名称中只能包含字母及数字以及下划线符号“_”,同时需要注意的是尽管名称里允许使用数字,但绝不能以数字开头,这可能会导致在撰写GML或DnD脚本时精灵失效。
图像(Image)
在这个区域你可以点击按键以进入设置图像尺寸的界面,如下图所示:
在这个界面你可以看到修改前后的预览图像,下方还有两块用于设置图像属性的区域:
缩放图片:在这里你可以你可以调整精灵画布以及所有绘制在画布之上的内容尺寸。你可以选择锁定长宽比来进行缩放,也可以设置以像素或百分比为单位进行调整。你还可以根据你的图像类型来选择是否开启线性过度来对图片缩放进行调整(通常开启线性过度会使得像素边缘更加“平滑”,因此在一些像素风格的游戏中最好关闭此选项)。
缩放画布:这个选项仅仅调整画布的大小,而不会对上面的绘图内容造成任何变化。你可以通过选择方向箭头来设定不同的“锚点”并设置尺寸。在下方还有锁定长宽比进行缩放的选项,底部则是设定以像素或百分比为单位进行调整的选项。
当你设定好你所需要的尺寸后,你可以点击“接受(Apply)”来确认本次修改操作并关闭当前窗口。
注意:本操作仅对位图精灵有效,而对于“矢量图(SWF)”格式及“骨骼动画(Skeleton animation )”精灵是灰色无效状态的
在这里你还能直接打开图像编辑器来直接绘制你的精灵,或者你可以点击”导入(Import)“按钮来导入现成的图片来创建精灵。常见的位图格式都可以使用(PNG、JPG、GIF等等),同时Gamemaker Studio 2还支持矢量图精灵(SWF)以及骨骼动画(Spine)。想了解更多信息可以查阅导入非位图精灵的内容。注意当导入位图精灵时你可以一次选择多个图片文件,每一个突破文件都会作为子项被添加到同一个精灵之中即一图一帧。
纹理设定(Texture Settings)
这个功能用于管理和使用GameMaker Studio 2中”纹理页“中存储的图像资源,这个功能通常对于桌面平台并不十分重要,但是如果你打算开发手机或网页游戏项目时就显得十分有必要,因为一旦不能正确使用纹理特性可能会对游戏造成不良影响,甚至影响游戏性能。
”瓷片:横向(Tile:Horizontal)“和”瓷片:纵向(Tile:Vertical)“这两个复选框通常是默认关闭的,因为大多数时候你是用不着瓷片精灵的。但是,在某些特定的情况下,你可以考虑把精灵变成瓷片类型,这种时候你就要把这两个选项勾上,尤其是在某些时候你打算缩放场景尺寸,但是纹理贴图无法正确显示的时候。
如果你的精灵将被用来作为纹理贴图时,你应该把”分离纹理页(Separate Texture Page)“选项也勾上,这样(注意,每个子图像也都将拥有自己的纹理页面,所以如果你的精灵有10帧画面,你最后会生成10个纹理页面)。这会大大增加你的游戏对内存的消耗,因此无比谨慎使用这个功能。另外还要注意,如果你用这个功能来实现3D功能,纹理数量应当是2的冥数级(如128*128,256*256,512*515等)。
最后,你也可以选择纹理组来管理你的纹理资源。基本上,一个纹理组(首先要在纹理组管理器中定义)可以用来统一管理和存储你某个特定游戏场景或关卡中所需的相关图像资源。比如,你可以把第一关所有的图像放进一个纹理组,然后把第二关所有的图像放进另一个纹理组,以此类推……而GameMaker Studio 2会把这些分过组的资源都放在同一个纹理页上,这样可以减少游戏在目标平台上运行时对纹理页进行缓存的需求。
提示:这种做法并非总是必须的,这个方法对于性能的提升取决于目标设备的CPU及GPU的性能限制。
碰撞蒙版(Collison Mask)
所有的精灵都有一个”碰撞蒙版(Collision Mask)“来指示这个精灵的可碰撞区域范围,这个区域在生成实例后将被用来检测碰撞事件。
首先你可以了解一下自带的几种碰撞蒙版模式
自动模式:GameMaker Studio 2会自动以精灵透明度为基准来计算碰撞蒙版(取决于下面将提到的“公差(Tolerance)”设置)。
全图模式:这个模式会自动计算精灵图片的上下左右边界,然后设置对应的碰撞蒙版
手动模式:选择这个模式后,你可以手动设置碰撞蒙版的上下左右的边界值。
除了上述的三种模式以外,你还可以从下拉选项菜单中指定不同的蒙版类型
矩形蒙版:一个简单的矩形碰撞蒙版,效率最高速度最快。
圆形蒙版:创建一个圆形蒙版,计算量稍大会慢一些。
菱形蒙版:创建一个菱形的碰撞蒙版,计算量更大,对CPU的消耗也更多。
精确蒙版:这种类型会严格贴合精灵图像的边框生成碰撞蒙版,如果精灵有多帧不同形状的图像,碰撞蒙版会沿着复合边界生成确保覆盖每一帧画面。这种生成方式非常慢并且会消耗大量的CPU资源。
帧蒙版:这种蒙版会针对每一帧不同的图像单独计算边界并且精确匹配生成蒙版,这是目前最慢的蒙版方案,除非万不得已应当尽量避免使用这种机制。
下面这几张图能大致说明这几种不同蒙版类型的样子
碰撞检测是游戏中非常重要的一个环节,常被直接用于处理游戏中不同对象的相互作用和联系,如果处理不得当可能会影响整个游戏表现。为何如此?设想一下,当两个带有碰撞蒙版的实例相遇时,一旦出现相互叠加的蒙版区域时就会触发碰撞事件,而每个实例的蒙版类型各不相同,可能精确,也可能基于图形本身,下面是不同的蒙版相遇碰撞的几个简单示例:
在下方有一个控制xxx的滑动条,这个可以根据精灵像素的透明度用来调节蒙版的边界容差——这个值越高则会将越多较透明的像素放置到蒙版之外,这些在蒙版之外的像素将不会用于检测碰撞事件,值越低则相反。这个设置同样会作用于包裹体(没有设置为手动模式时)以及精确蒙版模式。
最后你可以针对蒙版设置包裹体(Bounding Box)的尺寸。包裹体即恰好能容纳精灵蒙版的矩形区域。只有在包裹体内的像素会被用来处理碰撞蒙版以及处理碰撞事件的检测,这个值默认是自动计算的。如果你开启了精确蒙版模式,这个包裹体也会针对每一帧图像单独进行计算。如果你打算自己设置包裹体的尺寸,你可以直接在上下左右的数值框中输入对应的数字,或直接在精灵视图上按住鼠标左键拖放来直接“画”出包裹体的范围。要注意当你在“画”包裹体时,蒙版将根据最终的值自动生成。
值得注意的是当你查看预览窗口时,你可以通过拖拽蒙版四个角的位置来调节蒙版尺寸,效果与输入包裹体的数值相同。
原点/缩放(Origin/Zoom)
在预览窗口上方有一条属性栏目,该处包含了精灵的原点属性设置以及缩放控制。在这里你可以看到精灵的长宽属性,以及一个”原点“的设置项。这个点代表了它在游戏场景中所处的位置,当你在场景中设定在某个指定的X/Y坐标生成这个精灵的实例时,这个原点将严格对应该坐标。默认的原点位置位于精灵的左上角,但大多数情况下你会考虑把精灵的中央位置或其它位置设置成原点,这样更方便操作,只要用鼠标左键单击原点的下拉选项菜单,然后选择不同的预设值即可进行修改。你也可以在精灵的预览图像上任意位置点击鼠标左键来自定义原点的位置,或在X/Y坐标的输入框中输入你想要的位置坐标。
值得注意的一点是,你甚至可以把原点设置在精灵的显示范围之外,你可以在坐标中输入负数或大于精灵尺寸的正整数,这种方式在处理某些特殊的精灵时会很有效。
在右上方的缩放操作则可以缩放预览图像的显示尺寸,中间的图标可以将预览图直接缩放至1:1的尺寸进行展示。
预览(Preview)
预览窗口可以查看这个精灵在游戏中将会呈现的样子,你可以使用鼠标滚轮来进行缩放查看,也可以按住滚轮中键或同时按住”空格键“和鼠标左键来拖放预览区域。你可以通过下文的”帧控制“中的方法来改变预览图的显示。
帧(Frame)
这个区域。你可以在任何一帧上按住鼠标左键并向左或向右进行拖拽来改变帧序列的顺序,同时你也可以在任何一帧画面上双击鼠标左键来启动图像编辑器来进行编辑修改操作。选中的帧画面的右上角有一个”x“图标,点击可以删除该帧。你也可以按住Ctrl键然后用鼠标复选多个帧,此时点击删除图标会把所有选中的帧都删掉。
帧控制(Frame Controls)
帧控制区域主要用来控制和回放预览窗口中的帧动画,点击”播放“按钮可以控制动画的播放以及暂停,点击循环按钮可以切换精灵动画的不同播放模式。
循环模式:当动画播放到最后一帧后从第一帧开始重新播放如此循环
乒乓模式:当动画播放到最后一帧后反向播放至第一帧如此循环播放
同时你还可以在输入框中设置动画播放的速度,帧动画的速度可以基于”每秒播放的帧数“或”每一帧游戏播放的动画帧数“两种单位进行设置,在右侧还会显示当前播放的是哪一帧画面的序号,你也可以按住Ctrl再用鼠标左键同时选择多个帧来进行操作。
Reddit的GMS每月挑战——五月期
最近开始准备着手学习GMS,今天刚好在Reddit的GM版块看到了置顶帖有个每月挑战,针对不同水准的人都布置了不同难度的开发任务,发过来让有兴趣的朋友一起参与下:)
Monthly Challenge 25 - May 2017
——————————翻译分割线——————————
各位游戏开发者大家好,欢迎参加第二十五届月度挑战!这个月度挑战是个小而有趣的活动,试图让参与者通过完成一些既定的主题任务来磨练和运用参与者的开发技巧和知识。
经常会有一些用户来咨询如何控制一大堆相同种类的游戏对象。他们有的想要在运行时能生成大量的对象,或者想让某一类对象都发生某种特殊的变化。本月的挑战任务就是关于如何处理这种多个对象的状况。
你可以通过以下方式来参与这次挑战:
- 在你正在做的游戏里实现这个功能
- 做一个小的Demo演示
- 把相关的代码直接发出来
- 任何方式,你喜欢就好!
Complete any of these challenges by posting in this thread! Share your unique ways of accomplishing each task!
难度 | 标题 | 描述 |
---|---|---|
初学者 | 多多益善 | 游戏开始后,让用户进行一些操作然后在场景内创建10个相同种类的对象(比如按下空格键生成10个史莱姆) |
进阶试炼 | 独一无二 | 让每个对象在生成时都带有不同的特征 (比如让每个史莱姆都变成不同的颜色或者有不同的动作) |
高阶挑战 | 天选之人 | 在对象都创建完成后,让用户进行一些其他输入操作,然后作用于其中一部分对象并触发效果( 比如按下“回车键”立刻消灭最大的4只史莱姆) |
小提示: 可以使用 for 循环来一次性生产多个对象。记住可以用 instance_create() 和 instance_create_depth() 返回刚生成的实例的ID。用 'with' 声明你想要的对象类型。