作为游戏策划,最梦想的可能就是做一款完全自己设计的游戏,这也是独立游戏的魅力所在。现在市面很有很多游戏制作工具,construct2绝对是其中的佼佼者,它的拿手好戏就是“快”,上手快、开发快,“理论”上可以制作任何类型的2d游戏,支持导出html5也非常方便传播。 虽然用construct2制作大型商业游戏也是可以的,但在我看来它的最大价值就是可以实现游戏的”MVP”(minimum viable product,最小化可行产品),这个词在创业领域很流行,就是用最小的代价试验产品是否可行,得到验证之后再投入大量资源。如果有一个特别的游戏创意,可以先做一个小demo出来,小范围传播后看反响再进行一次次迭代,初期投入少,也可以慢慢积累种子用户,利用construct2的“快”的特性,可以胜任这个任务。 “不用写代码”我承认这个标题党了,其实construct2也是真的不需要你“写”代码,通过鼠标拖拽即可。但其游戏的内部逻辑,还是需要用代码的思维。construct2的好处就是,你不用特别额外时间去学习语法、记忆命令,即用即得,就像是搭积木一样,所有的积木已经摆在你面前了,需要的只是你去找到那一块合适的积木。如果你是程序员,估计更能用得更加得心应手。 说到做HTML5游戏,很多人第一个反应就是白鹭,而且大家打开软件一看,怎么界面这么像啊,其实呢……你就把construct2比作whatsapp,白鹭比作微信就懂了。 这次用的版本是Release 239(64-bit)免费版,有诸多限制,但不影响本次教学。学习完之后如果感兴趣想继续,建议购买个人版,里面的图层数量无限制、设置图层顺序等,都是非常好用和重要的功能。 1. 打开软件
New Project 新建工程 → 打开之后一张白纸。 Open Project 打开工程 → 打开之前已经保存过的工程文件,首次打开指向的是一堆官方的范例文件,很有用(后面会说到)。 l 点击New Project 
New empty project 新建空白工程,同上,建一张白纸。 建议:如果已经想好想做的游戏的界面尺寸,可直接选用下面的模板,省不少时间。 此外,强烈建议!往下拉,就是官方的范例文件。这些都是已经做好的游戏,对新手来说有很高的借鉴价值,而且刚好想做同类型的游戏(比如说Flappy Bird),直接打开,替换一下图片,调整一下参数,微调部分代码,那就是自己的游戏了,多方便。 2. 界面介绍
将主界面进行大致的区域分割,先不要关注具体细节。 A 最次要,设置好了基本不用管了。 B 重要,有很多时间会消耗在这里,下文会重点介绍。 C 最重要,大部分时间消耗在这里。 D 一般,本项目所有的项目元素(插件、图片、音效等等)列在此处(Projects) E 一般,查看当前页面使用到的项目元素,列在此处(Objects),还有瓦片背景(Tilemap) 另外,个人版还有一个Z-layer,用过PS的应该清楚,就是图片的上下层关系,很重要的功能,免费版可通过调整D区域的Layers来解决。 3. 架构介绍我们先暂停一下教程,了解一下construct2的架构。了解架构可以让大家心中先有一个整体的概念,知道C2是怎么运作的,对后面的设计工作很有帮助。 l 上一章中说到,界面中最重要的就是C区,那C区有什么呢 除了一大块空白以外,左上角有一个标签: 
另外,细心的朋友也会发现,D区也有类似的: 
其实就是最重要的界面层和逻辑层。 
一个图片层对应一个逻辑层,图片层就是放置我们游戏界面上的主角、坏人、机枪子弹等元素的,逻辑层就是控制这些主角坏人等元素的逻辑的,也就是传说中的代码。 图片层下面只能有一个逻辑层,或者没有逻辑层。 逻辑层上面必定只有一个图片层,不能没有图片曾。 我们可以把自己当成这个游戏的上帝,那么图片层就是天地,逻辑层就是这天地间运作的规律。 l 有了天地,那还要有丰富多彩的世界,让我们把主角、坏人、枪支、子弹、地板等加入到这个世界中,这个就是插件(plugins)。 双击任意空白处,弹出插入插件的窗口: 
第一次看到吓死了,这么多插件啊。实际上我们90%的情况下用到的就只有Sprite插件。 
就这货 回到上帝模式,我们要创世,首先要造出落脚的地板。用到的是Tiled Backgroud插件,也就是传说中的瓦片,把一张图片无限重复铺满整个画面。 
所以,我们可以看到,青色的地板加上了,三角形的小人(项目元素大部分都是Sprite)快乐地生活在上面。  4. 项目元素属性和人一样,每个项目元素(插件)也有高矮胖瘦,拥有各自的属性,可以调整它们的位置、大小、颜色、透明度等等基础属性,B区域中就可以进行调整。 既然有基础属性,当然也有特殊属性,下面就介绍一下特殊属性四大天王: 1、变量(instancevariable) 2、行为特性(behaviors) 3、特效(Effects) 4、容器(Container) l 变量 附着在插件上的变量,可以存储数字和文本,并进行运算和增减。和你说一个词你就懂了,HP,就是血量,就是一个变量,将它附着在某个敌人上,数字小于或等于零,敌人就死啦。 l 行为特性(behaviors) 如果说插件(plugins)是C2中第一重要的话,那么行为特性(behaviors)就是第二重要。 行为特性就相当于是将若干相关或常用的属性打包,变成属性包,比如说有个“子弹”(bullet)行为特性,带有自动飞行的属性、可以设置移动速度、加速度、减速度等等。将其挂载在某个插件上,这个插件就带有了子弹的全部所有属性。 那我们先看看behaviors的列表: 
这也是一坨一坨的好多呀。但这不用一个个去记,可以用一个学一个。 其实学习construct2有点像学英语,插件(plugins)、行为特性(behaviors)就像是英文单词,掌握得越多越能写出好文章(做出好游戏)。而且不仅限官方自带的插件,非官方的爱好者也会写一些非常非常好用的插件,有时候自己费尽脑汁想做的效果,一个插件就搞定了。 l 特效(Effects) 也是附着在插件上的特性,视觉效果,比如雾化、液态、噪点等。 
这个功能免费版不支持,而且需要浏览器支持WebGl,在手机上可能由于一些兼容问题会出现一些奇怪的效果。所以新手用的不是很多,有兴趣可以自己研究。 不过,有些特效真的很漂亮呀。(颜控必入) l 容器(Container) 这个也属于高级功能,但免费版也能用,作用是把一个插件装入另一个插件。具体怎么应用呢,比如说要做一个魂斗罗一样的射击游戏,主角就是一个插件,手上的枪也是一个插件,把枪“装在”主角身上,用到就是这个功能。 继续回到上帝模式,这个世界上的每一小人,高矮胖瘦都不一样,并带有自己的脾气特性。 
每个点代表一个行为特性 5. 逻辑代码看完了图片层,再看看逻辑层。每个逻辑层只能对应一个图片层,就如同一个世界只能拥有一套自然规律。(看到这里就想到了三体,一个世界有多套自然规律) 逻辑层,其实就是代码。Construct2号称不用写代码,实际上还是要写的哈,只是它的代码结构非常简单,优点是好学,缺点是代码量大了就像搅面条,维护起来特别麻烦。所以construct2适合做创意小游戏,高效快速,大型的商业游戏还是交给专业的游戏开发引擎吧。 我们先来看C2的代码窗口 
1、上方的绿色的放置的是游戏中用到的全局变量,例如游戏时间、分数等等放置在此。 2、下方的每个数字,代表一条代码,学过BASIC的就知道,这就是行号,程序运行时按照这个顺序一条一条地运行代码。 说到这里,要普及一个概念,什么叫tick。比如说有200条代码,系统从第1条开始检查并运行到第200条后结束,算是一个tick(当然不是200条代码全部运行,中间肯定有一些跳转和条件判断)。一般一秒钟运行20 tick,这张程序表一秒钟要运行20次。这有点类似“帧”的概念,一秒20帧的动画,就是一秒钟播放20张图片。 人的反应能力0.1秒左右,所以理论上来说系统运算速度高于一秒10 tick就够了。当然tick不是越高越好,手机等设备对运算的强度非常敏感,太高就会导致耗电、卡顿等等问题。 3、细心的朋友可以发现某些代码前面有个小标记。带有绿色小箭头 的表示是个触发事件,比如这条tick内检测到手指触摸,则运行该条代码。带有绿色旋转箭头 的表示的是遍历事件,比如说,检查所有人的HP情况,如果发现有人HP少于或等于0,则执行“处死”事件。 4、单条代码的结构非常简单,看这个表就懂了 这部分后面实战部分会详细讲解,目前只要先做了解。 6. 准备开工吧好了,到此,作为使用C2创造世界的上帝,手上的工具已经全都准备好了。当然了,作为一个完整的游戏,仅仅只有“一个世界”是不够的,比方说: 
是不是有种“大千世界”的感觉?其实我们所说的“世界”就是场景,一款完整的游戏需要多个场景。 为了本次教学方便,范例游戏只做一个场景。有兴趣的朋友可以自己创建多个场景,只要右键点击D区域的Layouts文件夹,选择Add layout即可。 
另外别忘记同样在Event Sheets文件夹创建layout对应的Event sheet,不然你的世界就“动”不起来哦。 7. 游戏构思相信大家都玩过《植物大战僵尸》吧。我们可以自己控制豌豆射手,变成一个射击游戏,配合触摸,做一个适合手机上玩的小游戏。 大家可以先看看最终效果图: 
需要的素材也准备好了,附件里下载: 8. 瓦片地板在铺设地板之前,我们先设置一下“房间”的大小。 先移目到D区,选中Newproject 
再移目到B区,设置WindowsSize为480,640 
设置好project的尺寸后,还要设置layout的尺寸 
选中后,B区内设置LayoutSize、Margins都是480,640 
大家可能会奇怪,为什么我设置好了project的尺寸,还要设置layout呢。同时,细心的朋友也能发现,实际上设置project的,是一个虚线框。 其实,虚线框就是我们屏幕的尺寸,俗话说的“镜头”。卷轴类的游戏,例如Flappy Bird,镜头就小于背景,这样才能形成背景滚动的效果。但我们这款不用滚动卷轴,所以全都设置成一样。 
设置好之后,可以正式铺设瓦片了。双击C区域的任意空白处,弹出Insert New Object,选中Tiled Background插件后选择insert: 
点击屏幕空白处后,弹出瓦片编辑窗口: 
选择load an image from a file: 
选中素材文件夹里的地板: 
如果图片的尺寸不是2的指数形式,会提醒你。 
这里就要提一下,制作图片素材的时候,尽量将图片尺寸裁剪成32、64、128等2的指数的形式,图片量多之后对性能有很大的影响,特别是移动设备上。不过暂时做不到也关系,为了教程顺利进行,先凑活着用吧。 关闭编辑窗口后,瓦片会自动根据大小铺设,将其铺设成界面尺寸一样大即可。 
可以拖动移动并控制大小 
直接设置参数更准确方便 界面D区,切换至Layers标签,点击锁图标,将Layer 0锁定。 
另外,再此界面,点击加号图标,增加一个图层Layer 1并选中。 
解释一下:我们将瓦片地板放在Layer 0并锁定,因为瓦片不会变化,可以方便之后的操作。我们新建一个Layer 1,将其他元素(大多数都是动态的)放置在这里。 PS:再啰嗦一下,大家也可以自己斟酌,将确定不会变动的元素放在Layer 0,可以方便管理和之后的操作。 9. 放置豌豆射手双击舞台,插入一个Sprite,最好能够下方命名处命一个名方便管理。 
选择花盆底座,将其放置在界面下方位置。 
同样操作,将豌豆射手也添加进入,但是图片的炮口是转向右边的,看起来像是得了歪脖子病,所以我们在B区设置一下角度让它朝上。 
看起来还不错: 
为什么要弄一张“歪脖子”的素材呢,因为CT2规定图片的默认是朝向45°的(可能因为它默认自己是一款制作横版卷轴游戏的工具吧)
我们要通过触摸控制炮口的转向,首先要加一个touch的插件。 
接下来要写代码了,转向Event sheet 1,点击Add event,选择豌豆射手 
选择on anytouch start 
细心的朋友应该会发现,能表达触摸的时间很多,那为什么要选择这个事件呢? 如果实际用手指操作看看就能发现问题,如果是on any touch end或是on tap,他们完成触发的条件是“手指松开”,所以必须完成手指的“点击”再“松开”,才能完成一次转向。而on any touch start只要手指“点击”即可,手感会好很多,设置可以在屏幕上滑动进行转向。有兴趣的朋友可以试试用on anytouch end或是on tap,感受一下最终在手机上的表现效果。 以上只是条件,接下来点击Add action创建事件。 
选中豌豆射手 
选中set angletoward position,设置朝那个方向转向: 
输入touch.X和touch.Y,表示朝着手指触摸的位置转向。 
按F5,查看一下效果。 
现在豌豆射手已经“指哪儿朝哪儿”了。但是还有一个小问题,因为小射手的脑袋是圆圆的,好像转向没有完全沿着圆脑袋转,有点偏。 这问题就需要我们设置一个锚点,转向的时候以它为圆心。 双击豌豆射手打开图片设置,选择锚点,设置锚点位置在射手的脑袋中间即可。(注意:设置锚点位置要用键盘的上下左右键移动) 
然后稍微调整一下射手在花盆上的位置,让锚点和花盆的中心重合,这样转起来看就像是射手在花盆上转着脑袋的样子,比较自然。 完成之后F5看一下效果,看起来就比较完美了。 10. 发射子弹首先我们要将子弹素材加入进来。双击舞台插入一个Sprite,使用素材bean,创建成功后放置在任意位置,选中后在B区设置其属性,点击Behaviors添加一个行为特性。 

