游戏预览

开始场景

搭建开始场景

摆放一个背景图,在背景图上添加背景地面、开始按钮、4个角色选择按钮、游戏logo。

创建游戏脚本

1. 实现开始按钮的回调,点击开始按钮,跳转到游戏场景。跳转场景方法如下:


cc.director.preloadScene('playScene', function () {cc.director.loadScene('playScene');
});

2. 实现选择角色按钮的回调,点击某个角色时,先将其他角色设置为未选中状态,再将当前选择的角色设为选中状态,最后用cc.sys.localStorage.setItem(“key”,value);方法本地保存选择的角色类型。

3. 在onLoad()方法中,调用cc.sys.localStorage.getItem(“key”);方法获取到本地保存的角色类型,并设置角色按钮的选中状态。

4. 游戏中音效必不可少,点击各个按钮时,都需要播放音效,方法如下:


//播放音效
playSound : function(name, isLoop){cc.loader.loadRes(name, cc.AudioClip, function (err, clip) {if(err){return;}let audioID = cc.audioEngine.playEffect(clip, isLoop);});
},

开始场景和脚本关联

1. 将脚本拖到start场景的属性检查器中,并将脚本中声明的属性和组件关联起来,如下图:

2. 给开始按钮绑定回调事件,选中开始按钮,在属性检查器中,找到Button属性,将ClickEvents值改成1,表示有一个点击事件,再按照如下方式将函数和组件关联起来:

3. 给角色按钮绑定回调,方法和给开始按钮绑定回调完全一样,只是绑定的函数不同。

游戏场景

游戏玩法是控制我方英雄的发炮角度,如果打中敌方英雄就得分,否则会被敌方英雄的炮弹打中,如果我方英雄血量为0则游戏结束。

搭建游戏场景

1. 游戏主界面:包含背景,地面,我方英雄,分数文本,返回主界面按钮。

2. 结算界面:包含遮罩层,最高得分文本,当前得分文本,重新开始按钮,返回主界面按钮。

创建游戏脚本

gamePlay.js脚本是游戏的核心,主要方法如下:

1. 开启物理系统:

cc.director.getPhysicsManager().enabled = true;

2. 设置重力加速度:

cc.director.getPhysicsManager().gravity = cc.v2(0, -640);

3. 添加触摸监听,事件分为TOUCH_START(开始)、TOUCH_MOVE(移动)、TOUCHCANCEL(取消)、TOUCH_END(结束)四个状态,方法如下:

this.node.on(cc.Node.EventType.TOUCH_START, this.onEventStart, this);this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onEventMove, this);this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onEventCancel, this);this.node.on(cc.Node.EventType.TOUCH_END, this.onEventEnd, this);

4. 当开始触摸屏幕时,触发开始的回调onEventStart(),回调中开启定时器,每隔0.03秒角度加1,并改变炮台的角度,方法如下:

//更新炮管角度

updateGunAngle : function(){  this.shootLineImg.active = true;  this._curAngle = 0;  this.gunSchedule = function(){    if (this._curAngle < 90){      this._curAngle += 1;      this.myGunImg.angle = this._curAngle;    }  };  this.schedule(this.gunSchedule, 0.03); },

5. 当结束触摸时,触发结束的回调onEventEnd(),回调中关闭定时器,方法如下:

//停止更新炮管stopGunAngle(){  this.unschedule(this.gunSchedule);  this.shootLineImg.active = false;},

6. 敌人开炮,需要先调整角度再发炮,炮的角度通过敌方子弹和我方英雄的坐标可计算出来,方法如下:

//敌方开炮enemyOpenFire : function(){  //敌方子弹世界坐标  let enemyBulletPos = this._enemyNode.enemyBulletWorldPos();  //我方英雄世界坐标  let myHeroPos = this.myHeroImg.parent.convertToWorldSpaceAR(cc.v2(this.myHeroImg.position.x, this.myHeroImg.position.y + 30));
  //计算夹角  let lenX = Math.abs(enemyBulletPos.x - myHeroPos .x);  let lenY = Math.abs(enemyBulletPos.y - myHeroPos .y);  let angle = Math.atan2(lenY, lenX) * 180 / Math.PI; 
  //设置敌方小火炮的角度  this._enemyNode.setGunAngle(angle); 
  //计算炮运行的距离  let len = Math.sqrt(Math.pow(lenX, 2) + Math.pow(lenY, 2));  this._enemyNode.gunAni(len);  this.playSound("sound/enemyBullet", false);},

7. 更换纹理方法:

