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

游戏预览 

开始场景 

搭建开始场景

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

创建游戏脚本

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


 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);
知识兔 

获取代码

关注微信公众号,发送【大炮英雄】,获取代码。

计算机