点击加号添加 选择Bullet并添加(就是子弹……) 
添加好之后发现Behaviors里已有Bullet属性了,关闭窗口。 此时再选中豌豆,就会发现有B区已经有Bullet相关的参数设置了。 对Bullet参数进行相应的设置,设置Speed值为600(当然也可以根据自己喜好设置成别的值) 
另外几个参数,Acceleration是加速度,设置了之后子弹会越飞越快。Gravity是重力,设置了之后自动会向下落,数值越高下落越快。建议这两个值都设为0。 另外,还要在豌豆射手身上,再增加一个锚点。因为我们设置子弹从射手嘴里射出,需要将具体位置给指定出来,就是这个新加的锚点位置。 双击打开豌豆射手,新增一个锚点: 
转到代码区,在原有的touch条件下,增加一个事件 
依然是豌豆射手发生的事件 
选择Spawn another object事件,意思就是生成另外一个物件。 
有三个项目需要填写,分别是object(生成的物件)、layer(图层)、锚点(Image point)。 Object对应就是豌豆子弹,layer是1(还记得之前创建图层后面的编号了吗),Image point是1(翻回去看看后面的编号)。 
按F5看看,点击屏幕,发现豌豆射手可以射击了!突突突机关枪一样。 不过,好像有个小瑕疵,怎么一开始屏幕会有个豌豆子弹飞出去啊?(如果一开始你将子弹放置在舞台内的话) 解决的方式也很简单,把子弹拖出舞台就可以了。 
另外,还要选中子弹,在Behaviors里面增加一个DestroyOutsideLayout,意思就是这个物件不在屏幕中的时候,就被系统清除掉。这点非常重要,因为物件放置在屏幕外,依然占据着内存,一旦数量多了之后,就会造成内存泄漏事故,游戏会越来越卡。 11. 设置敌人同样,双击舞台插入Sprite,注意下方的Animation frames功能框,右键点击选择Import frames –From files… 
打开素材文件夹,选中所有的僵尸行走图 
默认自带的第一帧没有用,删除掉 
右边Animations功能框内,我们可以右键点击动画,选择Preview,查看动画预览效果。 
看了实际效果后发现,虽然僵尸以行动迟缓著称,但这动画也太慢了,所以我们还要对这个动画的参数进行一些调整。 选中动画,在B区,调整动画的参数Speed为10,Loop为YES。Loop就是无限循环播放的意思,因为僵尸行走是永不停息的捏哈哈哈哈…… 
还有一个小瑕疵,就是僵尸看着像是会“飘”,这是因为动画文件引起的,所以我们要设置一个锚点让僵尸“贴”住地面。 点击锚点图片,弹出Image points窗口,右键点击,选择Quick assign,选择Bottom。这样,我们就可以设置当前图片的锚点放置在下方居中位置。 
光有一张图片设置还不够,还要将设置普及到动画的每一帧图片内。 右键点击锚点,选择Apply to whole animation。 
但这只是让僵尸在原地踏步,还要让僵尸真正能够前进,就要在Behavior添加特性让它“走”起来。 大家可以依旧选中之前用过的bullet,但这里有一个更好的选择Platform 
Platform支持的可设置参数更多,可以实现更好的控制,一般用于横版游戏的主角、敌人的设计,完成各种复杂的动作。 另外还要加上DestroyOutsideLayout。随着大家做游戏的技能越来越熟练,是能够培养这种感敏性的,那种类似“无限生成”、“自动生成”的物件,都要有相应的垃圾处理机制,及时清除掉,对游戏的效率提升有非常大的好处。 
然后对Platform的部分参数进行设置。 
Maxspeed是僵尸移动的速度(当然就是很慢很慢啦)。 Gravity是重力,大于0就会下落,等于0是保持浮空。(也可以试试小于0,你懂的) Defaultcontrols是默认控制角色,一般用于横版游戏主角的控制,如果代码中加入玩家控制左右移动事件的话,就能直接控制该角色的移动。此时我们选择NO。 光有这些僵尸还“动”不起来,需要在代码中控制它“向前走”。 点击Addevent添加一条新的事件 
这回是添加System事件 
添加ForEach事件 
选择执行的目标物件——僵尸,点击Done完成创建。 
这段代码什么作用呢,For Each字面的意思就是“为每一个”,聪明的朋友可能就已经能想到,“为每一个”就说明不只有一个,可能会有很多个。作为敌人,僵尸的数量肯定不止一个,如果僵尸有多个实体,那一条代码就能对每一个实体做出控制,很方便吧。 点击Addaction,增加对应的事件。 
选择僵尸 
大家可以看到,一旦加入了某个Behavior,就会增加对应的动作选项,很方便吧,这次我们选中Simulatecontrol,意思就是系统对该对象进行控制。 
控制可以选择僵尸向左走、向右走、跳跃,我们先选择Right向右走。 
可能有朋友要问了,僵尸一直向左走,不会太单调了吗。别急,下一章我们就会讲到这个内容,现在我们可以先按F5,看到屏幕中的僵尸就可以缓缓地向右走动了。 12. 设置左右移动要实现这个目标,我们要实现这两种效果:一,让僵尸“知道”自己现在朝向哪里;二,让僵尸碰到屏幕边界后转身返回。 现在我们要在僵尸身上添加一个变量,标注它现在是“向左”还是“向右”。 选中僵尸,在B区属性内点击Instance variables添加局部变量。 
设置Name为direction(当然也可以自己设喜欢的变量名),Type选择Text(文本),Initial value设置为right(当然也可以用符号表示向左或向右,自己看得懂就好)。 
设置好变量之后,僵尸就“知道”自己应该是向左还是向右了,另外还要在代码中添加对僵尸目前状态的判断。 我们要对原有的代码进行修改,右键点击2号代码,选择Add,选择Addsub-event 
选择僵尸,选择Compareinstance variable 
大家可以看到,系统已经自动检测到局部变量了,大家只需要保证comparison的值是=equal to,value的值是”right”(一定要有英文引号,注意!)。 
同样的操作,同样步骤再建立一个sub-event,只是最后的value的值为”left”。 最终的效果为一个一分为二的分支: 
看到这里,一些聪明的朋友就应该能够猜到,我们只要分别在”right”和”left”后面分别对应让僵尸向右走、向左走就可以了。 之前有做好的,将其拉拽到”right”后面即可,然后同样的方式再创建一个,control改成left即可。 
光是这样还不够,因为僵尸的动画素材是向右走的,如果向左走的话,就会出现“僵尸版月球漫步”倒着走了,所以我们要在进行一些相关设置。 点击Addaction,添加僵尸的事件: 
选择Setmirrored,设置镜像: 
因为我选择的是在“right”下创建的,所以要选择not mirrored,不进行镜像。 
同样操作,在“left”下创建同样的action,但最后state选择mirrored,进行镜像。 
好了,我们已经完成了第一步,另外还要让僵尸“自己”转身。我们先点击界面任意处添加一个sprite,不用任何图片,填上你喜欢的颜色,作为界面边界。 建议创建sprite时命一个名字,例如“leftBorder”。选择油漆桶工具,涂上喜欢的颜色: 
拖动调整其大小,放置在界面左边(不要放在舞台内),作为左边的边界。同样的操作新创建一个sprite,命名为rightBorder,作为右边的边界。 
之后,在代码区内,点击Add event,新增一条leftBorder的事件: 
选择On collisionwith another object,意为碰触到某个其他物件。 
然后就是选择碰触的目标物件,当然就是僵尸啦。 
然后,在这条事件后,点击Add action,创建对应的执行事件。 由于之前的准备工作做得很充分,所以我们只要设置僵尸的局部变量direction为“right”即可。(撞到左边的墙后当然是继续往右走啦。) 
将变量设为“right”(注意一定不能忘了引号)。 
同样的操作,将rightBorder的事件也创建起来,注意direction为“left”。 
完整之后,按F5预览,僵尸能够正常行走了,而且走到边界会自动转身徘徊了! 
13. 子弹击中效果先把击中效果的动画加进来,双击舞台创建Sprite,命名为explosion。 
设置动画参数,speed设为15,注意loop要保持NO,因为此动画只播放一次,不需要循环。 
然后代码内,增加击中相关的事件。Add event,选择豌豆子弹,选择上一节新接触到的On collision withanother object事件,目标设置为僵尸: 
点击Addaction,继续添加执行事件。选择执行豌豆的事件,spawn another object事件 
选择目标为击中动画explosion,默认layer1,锚点0 
在下面还要继续添加一个action: 
依然是豌豆的事件,选择Destroy。因为子弹击中敌人之后,就“打到肉里面”了,所以要设置为击中后消失。 
还有一条重要的代码,将explosion动画清理掉,不然随着击中次数越多,游戏会变得越来越卡。 新增一条事件Addevent,选中explosion,选中On finished(在Animations下) 
填入动画的名称,由于我们用的是默认名,所以填入“Default”(注意引号)。 
后面继续Addaction,增加explosion事件,选择destory。 
按F5试试吧,点击屏幕射击,子弹飞到僵尸身上,很有打击感吧。 14. 设置多个敌人要放置多个僵尸,就要用到系统的刷新机制,新增一条事件Add event,选择system(系统),选择Every X seconds事件。 
设置每隔多少秒触发,1.0表示1秒。当然也可以使用ramdom函数,每隔1-3秒进行,不定时刷新更具趣味性。 
继续添加Add action,选择system,添加Create object 
创建的目标当然就是僵尸,Layer是1,另外要注意的是坐标(X,Y),表示的是在屏幕左边界外面刷新(凭空出现比较违和),随机位置(不要设置太高僵尸脑袋在外面,或位置太低豌豆射手都打不到了)。 
同样操作,再创建一条同样的事件,只是坐标X轴改为500,是在屏幕的右边界外。这样做有个好处,僵尸是左边右边都有出,而不是单单从左边出来,略显单调。 按F5查看效果,发现一会儿就满屏幕僵尸了  15. 设置数值拍脑袋定一下,僵尸的血量为15,豌豆的攻击力为2-5。 点选僵尸,B区点击Instance variables,增加一个局部变量HP,类型为Number,数值为15。 
另外,在子弹击中僵尸的事件下,再添加一个事件,用于削减僵尸的HP。 
选中僵尸,选择subtractfrom(减少局部变量的数值) 
设置减少的量为随机2-5. 
然后需要设定僵尸的血量小于或等于0的事件(当然是死亡啦)。 在这之前,我们要先把僵尸死亡的动画加进来。双击舞台添加Sprite,导入dead文件夹的素材,步骤参考11节 设置敌人部分的内容(别忘了设置锚点)。 设置动画参数,Speed设为10,loop设为NO(默认)。设置好后将其拖出舞台(别让玩家看到)。 
新增事件Addevent,选中僵尸: 
再选择Compareinstance variable,监控局部变量数值: 
设置当HP的数值小于或等于0时,执行命令:(注意Instance variable对应的是HP) 
继续在此事件后添加执行事件Add action。选中僵尸,选择spawn another object事件,目标为僵尸死亡的动画,Layout为1,锚点为0。 跟着下方再添加一条事件,将死亡后的僵尸清除掉Destory。 
就如同13节子弹击中效果 中讲到的,我们要将播放结束的僵尸死亡动画清除掉,所以我们要添加类似的事件。 同样,选中僵尸死亡动画,选中On finished(在Animations下),然后让其Destroy掉。 
就这样就OK了吗,还不对,因为僵尸还有向左(也就是mirrored状态),所以,对应的死亡动画也要mirrored。 首先我们创建一条和10号代码一样的一条代码(用复制粘贴大法)。 
右键点击事件条件,选择Add,选择Addanother condition。这里有点类似12节设置左右移动中的sub-event。 这里我们添加的,叫复合条件,也就是说,需要两条条件同时满足,才会执行后面的事件。 
我们创建的复合条件就是,当僵尸处于mirrored状态下,执行事件。 先选中僵尸 
选择is mirrored 
大家可以看到,复合条件创建好后的样子 
之后继续添加执行事件Add action,选择僵尸死亡动画,然后将其镜像(使用set mirrored)。 
最后,最重要的一点,将刚刚创建的12号代码拖拽放在原来的代码前面!因为当前代码的条件比之前的代码条件苛刻,如果放在后面的话,会造成这条代码永远不会执行! 
好了,按F5试玩,点击屏幕发射子弹,可以正常击杀僵尸,已经基本是个可玩的游戏了。 16. 设置记分系统游戏就这么茫无目的地打着未免有些单调,所以我们要设置一个记分系统。有三个数据要实时显示:1 杀死的僵尸个数2 豌豆射手开炮次数 3 游戏时间。 首先我们要再建立一个图层,用于放置UI相关的内容,D区Layers里面点击加号添加: 
选中layers 2,拖入三张图片kills.png、times.png、bean.png(注意和之前用过的不一样),作为记分数字栏的图标,将其放在合适的位置。 我们可以发现,将图片直接拖入,系统会自动将其创建为Sprite,注意要在Layer 2 图层下(后面所有涉及UI的都要放在Layer 2下,否则会图层错误) 
然后双击舞台,添加插件textbox,同样的操作创建三个,分别命名为kills_text、times_text、bean_text。 
调整大小至合适位置,并放置在相应的图标旁边(用于显示分数数值)。 
选中文本框,在B区进行设置,Placeholder里面分别设置文字为kills: 、beans: 、time: 
要记得三个文本框的名字,之后代码中需要用到: 
转到代码部分,右键点击任意空白处,选择Add global variable,创建全局变量,用于存储杀死的僵尸数、打出的豌豆数、游戏时间(秒) 
自己命名(任意文本,自己能看懂就行),保证类型是number就可以,怕忘记可以在Description里面写上注释(支持中文) 
三个全局变量建好了,置顶显示在代码窗口中: 
首先,将僵尸死亡的计数加上去。在僵尸死亡动画结束的代码下增加一条: 
选择system事件,选择Add to,增加变量值 
选择Variable变量名为kills,value变量值为1,也就是僵尸死亡1只,分数加1。 
然后要将这个变量值显示出来,新增事件Add event,选择system系统事件。 
选择Every tick,我们在第5节逻辑代码 中介绍过tick的概念,由于分数的变化每时每刻都有可能变化,所以需要系统对其进行每时每刻的更新。 
继续添加action,选择文本框kills_text。 
选择set text事件,设置文本内容。 
填入文本内容,"Kills: "&kills,前面引号内的就是文本,&是连接符号,kills是你之前设置好的变量名(如果之前已经设好了的话,系统会自动提示,很方便) 
同样的操作,在后面继续增加times_text、bean_text的实时更新。 
在touch事件下增加纪录子弹发射的相关代码: 
此时可以按F5试试,看看豌豆计数和僵尸死亡计数是否正常计算。 不过大家可能会发现,一开始什么都没打,击杀次数就自动变成1了。那是因为我们放置在舞台外面的死亡动画播放结束后增加的,解决方式很简单,给死亡动画加一个DestroyOutsideLayout的behavior,这样在游戏一开始屏幕外的死亡动画就被清除了,也就没有碰触到加分事件了。  17. 设置游戏时间我们先设定一局游戏时间为30秒,游戏结束后弹出结算框显示分数,并可以再次一局游戏。 首先把结算框面板score.png加入进来,然后添加text插件,命名为score_num 
在B区设置text的属性,text设为000(这个任意),Initialvisibility设为Invisible(不可见,记得同样把结算框面板score也设为不可见),字号为24,颜色白色。 
将其放置在合适的位置,作为结算框面板的数字。 最后,将restart.png重新开始按钮,放入,也设为invisible,将其放在合适的位置。 
将全局变量,将times设置为30。 
新建一个事件Add event,选择system系统事件,选择Evey X seconds,X设置为0.01。 
点击Add ation,选择system系统事件,选择subtract from,数值设置为0.01。 
再添加一条时间,用于检测时间是否走完。添加system系统事件,选择compare variable,variable变量名选择times,小于或等于0。 
接着Add action,选择score面板,选择set visible,设置为visible(可见)。 
同样的操作,将score_num、restart都设为可见。 
最后很重要的,将击杀的分数显示在面板上,找到之前写的Every tick的代码,下方添加一条,选择score_num,选择set text,值为全局变量kills。 
好了,按F5我们试试吧,系统自动倒计时30秒,结束后弹出结算框。呃……好像不对啊,这个时候怎么还能打?游戏应该结束了才对啊。我们需要设置一个游戏开始结束的“开关”才行,下一节继续讲。 18. 控制结束和开始我们先创建一个全局变量switch,作为开关,类型为number,数值为1,0表示关闭,1表示开始。(最好是写上注释) 
当switch为关时,僵尸应该不能继续刷新了、豌豆不能继续发子弹,游戏时间不能减少。我们可以用到之前学到的“复合条件”,将这些相关的代码位置加上限制。 豌豆发射子弹部分: 
僵尸刷新部分: 
游戏时间减少部分: 
另外,游戏结束的标志——时间小于或等于0的部分,要添加上相关的收尾工作,首先要用destory将场上的所有僵尸清理干净,另外将switch设为0。 
现在可以按F5试试,时间走完之后游戏是否结束。 测试成功后,还要添加重新开始游戏的相关代码,基本上和游戏结束的“反”过来。 新增事件Add event,选择touch,选择on tap object,目标为restart按钮。 
后面接着Add action,设置score、score_num、restart为invisible(不可见),将switch设为1(打开开关),还有一个 新增的将全局变量times重新恢复为30秒,还有相关的计数kills、beans也都要设为0。  19. 结语至此,本教程的所有内容都已结束。大家可以导出为html文件,将其部署在网站上,将链接发给朋友,打开就能玩(微信内也可以打开哦)。个人版提供了多种导出方式,包括iOS和安卓。也可以去官方网站(scirra),将游戏部署在官网的应用商店里(速度较慢,需翻墙)。 如果想深入研究,可以去百度construct2贴吧向各位高手们咨询,还有一些高手自制的很多很给力的插件,前文也说到了,当你想实现某种效果不知道如何下手时,很可能一个插件就搞定了,官网也有很多免费和收费的插件,大家要合理利用哦。 祝大家都能做出自己想要的游戏。 最后还有一个小彩蛋,我的素材文件里有个Boom文件是什么用的呢,就是用来作为炸弹的按钮,点击之后所有场上的僵尸都会死,大家可以自己想想看这个应该如何实现呢?(源文件里面已经做好了)
|