大家好,这是官方的教程的最后一部分内容,Heartbeast大大的视频我还在看,过阵子慢慢来:)
本节教程视频教程地址:【中文教程】GameMaker Studio 2官方教程8/8——随机生成敌人
————————————————————————————————————————
今天要学习的是如何随机生成敌人,在之前的学习过程中我们都是直接在场景编辑器中添加了几个敌人用来测试游戏的,但是那样有一些问题,比如你放几个敌人就是几个,打完了就没了,那游戏也就无法继续了,不同的玩家之间也缺乏了一个比较的依据,因此我们希望游戏能随着时间不断自动生成敌人,并且敌人的位置是完全随机的,那么我就开始今天的课程。
首先我们在场景编辑器中给敌人单独创建一个实例图层并取名为“EnemyLayer”,然后要记得我们需要调整一下顺序确保飞船所处的图层一直在最上方:
在敌人的图层创建好以后,我们要再创建一个对象,这个对象是用来作为敌人生成器的:
这个对象我们同样采用敌人的精灵作为贴图,但是稍微不同的是,我们需要在创建的时候把这个图设置的很小,如图所示,我们创建了一个Create事件,并在这个事件中写了两行代码:
image_xscale = 0.1 ;
image_yscale = 0.1 ;
这两个属性也是GMS2自带的属性,分别是图像高宽的缩放比例,我们在这里把高宽的缩放都设置为0.1即代表高宽都只有原图的1/10大小,这样就代表这个对象在生成实例时会显示的很小,整体面积只有原图的1/100。我们这个生成器就是希望让敌人有一种慢慢变大最后完全生成的感觉,因此我们还需要写一个方法来使得图像逐渐变大,这里我们应该还能记得在上一课曾经用过一个方法去使得图像的透明度逐渐增加,我们这里用类似的方法即可达到目的,首先我们需要创建一个step事件:
其中我们写了这些内容:
image_xscale = min(image_xscale+0.02,1)
image_yscale = image_xscale ;
if (image_xscale = 1) instance_change(obj_enemy,true);
第一行就跟我们上节课中逐渐增加图片透明图的方法几乎一样,只是这次我们修改的不是图片的透明度,而是图片的宽度的缩放比,同样用min这个方法来反复获得最小值,直至前面image_xscale的值大于1以后就永远被赋值为1即原图大小,第二行我们没有重复这个步骤是因为我们希望图像的高度缩放比跟宽度缩放比完全同步,因此直接将二者相等关联起来即可。
但是这个逐渐变大的图像是敌人生成器,而敌人生成器中没有任何行为逻辑代码,是不能像敌人一样来追赶玩家控制的飞船的,也不可能对玩家射出的子弹和玩家的飞船进行交互和碰撞,那么我们希望的就是这个生成器能变成一个敌人的实例,这里就用到了GMS2的另一个自带的方法instance_change,如上图最后一行。
在最后我们写的那一行意思是,当图像的缩放比与原图完全一致以后,将当前的实例替换为敌人对象的实例,由于我们生成器所使用的图像与敌人的图像完全一致,因此当生成器的图像尺寸达到原图尺寸以后,这个即时的替换是玩家无法察觉的,玩家只会看到一个敌人由小变大然后到达正常尺寸以后就会完全按照敌人的行为逻辑来追赶他控制的飞船,并不会知道前面逐渐变大的那个图像跟后面来追逐他的敌人其实是两个完全不同的实例。
为了测试这个生成器能不能正常工作,我们要去场景编辑器中,将几个生成器的实例放进场景进行测试,这里一定要注意,我们要放进场景的是今天创建的生成器的实例,而非敌人对象本身。
当运行游戏测试通过以后,我们要注意,现在虽然敌人有了一个生成的过程,但是这些敌人依然是我们在场景编辑器中提前放进去的,这些敌人的位置永远在那几个地方,数量也是恒定不变的,这还没有达到我们最初的要求——让敌人随着时间的推移不断增加。
于是我们又需要再创建一个新的对象,这个对象是不可见的,其作用就是在玩家看不到的地方默默地在场景中制造敌人(生成器)。
这个对象的名称可以根据自己的喜好进行定义,当然最好跟之前的命名规则保持一致,然后我们需要一个Create事件来初始化一些属性:
如图,我们初始化了一个自定义的变量,还用到了GMS2自带的倒计时方法alarm:
spawnrate = 60 ;
alarm[0] = spawnrate ;
这里我们首先自定义了一个spawnrate的变量,这是我们希望用来控制敌人生成时间间隔的一个属性,然后我们把这个变量的值定义给了一个alarm[0],这是GMS2自带的倒计时方法,在添加事件的列表中我们可以看到有专门一个alarm的事件列表:
这意味着,当我们定义的某个倒计时数字等于0时,就会触发对应事件中的代码,而我们之前定义了alarm[0],因此我们直接再添加一个对应的alarm[0]的事件:
我们在这个事件中定义了在游戏场景中随机的位置生成一个新的敌人生成器的实例:
instance_create_layer(random(room_width),random(room_height),"EnemyLayer",obj_enemyspawn)
alarm[0] = spawnrate ;
这上面一句翻译一下就是:
在后面参数所指定图层中指定的位置创建一个指定的实例(随机取一个小于等于后面参数并大于0的值(场景的宽度),随机取一个小于等于后面参数并大于0的值(场景的高度),敌人图层,敌人生成器对象)
alarm[0]的值重新定义为spawnrate的值
第一句就是在场景内随机获取一个x、y坐标,然后在敌人图层的这个位置生成一个敌人生成器对象,而经过我们之前的实验我们知道,生成器对象将会在游戏中自动变成真正的敌人对象。
然后最后我们要记得给alarm[0]重新赋值,因为这一串代码是当alarm[0]倒计时等于0以后触发的,如果我们不重新设定一个值,那这个倒计时永远等于0,那就不会再次被触发,因此需要重新赋值,确保这个倒计时能反复被触发,那敌人也就会源源不断的生成了。
当完成以上内容以后,可以再次打开游戏进行测试,这时候你就可以挑战一下自己到底能得到多少分了,也可以借此跟朋友们一较高下:)
在完成这系列翻译的周末B站又有人给我充了一次电,感激且有一些惶恐,我希望这些东西能帮到更多人,能有那么一些价值,希望大家能更多跟我互动(比如更喜欢什么方向的内容,或是有什么建议之类),给我更多动力,感激不尽~
请教一下大大:1.游戏该怎么插入背景音乐呢!希望能详细讲一下
最近由 piluo 修改于:2017-08-26 22:57:342.room放上敌人以后 该怎么删除呢
3.如何不让敌人生成在玩家身上
4.我看到官方的素材包里有敌人被打爆死掉的帧数图片,怎么让敌人hp=0的时候有死掉的动画呢
@piluo:
1、有一节讲了音效么不是,用同样的方法播放一段音乐就可以了啊,在某个常驻的对象里写个持续循环播放背景音乐的代码
2、我不知道你的删除是什么意思,在场景编辑器里的话选中直接delete就可以删除了,在游戏中的话触发事件然后用instance_destroy()就可以
3、你可以在生成敌人的代码里判断一下生成坐标与玩家的当前坐标来比对一下
4、把死掉的动画放进一个单独的精灵里创建一个新的精灵(类似敌人生成器那种),然后在敌人hp=0时先destroy掉实例本身,然后同时生产一个这个死掉动画对应的精灵指定正常播放动画(只播放一遍不要循环)并且播完就destroy掉自己
@顺子:非常感谢回答!(音乐的话是因为给room添加音乐切换场景的时候有时候会重叠,所以有些头疼。)抱歉没有把问题说清楚哈
最近由 piluo 修改于:2017-08-27 19:19:05@piluo:是怕切换场景的时候音乐停止播放之类?这个可以用对象的持久化属性来实现,如果是这个问题我可以写个教程
最近由 顺子 修改于:2017-08-28 01:13:54@顺子:反而是切换场景的时候上一个音乐和下个场景的音乐重叠了。如果能写教程的话就大感谢了
辛苦了,感谢楼主的翻译!简直就是拯救初学者的救星,多亏了楼主的翻译教程让我对GMS2有了深入的了解,少走很多弯路。楼主加油!希望以后能翻译一些关于背包系统的教程
@ABC123:好像看到一套讲背包的,回头我先看看难不难……
请问楼主怎样设置地图边界呢?就是限定我们的猪脚不会跑出边界
@ikonon:简单一点就是在整个room周围围一圈墙,然后给玩家设置碰撞事件,遇到墙就不能继续前进,这个可以去看一下heartbeast那套2D设计教程,最开始就介绍了这种墙的碰撞制作方法
@顺子:谢谢!