//更换纹理setImgTexture : function(str, node){  cc.loader.loadRes(str, cc.SpriteFrame, function (err, spriteFrame) {    if (err) {      cc.error(err.message || err);      return;    }    node.getComponent(cc.Sprite).spriteFrame = spriteFrame;  }.bind(this));},

创建敌人脚本

敌人脚本包含敌人,柱子,敌方炮弹等信息,脚本中的主要方法有:

1. 随机设置柱子的高度:

//调整敌方柱子高度setColumnHight : function(){  //随机获取高度  let y = Math.floor(Math.random() * -250) - 100;  this.cloumn.position = cc.v2(this._winSize.width / 2 + 100, y);},

2. 敌人进出场的动作:

//敌人进场动作comeOnAni : function(){  this.setColumnHight();  let w = Math.floor(Math.random() * (this._winSize.width / 4));  this.cloumn.runAction(cc.sequence(cc.moveTo(1.0, cc.v2(w, this.cloumn.position.y)), cc.callFunc(() =>{     this.enemyHeroImg.active = true;    this.enemyGunImg.active = true;    this.enemyAni();  }, this)));},
//敌方柱子运动enemyMove : function(){  this.enemyHeroImg.active = false;  this.enemyGunImg.active = false;  this.cloumn.runAction(cc.sequence(cc.moveTo(1.0, cc.v2(-this._winSize.width / 2 - 100, this.cloumn.position.y)), cc.callFunc(() =>{    if(this.callBack){      this.callBack();    }   })));},

3. 敌人开炮:

//炮运动gunAni : function(len){  let bulletPos = this.enemyBulletImg.position;  this.enemyBulletImg.runAction(cc.sequence(cc.moveTo(0.3, cc.v2(len, 0)), cc.callFunc(() =>{    if(this.hitHeroCallBack){        this.hitHeroCallBack();    }    this.enemyBulletImg.position = bulletPos;  })));},

创建碰撞脚本

碰撞脚本是给需要做碰撞检测的刚体用的,在碰撞脚本中做碰撞监听,当触发监听后,再调用相应的回调。比如我方子弹需要监听与墙壁,敌人,柱子等物体的碰撞,那么我们先给子弹绑定好碰撞组件,如下图:

再在代码中实现碰撞的回调并保存下来,方法如下:

​​​​​​​

//碰撞监听contactFunction (selfCollider, otherCollider){  if(this.callBack){    this.callBack(selfCollider, otherCollider);  }}, 
contactCallBack (callBack){  this.callBack = callBack;},

最后在碰撞开始的监听中调用回调,方法如下:

