Cocos Creator游戏开发的核心理念之一就是让内容制作和功能开发顺畅并行。上一部分重点介绍了美工内容的处理,接下来就是通过编写脚本开发功能的过程。之后我们还会看到,写出来的程序脚本可以很容易地被内容制作者使用。
如果你从来没有写过程序,不要担心。我们将在教程中提供所有需要的代码,只需复制并粘贴到正确的位置。之后可以找你的程序员朋友解决这部分工作。让我们开始创作推动主角行动的剧本。
创建脚本
首先,右键单击资源管理器中的assets文件夹,选择New-Folder,右键单击New Folder,然后选择Rename将其重命名为scripts。之后,我们所有的脚本都将存储在这里。右键单击脚本文件夹,然后选择新建-JavaScript。创建一个JavaScript脚本,并将新脚本的名称改为Player。双击脚本以打开代码编辑器。注意:Cocos Creator中脚本的名称是组件的名称,这个名称是区分大小写的!如果组件名称的大小写不正确,组件将不能正确地按名称使用!
写入组件属性
打开的播放器脚本中已经有一些预置的代码块,如下图所示:
抄送。Class({ extends: cc。Component,properties : {//foo : {////attributes ://default : null,//只有当组件第一次将////附加到节点时才会使用默认值//type: cc。SpriteFrame,//可选,默认值为type of default//serializable : true,//可选,默认值为true //},//bar: { //get () { //返回此。_ bar//},//set (value) { //this。_bar=值;//} //},},//生命周期回调: //onLoad () {},start () { },//update (dt) {},});让我们来看看这些代码的功能。首先我们可以看到一个全局cc。Class()方法。cc是什么?Cccocos是cc cocos的缩写,是Cocos引擎的主要命名空间。引擎代码中的所有类、函数、属性和常数都在这个名称空间中定义。而Class()是cc模块下的一个方法,用来声明Cocos Creator中的类。为了更容易区分,我们调用cc声明的类。CCClass类。Class()方法的参数是一个prototype对象,可以通过在prototype对象中以键-值对的形式设置所需的类型参数来创建所需的类。
例如:
var Sprite=cc。class({ name : \ ‘ sprite \ ‘ });上面的代码用cc创建了一个类型。Class()方法,并将其赋给Sprite变量。还将类名设置为sprite。类名用于序列化,通常可以省略。
对于cc的详细研究。类,可以参考使用cc。类来声明类型。
现在让我们回到脚本编辑器,回头看看前面的代码,这是编写一个组件(脚本)所需的结构。具有这种结构的脚本是Cocos Creator中的组件,可以安装在场景中的节点上,并提供各种功能来控制节点。我们先设置一些属性,然后看看如何在场景中进行调整。
在播放器脚本中找到属性部分,将其更改为以下内容并保存:
//player.js//.属性3360 {//主角的跳跃高度3360 0,//主角的跳跃持续时间3360 0,//最大移动速度MaxMoveSpeed 3360 0 0,//加速度accel: 0 0,},//.Cocos Creator规定一个节点拥有的所有属性都需要写在properties代码块中。这些属性将指定主角如何移动。在代码中,我们不需要关心这些值是什么,因为稍后我们将直接在属性检查器中设置这些值。以后在游戏制作过程中,我们可以把所有需要随时调整的属性都放在properties里。
现在我们可以将玩家组件添加到主角节点。在“层次管理器”中选择“播放器”节点,然后在“属性”检查器中单击“添加组件”按钮,并选择“添加用户脚本组件-播放器”将播放器组件添加到主角节点。
现在,我们可以在属性检查器中看到新添加的播放器组件(您需要选择播放器节点)。根据下图设置主角跳跃和移动的相关属性:
这些值以像素为单位,只是jumpDuration的单位是秒。根据我们目前对播放器组件的设置:我们的主角将能够在200像素的高度跳跃,跳到最高点所需的时间为0.3秒,最大水平移动速度为每秒400像素,水平加速度为每秒350像素。
这些值都是建议。游戏运行后,您可以根据自己的喜好随时在属性检查器中修改这些值,而无需更改任何代码。
编写跳转和移动代码。
再加一个让主角跳起来的方法。在属性:下{.},代码块中添加一个名为setJumpAction的方法:
//Player.js属性3360 {//.},set Jumping 3360 Function(){//Jumping up var jump up=cc . move by(this . jump duration,cc.v2 (0,this.jumpheight))。easing(cc . easecibizationout())//行踪变量jump down=cc . move by(this . jump duration,cc.v2 (0,-this.jumpheight))。easing(cc . easecibizationin());//不断重复返回cc。永远重复(cc。序列(向上跳,向下跳));},这里需要了解一下Cocos Creator的动作系统。因为运动系统比较复杂,这里简单介绍一下。
在Cocos Creator中,动作只是节点的位移、缩放和旋转。
例如,在上面的代码中,moveBy()方法的作用是在指定的时间内移动指定的距离。第一个参数是我们之前定义的主角属性中的跳跃时间,第二个参数是Vec2类型的对象(表示2D向量和坐标)。为了更好的理解,我们可以看看官方的功能描述:
/** * !#en *通过修改Node对象的position属性将它移动x,y像素。
* x和y是相对于对象的位置。
*可以同时调用几个MoveBy操作,结果
*运动将是个人运动的总和。* !#zh移动指定的距离。* @ method move by * @ param { Number } duration以秒为单位的持续时间* @ param { ve C2 | Number } delta pos * @ param { Number }[deltaY]* @ return { action interval } * @ example *//example * var action to=cc . move by(2,cc.v2(windowSize.width – 40,windowsize . height-40));*/cc.moveBy=function (duration,deltaPos,deltaY) {返回新cc。MoveBy(duration,deltaPos,deltaY);};如您所见,方法moveBy总共可以传入三个参数。我们已经知道了前两个参数,第三个参数是Number类型的Y坐标。我们可以发现第二个参数可以传入两种类型,第一个是数字类型,第二个是Vec2类型。如果我们在这里传入数字类型,这个参数默认是X坐标。这时候我们要填入第三个参数,也就是Y坐标。在上面的示例中,cc.moveby的第二个参数(this.jumpduration,cc.v2 (0,this.jumpheight))是使用cc.v2方法构建的Vec2类型的对象。这个类型代表一个坐标,既有X坐标也有Y坐标,因为不需要传入第三个参数!同时注意官段X和Y都是相对于物体的位置。这句话的意思是传入的X,Y坐标是相对于节点当前的坐标位置,而不是整个坐标系的绝对坐标。
知道了参数的意义之后,我们再来关注一下moveBy()方法的返回值。看一下官方说明,可以知道这个方法返回的是ActionInterval类型的对象。ActionInterval是Cocos中表示时间间隔动作的类,这个动作在一定时间内完成。这里我们可以理解前面部分代码cc.moveby (this.jumpduration,cc.v2 (0,this.jumpheight))的含义。easing(cc . easecibizationout()),意思是构造一个ActionInterval类型的对象,这个对象表示在jumpDuration的时间内移动到相对于当前节点的(0,this.jumpHeight)的坐标位置。简单来说就是一个向上跳跃的动作。
那么后半段宽松的作用是什么(cc。EASECUBICATIONOUT())?缓动是ActionInterval类下的一种方法。这种方法可以使时间间隔动作表现为一种慢动作。传入的参数是慢动作对象,返回ActionInterval类型对象。这里,传入的对象是一个慢动作对象,使用EaseCubicationNout方法构造。EaseCubicationNout是按照三次函数缓慢进出的动作。具体曲线请参考下图:
详情请参考API。
接下来,在onLoad方法中调用新添加的setJumpAction,然后执行runAction来启动该操作:
//player . JSON load 3360 function(){//初始化跳转动作this . jump=this . set jump();this . node . run action(this . jump action);},场景加载后会立即执行},onLoad方法,所以我们会把初始化相关的操作和逻辑放在里面。首先我们把循环跳转的动作传递给跳转变量,然后在这个组件挂载的节点下调用jumpAction方法,传入循环跳转的动作,保持节点(主角)跳转。保存脚本,然后我们就可以开始第一次运行游戏了!
单击Cocos Creator编辑器顶部中间的预览游戏按钮。
,Cocos Creator会自动打开你的默认浏览器,开始在里面运行游戏。现在,我们应该可以看到我们的主角3354小紫色怪物在场景中间弹跳。
运动控制
只会原地跳跃的主角是没有前途的。让我们为主角添加键盘输入,用A和D控制他的跳跃方向。在setJumpAction方法下添加键盘事件响应函数:
//player . js setjumpaction : function(){//.}、onKeyDown (event) { //按键时设置标志switch(event . key code){ case cc . macro . key . a : this . ACC left=true;打破;case cc . macro . key . d : this . accright=true;打破;} }、onKeyUp (event) { //按键释放开关时取消设置标志(event . key code){ case cc . macro . key . a : this . ACC left=false;打破;case cc . macro . key . d : this . accright=false;打破;}},然后修改onLoad方法,增加了左右加速的开关,以及主角在水平方向的当前速度。最后,调用cc.systemEvent,并在场景加载后开始监视键盘输入:
//player . JSON load 3360 function(){//初始化跳转动作this . jump=this . set jump();this . node . run action(this . jump action);//加速方向切换this . ACC left=false;this.accRight=false//主角当前水平速度this . x speed=0;//初始化键盘输入监视cc . system event . on(cc . system event . event type . key _ down,this.onkeydown,this);cc.systemEvent.on(cc。SystemEvent.EventType.KEY_UP,this.onKeyUp,this);},onDestroy () {//取消键盘输入监听cc . system event . off(cc . system event . event type . key _ down,this.onkeydown,this);cc.systemEvent.off(cc。SystemEvent.EventType.KEY_UP,this.onKeyUp,this);},有Android开发经验的同学更能理解。这里的监听器本质上类似于Android中的OnClickListener。在cocos中,systemEvent用于监控系统的全局事件。(有关鼠标、触摸和自定义事件的监控和分发的详细信息,请参考监控和传输事件。这里,向systemEvent注册了一个键盘响应函数。在该功能中,开关用于确定键盘上的A和D是被按下还是被释放。如果按下,将执行相应的操作。
最后,修改更新方法的内容,增加加速度、速度和主角当前位置的设置:
//player . js Update 3360 function(dt){//根据当前加速方向更新每帧速度if(this . ACC left){ this . x speed-=this . Accel * dt;} else if(this . AC right){ this . x speed=this . Accel * dt;}//限制主角速度不超过最大if(math . ABS(this . x speed)this . maxmovespeed){//if speed达到极限,使用当前方向的max speed this . x speed=this . maxmovespeed * this . x speed/math . ABS(this . x speed);}//根据当前速度this.node.x=this.xSpeed * dt更新主角位置;},场景加载后每一帧都会调用update。我们一般把需要经常计算或者及时更新的逻辑内容放在这里。在我们的游戏中,根据键盘输入得到加速度方向后,需要计算每一帧更新中主角的速度和位置。
保存脚本后,点击预览游戏,看看我们的最新成就。浏览器打开预览后,用鼠标点击游戏画面(这是浏览器的限制,你要点击游戏画面才能接受键盘输入),然后按A和D键控制主角左右移动!
感觉动作有点慢?主角跳得不够高?希望有更长的跳跃时间?没问题,这些随时可以调整。只要为Player组件设置不同的属性值,就可以按照自己的想法调整游戏。这里有一组设置供参考:
jump height 3360 150 jump duration 3360 0.3最大移动速度3360 400 Accel 3360 1000这套属性设置会让主角变得极其灵活。至于怎么选择,就看你想玩什么风格的游戏了。
制造明星
现在主角可以跳来跳去了。我们要给玩家一个目标,就是场景中会不断出现的星星。玩家需要引导小怪物触碰星星来收集点数。主角碰到的星星会消失,然后在随机位置立刻再生一个。
制作预制构件
对于需要重复生成的节点,我们可以保存为Prefab(预置)资源,在我们动态生成节点的时候可以作为模板。更多关于Prefab的信息,请阅读Prefab。
首先,将资源管理器中的资源/纹理/恒星图像拖放到场景中,位置是任意的。我们只需要将场景作为我们的工作台来制作Prefab,制作完成后我们会将这个节点从场景中删除。
我们不需要修改星星的位置或者渲染属性,但是要让星星在被主角触碰后消失,我们需要为星星添加一个特殊的组件。按照添加玩家脚本的相同方式,将名为Star的JavaScript脚本添加到assets/scripts/中。
接下来,双击这个脚本开始编辑。星星组件只需要一个属性来指定主角离星星有多近就可以完成集合。修改属性,添加以下内容并保存脚本。
//star . jsproperties 3360 {//当星星与主角的距离小于这个值时,pickRadius: 0,}的收集就完成了。将该脚本添加到新创建的星形节点中,在层次管理器中选择星形节点,在属性检查器中单击“添加组件”按钮,然后选择“添加用户脚本组件-星形”,该脚本将被添加到新创建的星形节点中。然后在属性检查器中将“选取半径”属性值设置为60:
星形预制体的所需设置已完成。现在将star节点从层次管理器拖到资源管理器的assets文件夹中,一个名为star的预置资源将会生成。
现在可以从场景中删除星形节点,然后可以直接双击星形预置资源进行编辑。
接下来,我们将动态使用脚本中星星的预置资源来生成星星。
添加游戏控制脚本
星星的产生是游戏主逻辑的一部分,所以我们要添加一个叫做Game的脚本作为游戏的主逻辑脚本。在这个脚本之后,我们还将添加得分、游戏失败和重启的相关逻辑。
将游戏脚本添加到“资源/脚本”文件夹,双击打开脚本。首先添加生成星星所需的属性:
//game . js Properties 3360 {//该属性是指恒星预制资源StarPrefab : {默认3360 null,Type 3360cc.prefab},//恒星诞生后消失时间的随机范围maxStarDuration: 0 0,starduratu : 0 0,//ground节点,用于确定恒星Ground3360 {默认3360 null,type 3360cc.node}和//player节点生成的高度,其中这里的初学者可能会奇怪,为什么像starPrefab这样的属性都是用{}括起来的,括号里还有新的“属性”?其实这是一个完整的属性声明。以前,我们所有的属性声明都是不完整的。在某些情况下,我们需要给属性声明添加参数。这些参数控制属性在属性检查器中的显示方式,以及它们在场景序列化期间的行为方式。例如:
properties : { score 3360 { Default 3360 0,displayName 3360 \ ‘ Score(Player)\ ‘,tooltip 3360 \’ The Score of Player \ ‘,}}上面的代码为Score属性设置了三个参数default、display name和tooltip。这些参数分别指定score的默认值为0。在属性检查器中,其属性名(displayName)将显示为Score (player),当鼠标移动到该参数上时,将显示相应的工具提示。
以下是常见参数:
Default:设置属性的默认值,该值仅在首次将组件添加到节点时使用。
类型:定义属性的数据类型。有关详细信息,请参考CCClass高级参考:类型参数。
Visible:设置为false将不会在属性检查器面板中显示该属性。
Serializable:设置为false不序列化(保存)该属性。
DisplayName:在属性检查器面板中显示为指定的名称。
工具提示:在属性检查器面板中添加属性的工具提示。
所以上面的代码3360
star prefab : { default 3360 null,type3360cc。Prefab},很好理解。首先在游戏组件下声明了starprefab属性,该属性的默认值为null。可以传入的类型必须是预制的预制资源类型。之后,地面和玩家的属性也可以理解了。
保存脚本后,将游戏组件添加到层次管理器中的画布节点(选择画布节点后,将脚本拖到属性检查器上,或者单击属性检查器中的“添加组件”按钮,并从“添加用户脚本”组件中选择“游戏”。)
接下来,从资源管理器中拖拽星星的预置资源到游戏组件的星星预置属性中。这是我们第一次为属性设置引用。只有当属性声明指定该类型是引用类型(如cc。我们在这里写的预置类型),我们可以拖放资源或节点到属性上。
然后从层次管理器中拖拽地面和玩家节点到画布节点的游戏组件中对应名称的属性上,完成节点引用。
然后将最小恒星持续时间和最大恒星持续时间的值设置为3和5,然后我们在生成恒星的时候,会随机取这两者之间的值,也就是恒星消失之前经过的时间。
在随机位置生成星星
接下来,我们继续修改游戏脚本,并在onLoad方法后添加生成星星的逻辑:
//game . JSON load 3360 function(){//获取地平面的Y轴坐标this . ground=this . ground . Y this.ground.height/2;//生成一颗新星this . spawnnewstar();},spawn new star 3360 function(){//使用给定的模板在场景中生成一个新的节点var new star=cc . instantiate(this . star prefab);//将新添加的节点添加到画布节点下的this.node.addChild(newStar)中;//为星星设置一个随机位置newstar . Set position(this . getnewstar position());},getnewstarposition : function(){ var randX=0;//根据地平面位置和主角的跳跃高度,随机得到一颗星星的Y坐标var Randy=this . ground ymath . random()* this . player . get component(‘ player ‘)。JumpHeight 50//根据屏幕宽度,随机得到一个星x坐标var maxX=this.node.width/2; randX=(math . random()-0.5)* 2 * maxX;//返回星坐标返回cc.v2(randX,randY);},这里我们需要注意几个问题:
节点下的Y属性对应于锚点所在的Y坐标。因为锚点默认在节点的中心,所以需要加上地面高度的一半作为地面的Y坐标。实例化方法的作用是克隆任何指定的对象或者从预置实例化一个新的节点。返回值节点或ObjectNode下的addChild方法的作用是在节点的下一级建立新节点,所以新节点的显示效果在节点之上。节点下的setPosition方法的作用是设置节点在父节点坐标系中的位置,坐标点的设置有两种方式。一个是传入两个数值X和Y,另一个是传入cc.v2(x,Y)(cc类型的对象。Vec2)。您可以通过节点下的getComponent方法获取节点上安装的组件。保存脚本后点击预览游戏按钮,可以在浏览器中看到游戏开始后动态生成一颗星星!同理,你可以在游戏中以Prefab为模板动态生成任意预设节点。
加上主角摸星星和收星星的行为。
现在是时候补充一下主角收星行为的逻辑了。这里的重点是星星要能随时得到主角所在节点的位置,从而判断它们之间的距离是否小于可收藏的距离。如何获得主角节点的引用?不要忘记我们之前做的两件事:
游戏组件中有一个名为player的属性,保存着主角节点的引用。每个星星都是在游戏脚本中动态生成的。所以我们只需要在游戏脚本生成星形节点的实例时,将游戏组件的实例发送到星形中并保存即可。之后,我们可以通过game.player随时访问和询问主角节点,让我们打开游戏脚本,添加一句newstar.getcomponent (‘star ‘)。game=this在spawnNewStar方法的末尾;如下所示:
//game . js spawn newstar 3360 function(){//.//临时存储游戏对象newstar.getcomponent (‘star ‘)的引用。游戏=明星组件上的这个;},保存后打开明星脚本。现在我们可以通过使用游戏组件中引用的玩家节点来判断距离。在onLoad方法后添加名为getPlayerDistance和onPicked的方法:
//star . js getplayerdistance 3360 function(){//根据player节点的位置判断距离var player pos=this . game . player . get position();//根据两点的位置计算两点之间的距离var dist=this . node . position . sub(player pos)。mag();返回距离;}、onPicked: function() {//星星收集完毕后,调用游戏脚本中的接口生成新的星星this . Game . spawnnewstar();//然后销毁当前星形节点this . node . destroy();},节点下的getPosition()方法返回该节点在父节点坐标系中的位置(x,y),即Vec2类型的对象。同时调用节点下的destroy()方法销毁节点。
然后在update方法中加入每一帧的判断距离,如果距离小于pickRadius属性指定的收集距离,则执行收集行为:
//star . js update : function(dt){//每帧判断主角与主角之间的距离是否小于集合距离if(this . getplayerdistance()this . pick radius){//调用集合行为this . on picked();返回;}},保存脚本,再次预览测试,按A和D键控制主角左右移动。你可以看到,当控制主角靠近星星时,星星会消失,然后随机位置会生成一颗新的星星!
添加分数
小怪物辛辛苦苦收集星星,没有报酬怎么行?现在我们来补充一下收集星星时增加分数奖励的逻辑和显示。
添加分数文本(标签)
游戏开始时,分数从0开始,每收集到一个星星分数,就会加1。要显示分数,首先创建一个标签节点。在层次管理器中选择画布节点,右键单击并在菜单中选择“新建节点-创建渲染节点-标签(文本)”,画布节点下将按最低顺序创建一个新的标签节点。接下来,我们将通过以下步骤配置此标签节点:
将节点的名称更改为score,并将score节点的位置(位置属性)设置为(0,180)。选择此节点,在属性检查器中编辑标签组件的string属性,并填写Score: 0的文本。将标签组件的字体大小属性设置为50。将assets/mikado_outline_shadow位图字体资源(注意图标是)从资源管理器拖到Label组件的Font属性中,并将文本的字体替换为项目资源中的位图字体。注意:建议Score: 0的文本使用英文冒号,因为在Label组件的String属性中添加位图字体后,中文冒号将无法识别。
完成的效果如下图所示:
在游戏脚本中添加得分逻辑
我们会把得分和更新比分显示的逻辑放到游戏脚本中,打开游戏脚本,开始编辑。首先,在属性块的末尾添加乐谱显示标签的引用属性:
//game.jsproperties3360 {//.//分数标签的参考分数显示3360 {默认3360 NULL,键入:cc。LABEL}},然后在onLoad方法中添加用于计分的变量的初始化:
//game . JSON load 3360 function(){//.//初始化评分this . score=0;},然后在update方法后添加一个名为gainScore的新方法:
//game . js gain score : function(){ this . score=1;//更新scoreDisplay标签this . score display . string=’ score : ‘ this . score的文本;},保存游戏脚本后,返回关卡管理器,选择画布节点,然后将之前添加的分数节点拖放到属性检查器中游戏组件的分数显示属性中。
在星际脚本中调用游戏中的得分逻辑
打开下面的星形脚本,在onPicked方法中添加gainScore的调用:
//star . js on picked 3360 function(){//星星收集完毕,调用游戏脚本中的接口生成新的星星this . Game . spawnnewstar();//调用游戏脚本this.game.gainScore()的评分方法;//然后销毁当前星形节点this . node . destroy();},保存后预览。你可以看到屏幕上方显示的分数在收集星星时会增加!
故障判断和重启
现在我们的游戏已经初具规模,但是无论得多少分,不能失败的游戏都不会给人成就感。现在,我们再加上星星定期消失的行为,当星星消失时,就判定为游戏失败。也就是说,玩家需要在每颗星星消失之前完成收集,并不断重复这个过程,完成游戏的循环。
给星星加上定时消失的逻辑。
打开游戏脚本,在onLoad方法的spawnNewStar调用之前添加计时所需的变量声明:
//game . JSON load 3360 function(){//.//初始化timer this . timer=0;this . star duration=0;//生成新的star this . spawnnewstar();//初始化评分this . score=0;},然后在spawnNewStar方法的最后加上重置计时器的逻辑,其中this.minStarDuration和this.maxStarDuration是我们在开头声明的游戏组件属性,用来指定星星消失时间的随机范围:
//game . js spawnnewstar 3360 function(){//.//重置定时器,随机取一个值this . stardration=this . minstardration math . random()*(this . maxstardration-this . minstardration);this . timer=0;},在更新方法中增加了定时器更新和超时判断的逻辑:
//game . js Update : function(dt){//每帧更新一次计时器,如果超过限制后没有产生新的星星,就会调用游戏失败逻辑if(this . timer this . star duration){ this . game over());返回;} this.timer=dt},最后在gainScore方法后添加gameOver方法,在游戏失败时重新加载场景。
//game . js game over : function(){ this . player . stopalactions();//停止播放器节点的跳转动作cc . director . load scene(‘ game ‘);}新手在这里需要知道的是,cc.director是一个管理你游戏逻辑流程的singleton对象。由于cc.director是单例的,所以不需要调用任何构造函数或创建函数。使用它的标准方法是调用cc.director.methodName()。比如这里的cc.director.loadScene(‘game ‘)就是重新加载游戏场景游戏,也就是重启游戏。节点下的stopAllActions方法是显而易见的,它将使节点上的所有操作无效。
以上,游戏脚本修改完成。保存脚本,然后打开Star脚本。我们需要为消失的星星添加一个简单的视觉提示效果,并在update方法的末尾添加以下代码:
//star . jsupdate 3360 function(){//.//根据游戏脚本中的计时器更新星星的透明度varopacity ratio=1-this.game.timer/this.game.starDuration; var minOpacity=50;this . node . opacity=minOpacity math . floor(opacity ratio *(255-minOpacity));}保存明星剧本,我们的玩法逻辑就全部搞定了!现在点击预览游戏按钮,我们在浏览器里看到的就是一个合格的游戏,有核心玩法,有激励机制,有失败机制。
添加声音效果
虽然很多人玩手游的时候忽略了声音,但是为了让教程中显示的工作流程尽可能完整,我们还是要完成添加音效的任务。
跳跃音效
首先,添加跳跃声音效果,打开播放器脚本,并添加引用声音文件资源的jumpAudio属性:
//Player.js属性3360 {//.//JumpAudio资源3360 {默认3360 null,键入3360cc.audioclip},},然后重写setJumpAction方法,插入一个回调来播放音效,通过添加playJumpSound方法来播放声音:
//player . js setjumption 3360 function(){//jump up var jump up=cc . move by(this . jump duration,cc.v2 (0,this.jumpheight))。easing(cc . easecibizationout());//行踪var jump down=cc . move by(this . jump duration,cc.v2 (0,-this.jumpheight))。easing(cc . easecibizationin());//添加一个回调函数调用我们在action末尾定义的其他方法var callback=cc . call func(this . playjumpsound,this);//不断重复,调用回调播放声音返回cc。永远重复(cc。每次落地动作后的顺序(向上跳、向下跳、回调));}、playjumpsond : function(){//调用声音引擎播放声音cc . audio engine . play effect(this . jumpaudio,false);},这里需要强调的是回调函数的作用。我们先来看看官方对callFunc()方法的定义:
/** * !#en用回调创建动作。* !#zh执行回调函数。* @ method call func * @ param { function } selector * @ param { object }[selector target=null]* @ param { * }[data=null]-data对于函数,它接受所有数据类型。* @ return { action instant } * @ example *//example *//call func不带数据* var finish=cc . call func(this . remove sprite,this);* *//call func with data * var finish=cc . call func(this . removefrompertancleanup,this。_grossini,true);*/cc . call func=function(selector,selectorTarget,data) {返回新的cc。CallFunc(选择器,selectorTarget,data);};我们可以看到callFunc方法可以传入三个参数。第一个参数是方法的选择器,我们可以理解为方法名。第二个参数是对象类型,通常用这个填充。第三个参数是带回的数据,可以是所有数据类型,可以留空。我们还注意到这个方法的返回值是—— ActionInstant,这是一个立即执行的action类。至此,我们可以理解,用callFunc调用回调函数,可以使函数在cc中变成一个动作。这个用法在cc的动作系统中非常实用!比如上面我们把播放声音的函数传入callFunc,赋给callback,使得callback成为一个播放声音的动作。那么我们就可以通过cc.sequence将跳跃和播放声音的动作结合起来,实现每次跳跃都播放音效的功能!
配乐音效
保存玩家脚本后,打开游戏脚本添加得分音效。首先,在属性中添加一个属性来引用声音文件资源:
//Game.js Properties 3360 {//.//乐谱音频资源ScoreAudio 3360 {默认3360 null,键入3360cc.audioclip}},然后插入代码播放gainScore方法中的声音:
//game . js gain score : function(){ this . score=1;//更新scoreDisplay标签this . score display . string=’ score : ‘ this . score . tostring()的文本;//播放配乐音效cc.audioengine.play效果(this.scoreaudio,false);},保存脚本,返回到级别管理器,选择播放器节点,然后将资源管理器中的assets/audio/jump资源拖到播放器组件的Jump Audio属性中。
然后,选择Canvas节点,并将assets/audio/score资源拖到游戏组件的Score Audio属性中。
所以你完了!完成的表单的场景级别和每个关键组件的属性如下:
现在我们可以享受刚刚结束的游戏了。你能得多少分?别忘了,你可以随时在玩家和游戏组件中修改移动控制、星级时长等游戏参数,快速调整游戏难度。修改完组件属性后,需要保存场景,修改的值会被记录下来。
摘要
恭喜你完成了第一个用Cocos Creator制作的游戏!希望这篇快速入门教程能帮助你了解Cocos Creator游戏开发过程中的基本概念和工作流程。如果对编写和学习脚本编程不感兴趣,也可以直接从项目的成品版本中复制编写好的脚本。