暂停是一个游戏的基本,有一个好的暂停系统可以让玩家上厕所的效率更高,这次就来谈谈使用GM做游戏如何来做游戏暂停。
使用show_message函数
使用对话框可以让游戏马上卡顿,只要一行代码就可以完成暂停的功能
show_message("pause");
效果就是下面这样了:
这样只要当玩家点击ok按钮之后就会解除暂停,该方法的缺陷是大大的,比如看上去逼格一点都不高啊。然后也非常简陋啊。暂停之后就不能干其他的事情了啥的。。
使用keyboard_wait函数
使用keyboard_wait函数可以达到游戏暂停的效果,原理是让游戏休眠,等待用户的键盘输入后再继续运行。
这个方法在官方的GML教程中在一个不起眼的位置提到过。
这三行代码的意思就是用户触发暂停后,绘制一行文字告诉用户现在是暂停阶段,然后为了显示这行字强制屏幕刷新一次,之后等待用户的键盘输入。
方法非常的简单,但是缺陷也有很多,比如说,用户可以按任意按键解除游戏暂停,这样就不能实现做出暂停选单的效果了。
使用解散游戏实例的方法
GM提供了一套解散实例的暂停方式,当用户需要暂停的时候,可以使用函数instance_deactivate_all来解散房间内的所有实例,取消暂停时再用instance_activate_all来激活所有的实例,达到暂停的目的:
新建一个专门用于管理暂停的物体,名字为obj_pause,当用户暂停的时候创建出这个物体的实例,并且可以按空格键解除暂停。
如下就是obj_pause物体中各个事件的代码:
创建事件:
screenSpr = sprite_create_from_screen(0,0,640,480,false,false,false,true,0,0); //截屏用于在暂停的时候显示游戏画面
instance_deactivate_all(true); //解散所有实例,但是不解散obj_pause物体,可以在该物体中写下一些在暂停时运行的代码
绘制事件:
if(sprite_exists(screenSpr)) {
draw_sprite(screenSpr,0,0,0); //绘制截屏的精灵
}
draw_text(30,30,"pause"); //绘制一个文本提示玩家现在正在暂停阶段
<空格>键按下事件:
instance_destroy(); //销毁当前物体解除游戏暂停
销毁事件:
instance_activate_all(); //激活所有物体解除暂停
sprite_delete(screenSpr); //删除截屏时创建的精灵释放内存
这样子就可以保证游戏中的物体暂停后也有一个物体是激活状态的,可以在这个物体里写下一些代码来完成你的暂停时菜单,或者在暂停的时候让用户输入秘籍来提升火力等等功能。缺点就是使用解散实例后他们将不再执行绘制事件,这也就表示他们将不会继续显示在屏幕上,在解散所有实例之前截图就是为了这个,当然,如果你想做一个类似玛丽医生那样的暂停,在游戏暂停后屏幕一片漆黑,只显示pause几个字符,使用这种方法再适合不过了!
运用变量控制物体执行并行事件
这个方法是最麻烦的,但是也是效果最好的一个方法。他可以不使用截屏功能让物体能继续显示在屏幕上,实现暂停的效果。
利用该暂停方案的源码,可以在GM论坛上找到实例源码:
http://www.52gmk.com/thread-82.html
笑死 这论坛都没了
这个方法的思路就是,在暂停阶段,把GM内置的所有关于速度的或影响物体的变量全部设置为0,比如speed,hspeed,image_speed,以及时间轴速度,路径速度等。暂时将他们储存在成员变量内,解除暂停后再恢复,同时让该物体的鼠标,键盘,步事件全部失效,让所有计时器不再进行递减,就达到了暂停的目的。
参考上面给出的实例,可以大致了解一下该暂停方案的实现思路。大家可以下载看一下,源下载地址是yoyogames的东西,下载速度可能慢,或者说不定哪天就挂了,我就分流一个吧:
傲娇玉米下载点 [点击下载]
例子里面的obj_controller物体就是核心物体,里面的代码就是所有有关于暂停的东西,当然,并不是你在游戏中加上这个物体就能达成暂停了,因为要保证暂停的时候不执行并行事件,还需要再每个物体的并行事件中进行判断。
利用该方法可以达成最好的暂停效果,坏处就是要在所有的物体中把并行事件,键盘事件,鼠标事件的第一行代码都加上判断,如果游戏正在暂停,就用exit强行跳出代码。这样也增加了很多的工作量。大家可以使用父对象然后让游戏物体继承这个对象,并将所有的并行事件改为一些自定义的事件,然后在这个父对象中来判断游戏是否暂停,从而来决定是否执行这些自定义事件。