onBeginContact ( contact, selfCollider, otherCollider){  if(selfCollider.tag == 0 && otherCollider.tag == 0){    cc.log("onBeginContact...");  //碰撞开始    this.contactFunction(selfCollider, otherCollider);  }},

创建动画脚本

游戏中有英雄角色的等待和走路动作,敌人等待动作,如果在编辑器做动画,编辑的个数比较多,所以我的做法是通过修改纹理达到动画效果,用法是将这个脚本绑定到需要播放动画的节点上,并设置一张大图,方法如下:

使用方法:​​​​​​​

playAni(nameStr, count, dt, isLoop){  this.stopAni();  this.node.getComponent(cc.Sprite).spriteFrame = this.bigImg.getSpriteFrame(nameStr + 0);  let array = [];  for(let i = 0; i < count; i++){    array.push(cc.delayTime(dt));    array.push(cc.callFunc(() =>{      this.node.getComponent(cc.Sprite).spriteFrame = this.bigImg.getSpriteFrame(nameStr + i);    }));  }       
  if(isLoop){    this.node.runAction(cc.repeatForever(cc.sequence(array)));  }  else{    this.node.runAction(cc.sequence(array));  }},

参数分别是图片名称,图片张数,间隔时间,是否循环,调用方法:

this.shieldImg.getComponent("spriteFrameAni").playAni("shield", 4, 0.1, true);
//-------------contact.js------------------//碰撞监听脚本
cc.Class({extends: cc.Component,properties: {},onLoad () {},onDestroy () {},onBeginContact ( contact, selfCollider, otherCollider){if(selfCollider.tag == 0 && otherCollider.tag == 0){cc.log("onBeginContact...");  //碰撞开始this.contactFunction(selfCollider, otherCollider);}},onEndContact (contact, selfCollider, otherCollider){//cc.log("onEndContact...");//碰撞结束 },onPreSolve(contact, selfCollider, otherCollider){//cc.log("onPreSolve...");//碰撞持续,接触时被调用},onPostSolve (contact, selfCollider, otherCollider){//cc.log("onPostSolve...");//碰撞接触更新完后调用,可以获得冲量信息},//碰撞监听contactFunction (selfCollider, otherCollider){if(this.callBack){this.callBack(selfCollider, otherCollider);}},contactCallBack (callBack){this.callBack = callBack;},});//-------------enemy.js------------------
cc.Class({extends: cc.Component,properties: {cloumnNode : cc.Node,cloumn : cc.Node,enemyGunImg : cc.Node,enemyBulletImg : cc.Node,enemyHeroImg : cc.Node,enemyDieParticle : cc.ParticleSystem,},onLoad: function () {this._winSize = cc.winSize;this.enemyHeroImg.active = false;this.enemyGunImg.active = false; },//敌人运动enemyAni : function(){this.enemyHeroImg.getComponent("spriteFrameAni").playAni("enemy", 3, 0.1, true);},//调整敌方柱子高度setColumnHight : function(){//随机获取高度let y = Math.floor(Math.random() * -250) - 100;this.cloumn.position = cc.v2(this._winSize.width / 2 + 100, y);},//敌人进场动作comeOnAni : function(){this.setColumnHight();let w = Math.floor(Math.random() * (this._winSize.width / 4));this.cloumn.runAction(cc.sequence(cc.moveTo(1.0, cc.v2(w, this.cloumn.position.y)), cc.callFunc(() =>{ this.enemyHeroImg.active = true;this.enemyGunImg.active = true;this.enemyAni();}, this)));},//敌方柱子运动enemyMove : function(){this.enemyHeroImg.active = false;this.enemyGunImg.active = false;this.cloumn.runAction(cc.sequence(cc.moveTo(1.0, cc.v2(-this._winSize.width / 2 - 100, this.cloumn.position.y)), cc.callFunc(() =>{if(this.callBack){this.callBack();} })));},//获取敌方子弹的世界坐标enemyBulletWorldPos : function(){let pos = this.cloumn.convertToWorldSpaceAR(cc.v2(this.enemyGunImg.position));return pos;},//设置炮的角度setGunAngle : function(angle){this.enemyGunImg.angle = angle;},//炮运动gunAni : function(len){let bulletPos = this.enemyBulletImg.position;this.enemyBulletImg.runAction(cc.sequence(cc.moveTo(0.3, cc.v2(len, 0)), cc.callFunc(() =>{if(this.hitHeroCallBack){this.hitHeroCallBack();}this.enemyBulletImg.position = bulletPos;})));},//敌方英雄死亡动画enemyDie : function(){this.enemyDieParticle.node.active = true;this.enemyDieParticle.stopSystem();this.enemyDieParticle.resetSystem();//隐藏敌方英雄this.enemyGunImg.active = false;this.enemyHeroImg.active = false;},//播放音效playSound : function(name, isLoop){cc.loader.loadRes(name, cc.AudioClip, function (err, clip) {if(err){return;}var audioID = cc.audioEngine.playEffect(clip, isLoop);});},//运动完成的回调finishCallBack (callBack){this.callBack = callBack;},//打中我方英雄后的回调hitHeroCallBack : function(callBack){this.hitHeroCallBack = callBack;},// called every frameupdate: function (dt) {},
});//-------------gamePlay.js------------------cc.Class({extends: cc.Component,properties: {bgImg : cc.Node,sunImg : cc.Node,moonImg : cc.Node,floorParent : cc.Node,farHouseImg0 : cc.Node,farHouseImg1 : cc.Node,nearHouseImg0 : cc.Node,nearHouseImg1 : cc.Node,farFloorImg0 : cc.Node,farFloorImg1 : cc.Node,nearFloorImg0 : cc.Node,nearFloorImg1 : cc.Node,scoreText : cc.Label,//我方英雄组件heroNode : cc.Node,shootLineImg : cc.Node,myBulletImg : cc.Node,myHeroImg : cc.Node,myGunImg : cc.Node,shieldImg : cc.Node,bloodBar : cc.ProgressBar,heroDieParticle : cc.ParticleSystem,//结束层endLayer : cc.Node,bestScoreText : cc.Label,allScoreText : cc.Label,myBulletPrefab : {default: [],type: cc.Prefab,},enemyPrefab : cc.Prefab,},onLoad: function () {this._winSize = cc.winSize;this._canShooting = true;  //是否能射击this._canContact = true;   //是否检测碰撞this._curScore = 0;  //当前得分this._heroBloodValue = 100;  //当前血量值//打开物理系统cc.director.getPhysicsManager().enabled = true;//cc.director.getPhysicsManager().debugDrawFlags = true;// 重力加速度的配置cc.director.getPhysicsManager().gravity = cc.v2(0, -640);//随机获取一种类型this.randStyle = Math.floor(Math.random() * 100) % 3; cc.sys.localStorage.setItem("gunHeroBgStyle", this.randStyle);//角色类型this.heroType = parseInt(cc.sys.localStorage.getItem("gunHeroType")) || 0;//修改辅助线纹理this.setImgTexture("imageRes/line" + this.heroType, this.shootLineImg);//修改大炮纹理this.setImgTexture("imageRes/gun" + this.heroType, this.myGunImg);//游戏背景this.setImgTexture("bg/bgImg" + this.randStyle, this.bgImg);//太阳图片  if(this.randStyle == 2){this.sunImg.active = false;this.moonImg.active = true;}else{this.moonImg.active = false;this.sunImg.active = true;this.setImgTexture("imageRes/sun" + this.randStyle, this.sunImg);}//远处房子this.setImgTexture("imageRes/house" + this.randStyle, this.farHouseImg0);this.setImgTexture("imageRes/house" + this.randStyle, this.farHouseImg1);//近处房子this.setImgTexture("imageRes/houshSmall" + this.randStyle, this.nearHouseImg0);this.setImgTexture("imageRes/houshSmall" + this.randStyle, this.nearHouseImg1);//远处地面this.setImgTexture("imageRes/floor" + this.randStyle, this.farFloorImg0);this.setImgTexture("imageRes/floor" + this.randStyle, this.farFloorImg1);//近处地面this.setImgTexture("imageRes/gameFloor" + this.randStyle, this.nearFloorImg0);this.setImgTexture("imageRes/gameFloor" + this.randStyle, this.nearFloorImg1);this.nearFloorImg0.zIndex = 5;this.nearFloorImg1.zIndex = 5;//得分this.scoreText.string = "0";this.node.on(cc.Node.EventType.TOUCH_START, this.onEventStart, this);this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onEventMove, this);this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onEventCancel, this);this.node.on(cc.Node.EventType.TOUCH_END, this.onEventEnd, this);//云动画this.yunAni();//创建敌人this.createEnemy();//我方英雄等待动作this.myHeroAni(false);//地方英雄等待动画this._enemyNode.enemyAni();//英雄身上的护盾动画this.shieldImg.getComponent("spriteFrameAni").playAni("shield", 4, 0.1, true);},//云动画yunAni : function(){let curWidth = -this._winSize.width / 2;while(curWidth < this._winSize.width / 2){//随机一个类型let t = Math.floor(Math.random() * 100) % 3;//随机一个高度值let h = Math.random() * (this._winSize.height * 1 / 6) + this._winSize.height * 2 / 8;curWidth = curWidth + Math.random() * 150 + 150;let yunNode = new cc.Node();let yunSp = yunNode.addComponent(cc.Sprite);yunNode.parent = this.floorParent;yunNode.position = cc.v2(curWidth, h);this.setImgTexture("imageRes/yun" + this.randStyle + "_" + t, yunSp);yunNode.runAction(cc.repeatForever(cc.sequence(cc.moveBy(1.0, cc.v2(-20, 0)), cc.callFunc(() =>{if(yunNode.position.x < -this._winSize.width / 2 - 100){yunNode.position = cc.v2(this._winSize.width / 2 + 100, yunNode.position.y);}}))));}},//创建敌人createEnemy : function(){let node = cc.instantiate(this.enemyPrefab);node.position = cc.v2(0, -110);node.parent = this.floorParent;this._enemyNode = node.getComponent("enemy");this._enemyNode.comeOnAni();this._enemyNode.finishCallBack(()=>{//可检测碰撞this._canContact = true;//设置为可发炮this._canShooting = true;node.removeFromParent();node = null;this.createEnemy();});this._enemyNode.hitHeroCallBack(()=>{this._heroBloodValue = this._heroBloodValue - 25;if(this._heroBloodValue <= 0){this.playSound("sound/heroDie", false);this._heroBloodValue = 0;this.myHeroDie();//显示结算界面this.gameOver();}else{this.playSound("sound/enemyDie", false);this.setBloodValue();//还原炮的角度this.myGunImg.angle = 0;//设置为允许开炮this._canShooting = true;this._canContact = true;}});},//更新炮管角度updateGunAngle : function(){this.shootLineImg.active = true;this._curAngle = 0;this.gunSchedule = function(){if (this._curAngle < 90){this._curAngle += 1;this.myGunImg.angle = this._curAngle;}};this.schedule(this.gunSchedule, 0.03);},//停止更新炮管stopGunAngle(){this.unschedule(this.gunSchedule);this.shootLineImg.active = false;},//给自己的子弹绑定刚体setBulletBody : function(){//创建子弹this.bulletNode = cc.instantiate(this.myBulletPrefab[this.heroType]);this.bulletNode.parent = this.myGunImg;this.bulletNode.position = this.myBulletImg.position;let bulletSp = this.bulletNode.getComponent("contact");bulletSp.contactCallBack((selfCollider, otherCollider) => {if(!this._canContact){return;}this.playSound("sound/openFire", false);this._canContact = false;//停止子弹监听this.unschedule(this.bulletfun);let bodyGroup0 = selfCollider.node.group;let bodyGroup1 = otherCollider.node.group;//子弹打到地面if((bodyGroup0 == "heroBullet" && bodyGroup1 == "floor") || (bodyGroup0 == "floor" && bodyGroup1 == "heroBullet")){this.node.runAction(cc.sequence(cc.delayTime(0.5),cc.callFunc(() =>{this.bulletNode.removeFromParent();this.bulletNode = null;this.enemyOpenFire();})));}//子弹打到柱子if((bodyGroup0 == "heroBullet" && bodyGroup1 == "column") || (bodyGroup0 == "column" && bodyGroup1 == "heroBullet")){this.node.runAction(cc.sequence(cc.delayTime(0.5),cc.callFunc(() =>{this.bulletNode.removeFromParent();this.bulletNode = null;this.enemyOpenFire();})));}//子弹打到敌人if((bodyGroup0 == "heroBullet" && bodyGroup1 == "enemy") || (bodyGroup0 == "enemy" && bodyGroup1 == "heroBullet")){this._enemyNode.enemyDie();this.node.runAction(cc.sequence(cc.delayTime(0.3),cc.callFunc(() =>{this.bulletNode.removeFromParent();this.bulletNode = null;this.updateScore();this.myHeroAni(true);this.myHeroScaleAni();this.gameBgAni();this._enemyNode.enemyMove();})));}});},//我方英雄运动myHeroAni : function(isRun){if(isRun){this.myHeroImg.getComponent("spriteFrameAni").playAni("heroRun" + this.heroType + "_", 5, 0.06, true);}else{this.myHeroImg.getComponent("spriteFrameAni").playAni("heroWait" + this.heroType + "_", 3,  0.1, true);}},//我方英雄缩放效果myHeroScaleAni : function(){this.heroNode.runAction(cc.sequence(cc.scaleTo(1.0, 1.1), cc.scaleTo(1.0, 1.0)));},//背景运动gameBgAni : function(){//远处房子let fw = this.farHouseImg0.width;this.farHouseImg0.runAction(cc.sequence(cc.moveBy(2.0, cc.v2(-200, 0)), cc.delayTime(0.1), cc.callFunc(() =>{if(this.farHouseImg0.position.x <= -fw - this._winSize.width / 2){this.farHouseImg0.position = cc.v2(this.farHouseImg1.position.x + fw, this.farHouseImg0.position.y);}this.myHeroAni(false);})));this.farHouseImg1.runAction(cc.sequence(cc.moveBy(2.0, cc.v2(-200, 0)), cc.delayTime(0.1), cc.callFunc(() =>{if(this.farHouseImg1.position.x <= -fw - this._winSize.width / 2){this.farHouseImg1.position = cc.v2(this.farHouseImg0.position.x + fw, this.farHouseImg1.position.y);}})));//近处房子let nw = this.nearHouseImg0.width;this.nearHouseImg0.runAction(cc.sequence(cc.moveBy(2.0, cc.v2(-300, 0)), cc.delayTime(0.1), cc.callFunc(() =>{if(this.nearHouseImg0.position.x <= -nw - this._winSize.width / 2){this.nearHouseImg0.position = cc.v2(this.nearHouseImg1.position.x + nw, this.nearHouseImg0.position.y);}})));this.nearHouseImg1.runAction(cc.sequence(cc.moveBy(2.0, cc.v2(-300, 0)), cc.delayTime(0.1), cc.callFunc(() =>{if(this.nearHouseImg1.position.x <= -nw - this._winSize.width / 2){this.nearHouseImg1.position = cc.v2(this.nearHouseImg0.position.x + nw, this.nearHouseImg1.position.y);}})));//远处地面let ffw = this.farFloorImg0.width;this.farFloorImg0.runAction(cc.sequence(cc.moveBy(2.0, cc.v2(-400, 0)), cc.delayTime(0.1), cc.callFunc(() =>{if(this.farFloorImg0.position.x <= -ffw - this._winSize.width / 2){this.farFloorImg0.position = cc.v2(this.farFloorImg1.position.x + ffw, this.farFloorImg0.position.y);}})));this.farFloorImg1.runAction(cc.sequence(cc.moveBy(2.0, cc.v2(-400, 0)), cc.delayTime(0.1), cc.callFunc(() =>{if(this.farFloorImg1.position.x <= -ffw - this._winSize.width / 2){this.farFloorImg1.position = cc.v2(this.farFloorImg0.position.x + ffw, this.farFloorImg1.position.y);}})));//近处地面let nfw = this.nearFloorImg0.width;for(let i = 0; i < 100; i++){this.nearFloorImg0.runAction(cc.sequence(cc.delayTime(0.02 * i), cc.callFunc(() =>{if(i % 9 == 0){this.playSound("sound/walk", false);}let pX1 = this.nearFloorImg0.position.x - 4;this.nearFloorImg0.position =  cc.v2(pX1, this.nearFloorImg0.position.y);let pX2 = this.nearFloorImg1.position.x - 4;this.nearFloorImg1.position = cc.v2(pX2, this.nearFloorImg1.position.y);if(pX1 <= -nfw - this._winSize.width / 2){this.nearFloorImg0.position = cc.v2(this.nearFloorImg1.position.x + nfw, this.nearFloorImg0.position.y);}if(pX2 <= -nfw - this._winSize.width / 2){this.nearFloorImg1.position = cc.v2(this.nearFloorImg0.position.x + nfw, this.nearFloorImg1.position.y);}})));}},//敌方开炮enemyOpenFire : function(){//敌方子弹世界坐标let enemyBulletPos = this._enemyNode.enemyBulletWorldPos();//我方英雄世界坐标let myHeroPos = this.myHeroImg.parent.convertToWorldSpaceAR(cc.v2(this.myHeroImg.position.x, this.myHeroImg.position.y + 30));//计算夹角let lenX = Math.abs(enemyBulletPos.x - myHeroPos .x);let lenY = Math.abs(enemyBulletPos.y - myHeroPos .y);let angle = Math.atan2(lenY, lenX) * 180 / Math.PI;//设置敌方小火炮的角度this._enemyNode.setGunAngle(angle);//计算炮运行的距离let len = Math.sqrt(Math.pow(lenX, 2) + Math.pow(lenY, 2));this._enemyNode.gunAni(len);this.playSound("sound/enemyBullet", false);},//刷新英雄的血量setBloodValue : function(){//设置盾牌透明度let p = this._heroBloodValue / 100;this.shieldImg.opacity = Math.floor(p * 255);//设置血量进度this.bloodBar.progress = p;},//我方英雄死亡动画myHeroDie : function(){this.heroDieParticle.node.active = true;this.heroDieParticle.stopSystem();this.heroDieParticle.resetSystem();//隐藏我方英雄this.heroNode.active = false;},//游戏结束gameOver : function(){this.node.runAction(cc.sequence(cc.delayTime(1.0),cc.callFunc(() =>{//显示结算界面this.endLayer.active = true;//显示最高得分let bestScore = parseInt(cc.sys.localStorage.getItem("gunBestScore")) || 0;if(this._curScore > bestScore){this.bestScoreText.string = this._curScore;cc.sys.localStorage.setItem("gunBestScore", this._curScore);}else{this.bestScoreText.string = bestScore;}//显示当前得分this.allScoreText.string = this._curScore;})));},// 按钮的回调exitCallBack : function(event, customEventData){this.playSound("sound/click", false);cc.director.preloadScene('start', function () {cc.director.loadScene('start');});},//重新开始回调refreshCallBack : function(event, customEventData){this.playSound("sound/click", false);cc.director.preloadScene('playScene', function () {cc.director.loadScene('playScene');});},//屏幕触摸回调onEventStart : function(event){if(!this._canShooting){return;}cc.log("onEventStart");this.updateGunAngle();},onEventMove : function(event){cc.log("onEventMove");},onEventEnd : function(event){if(!this._canShooting){return;}cc.log("onEventEnd");this.playSound("sound/heroBullet", false);this._canShooting = false;this.stopGunAngle();this.setBulletBody(this.myBulletImg);let x = 5000; //2号子弹体积较大,需要更大的力if(this.heroType == 1){x = 7000; }//通过角度计算力度let y = x * Math.tan(Math.abs(this._curAngle) * (Math.PI / 180)); //给子弹设置冲量this.bulletNode.getComponent(cc.RigidBody).applyForceToCenter(cc.v2(x, y));let curPos = this.bulletNode.position;let lastPos = curPos;this.bulletfun = function(){curPos = this.bulletNode.position;//计算角度let lenX = curPos.x - lastPos.x;let lenY = 0;let r = 0;if(curPos.y < lastPos.y){ //向上运动lenY = curPos.y - lastPos.y;r = Math.atan2(lenY, lenX) * 180 / Math.PI;}else{   //向下运动lenY = lastPos.y - curPos.y;r = -1 * Math.atan2(lenY, lenX) * 180 / Math.PI;}lastPos = curPos;this.bulletNode.angle = r;};this.schedule(this.bulletfun, 0.1);},onEventCancel : function(event){this.onEventEnd(event);},//刷新得分updateScore : function(){this._curScore += 1;this.scoreText.string = this._curScore;this.playSound("sound/addScore", false);},//更换纹理setImgTexture : function(str, node){cc.loader.loadRes(str, cc.SpriteFrame, function (err, spriteFrame) {if (err) {cc.error(err.message || err);return;}node.getComponent(cc.Sprite).spriteFrame = spriteFrame;}.bind(this));},//播放音效playSound : function(name, isLoop){cc.loader.loadRes(name, cc.AudioClip, function (err, clip) {if(err){return;}var audioID = cc.audioEngine.playEffect(clip, isLoop);});},update: function (dt) {},
});//-------------gameStart.js------------------cc.Class({extends: cc.Component,properties: {heroBtn : {default: [],type: cc.Button,},},onLoad: function () {//设置当前选择的英雄let tag = parseInt(cc.sys.localStorage.getItem("gunHeroType") || 0);for(let i = 0; i < 4; i++){let hero = this.heroBtn[i];hero.interactable = true;}let hero = this.heroBtn[tag];hero.interactable = false;},//开始按钮回调startBtnCallBack : function(event, customEventData){this.playSound("sound/click", false);//显示游戏界面cc.log("startBtnCallBack"); cc.director.preloadScene('playScene', function () {cc.director.loadScene('playScene');});},//选择英雄按钮的回调selectHeroCallBack : function(event, customEventData){this.playSound("sound/select", false);let tag = parseInt(customEventData);for(let i = 0; i < 4; i++){let hero = this.heroBtn[i];hero.interactable = true;}let hero = this.heroBtn[tag];hero.interactable = false;//保存当前选择的英雄cc.sys.localStorage.setItem("gunHeroType", tag);},//播放音效playSound : function(name, isLoop){cc.loader.loadRes(name, cc.AudioClip, function (err, clip) {if(err){return;}let audioID = cc.audioEngine.playEffect(clip, isLoop);});},// called every frameupdate: function (dt) {},
});//-------------spriteFrameAni.js------------------cc.Class({extends: cc.Component,properties: {bigImg : cc.SpriteAtlas,},onLoad () {},playAni(nameStr, count, dt, isLoop){this.stopAni();this.node.getComponent(cc.Sprite).spriteFrame = this.bigImg.getSpriteFrame(nameStr + 0);let array = [];for(let i = 0; i < count; i++){array.push(cc.delayTime(dt));array.push(cc.callFunc(() =>{this.node.getComponent(cc.Sprite).spriteFrame = this.bigImg.getSpriteFrame(nameStr + i);}));}if(isLoop){this.node.runAction(cc.repeatForever(cc.sequence(array)));}else{this.node.runAction(cc.sequence(array));}},stopAni(){this.node.stopAllActions();},onDestroy () {},
});

感谢:

本文转载自 https://mp.weixin.qq.com/s/K932G6FvIE-5foQGgKraug 这篇文章,这里感谢原作者对于技术的分享。

下载:

本文章源码和资源下载地址

cocos creator实例--Cocos Creator实现的 大炮英雄 游戏相关推荐

  1. cocos creator实例--Cocos Creator 3D开发 投篮 小游戏

    效果预览 游戏介绍 ● 点击屏幕,根据按住屏幕的时间,进行蓄力,时间越短,发出去的力越小,时间越长,发出去的力越大,超过了最大力,再次从最小里开始,球从篮筐中穿过得1分,否则视为不得分,由于做的是de ...

  2. 手把手教你用 Cocos Creator 实现《大炮英雄》

    个人简介 一枚小工,多年 Cocos2d-x 和 Cocos Creator 游戏开发工程师.现阶段,主要在 Cocos Creator 环境下用 JS  和 TS 进行项目开发.19 年 7 月份开 ...

  3. cocos creator实例--实现FlappyBird游戏的基本功能 | 附代码

    FlappyBird是早期的早IOS上的一款非常受欢迎的像素游戏. 游戏玩法: 点击屏幕控制小鸟上下飞行:小鸟在飞行的过程中,碰撞到管子就结束游戏,飞过一根管子分数加1: 游戏效果: 实现逻辑介绍: ...

  4. 等了那么久,终于等到新游戏啦!大炮英雄Cocos Creator实现,关注获取代码!

    1 1 游戏预览 1 2 开始场景 搭建开始场景 摆放一个背景图,在背景图上添加背景地面.开始按钮.4个角色选择按钮.游戏logo. 创建游戏脚本 1. 实现开始按钮的回调,点击开始按钮,跳转到游戏场 ...

  5. cocosc++怎么打印_Cocos Creator实现大炮英雄,附代码!

    游戏预览 ​ 开始场景 ​ 搭建开始场景 摆放一个背景图,在背景图上添加背景地面.开始按钮.4个角色选择按钮.游戏logo. 创建游戏脚本 1. 实现开始按钮的回调,点击开始按钮,跳转到游戏场景.跳转 ...

  6. linux 64位 安装qt creator .run,Qt Creator安装

    Qt Creator安装 Linux IDE Tools Download QT 找到需要的包下载. Qt Creator PS: Qt Creator 3.4.2版本之后的版本需要注册信息. Ubu ...

  7. cocos creator实例--CocosCreator实现的 解救人质 游戏,学会碰撞检测

    游戏开发中,碰撞检测无处不在,今天就通过一个简单的小游戏教你学会如何在 Cocos Creator 中进行碰撞检测.配合官方文档学习效果更加(官方文档传送门:https://docs.cocos.co ...

  8. cocos creator实例--3D 足球

    体育类游戏,3D 足球射门 ,Cocos Creator 3D 实现,附源码! 效果预览 游戏介绍 点击屏幕,松开手指,足球就会被踢出去,还缺少力度和方向控制,同时也缺少力度和方向的界面展现,后期会继 ...

  9. Cocos Creator实例-制作抽奖池

    出现空白,请点击下方[] 转载地址:https://blog.csdn.net/u011607490/article/details/82701325 [预览效果](https://saber2pr. ...

最新文章

  1. 229页,CMU博士张浩毕业论文公布,探索机器学习并行化的奥秘
  2. [Android] Git组件化部署
  3. 趣学python3(28)-pygame-蛇身随机运动(可gameover )
  4. webService学习记录
  5. sql删除语句_推荐强大开源的数据库SQL语句审核平台,再也不用担心删除跑路了!...
  6. Python实现鸢尾花数据集分类问题——基于skearn的LogisticRegression
  7. Android 自定义相机
  8. python sys模块详解_python中os和sys模块的区别与常用方法总结
  9. python 3.X中打包二进制数据存储字符串出错原因分析
  10. 计算机5800计算道路标高程序,强大的高速公路坐标高程计算软件
  11. Echarts图表没数据的时候,用图片代替暂无数据(图片自适应)
  12. 要大容量有福了 Surface P4拆解可更换SSD!
  13. 周立功USBCAN-II的Python调用
  14. 电路设计与仿真各种类软件工具介绍
  15. 加拿大教授 武 计算机,加拿大卡尔加里大学Yingxu Wang教授访问计算机学院
  16. hash和history路由的区别
  17. 数据分析神器Alteryx
  18. 使用树莓派搭建直播平台实现b站实时直播
  19. 骁龙8+参数 骁龙8+什么水平 骁龙8+处理器怎么样
  20. 非法指令 (核心已转储) 彻底解决方案

热门文章

  1. 2021年危险化学品经营单位安全管理人员考试内容及危险化学品经营单位安全管理人员复审考试
  2. 酱香型白酒有哪几种品牌(原创图文)
  3. 模拟信号载波数字信息——新PCM编码
  4. 我不怕千万人阻挡,只怕自己投降
  5. 21次CCF认证——期末考试的阈值
  6. 【动手学树莓派】案例实操:点亮你的第一个LED(重点)
  7. 微信投票项目开发--ssm框架
  8. VMware虚拟机配置公网ip
  9. 全网最全,项目管理工具大合集!
  10. 关闭php.ini中register_globals,深入了解 register_globals (附register_globals=off 网站打不开的解决方法)...