cocos creator小游戏案例之橡皮怪

橡皮怪勇闯地下室

主界面

在这里插入图片描述

1. 触摸事件

注册
setInputControl: function() {
    var _this = this
    // 触摸开始
    this.node.on('touchstart', function(e) {}, this)
    // 移动
    this.node.on('touchmove', function(e) {}, this)
    // 结束
    this.node.on('touchend', function(e) {}, this)
    this.node.on('touchcancel', function(e) {}, this)

}
判断左右
this.node.on('touchstart', function(e) {
    var location = e.getLocation()
    // 全局 --转换成--> 相对于this.node
    var locationOfThisNode = this.node.convertToNodeSpaceAR(location)
    if (locationOfThisNode.x < 0) { // 左
        cc.log('左')    
    } else {   // 右
        cc.log('右')
    }
}, this)

2. player

左右移动
toMoveRight: function(e) {
    // player的y坐标: this.player.y
    // 墙宽: this.wallWidth
    var mWidth = this.node.width/2 - this.wallWidth
    var goRight = cc.moveTo(0.2, cc.v2(mWidth, this.player.y))
    this.player.runAction(goRight)
},
toMoveLeft: function(e) {
    var mWidth = -this.node.width/2 + this.wallWidth
    var goLeft = cc.moveTo(0.2, cc.v2(mWidth, this.player.y))
    this.player.runAction(goLeft)
}
旋转
  • 打开3D模式this.player.is3DNode = true

  • 旋转 player在右边时调整朝向

    this.player.eulerAngles = cc.v3(0, 180, 0) // 沿y轴旋转
    // this.player.angle = 180 // 平面旋转
    
判断动作
  • 通过旋转角度判断player位置与点击位置的关系this.player.eulerAngles.y
  • 原地踏步
  • 跳到另一边
toMoveRight: function(e) {
  // player的y坐标: this.player.y
  var goRight = cc.moveTo(0.2, cc.v2(this.node.width/2 - this.wallWidth, this.player.y))
  var goR1 = cc.moveTo(0.1, cc.v2(this.node.width/2 - this.wallWidth - 30, this.player.y))
  var goR2 = cc.moveTo(0.1, cc.v2(this.node.width/2 - this.wallWidth, this.player.y))
  // y轴对称旋转180度
  this.player.eulerAngles = cc.v3(0, 180, 0)
  // 沿y轴旋转的角度 this.player.eulerAngles.y
  if (this.player.eulerAngles.y === 180) {    // player在右, 点击位置在右 ==> 踏步
    var seq = cc.sequence(goR1, goR2)
    this.player.runAction(seq)
  } else {    // player在左,点击位置在右 ==> 跳跃
    this.player.runAction(goRight)
  }
},
toMoveLeft: function(e) {
  var goLeft = cc.moveTo(0.2, cc.v2(-this.node.width/2 + this.wallWidth, this.player.y))
  var goL1 = cc.moveTo(0.1, cc.v2(-this.node.width/2 + this.wallWidth + 30, this.player.y))
  var goL2 = cc.moveTo(0.1, cc.v2(-this.node.width/2 + this.wallWidth, this.player.y))
  if (this.player.eulerAngles.y === 0) {  // player在左, 点击位置在左 ==> 踏步
    var seq = cc.sequence(goL1, goL2)
    this.player.runAction(seq)
  } else { // player在右, 点击位置在左 ==> 跳跃
    this.player.runAction(goLeft)
  }
  this.player.eulerAngles = cc.v3(0, 0, 0)
}

3. 地刺

坐标
  • 声明预制体 --> 实例化 --> 将地刺放入父节点中

    • [0, 1)随机数,>-0.5地刺在右,否则在右
      • 在左时调整朝向
    • 设置坐标
      • x
      • y
        • 初始化八个地刺
        • 每次点击时将新生成的地刺放在第八个地刺位置
    // this.diciDis = 140  // 地刺间隔距离
    
    newDici: function(index) {
      // 实例化一个地刺
      var diciIns = cc.instantiate(this.dici)
      // 将地刺放入界面中
      this.node.addChild(diciIns)
      // 判断位置(左右)
      var randomNum = Math.random()
      if (randomNum >= 0.5) { // 使>=0.5时 地刺生在右边
        // diciIns.eulerAngles = cc.v3(0, 0, 0)
      } else {  // 地刺生在左边
        // 调整朝向
        diciIns.is3DNode = true
        diciIns.eulerAngles = cc.v3(0, 180, 0)
      }
      // 设置坐标(x, y)
      diciIns.setPosition(this.setPosition(randomNum))
    },
    setPosition: function(randomNum) {
      var dX = 0
      var dY = 0
      // X
      if (randomNum >= 0.5) {
        dX = this.node.width / 2 - this.wallWidth
      } else {
        dX = -this.node.width / 2 + this.wallWidth
      }
      // Y
      if(this.diciCount < 8) {    // 初始生成的八个地刺
        dY = this.node.height / 2 - this.diciDis * this.diciCount - this.diciDis*2
      } else {  // 每次点击生成的地刺放在第八个地刺位置
        dY = this.node.height / 2 - this.diciDis * 8 - this.diciDis*2
      }
      // cc.log(randomNum, 'randomNum')
      return cc.v2(dX, dY)
    },
    onLoad: function() {
      this.diciArr = []
      this.setInputControl()
      this.player.is3DNode = true
      this.diciDis = 140  // 地刺间隔距离
      this.player.x = -this.node.width/2 + this.wallWidth
      this.player.y = this.node.height/2 - this.diciDis
      // 初始化八个地刺
      for (var i = 0; i < 8; i++) {
        this.diciCount = i
        this.newDici()
      }
    }
    
移动
  • newDici时将地刺存入数组diciArr

  • 遍历所有地刺,向前

    // 在点击屏幕时调用
    moveDici: function() {
      for (var i = 0; i < this.diciArr.length; i++) {
        var goAhead = cc.moveBy(0.2, cc.v2(0, 140))
        this.diciArr[i].runAction(goAhead)
      }
    }
    

4. 碰撞

  • 添加碰撞组件BoxCollider --> 编辑Group

  • 编辑js组件

    • 获取碰撞管理器 cc.director.getCollisionManager
    • 注册回调, 如果有碰撞则回调 manager.enabled = true
    • 碰撞函数 onCollisionEnter onCollisionStay onCollisionExit
  • 碰撞时游戏结束

    • 在Main.js的onLoad里边预加载游戏结束场景cc.director.preloadScene('GameOver')
    • onCollisionStay 回调函数中切换场景: cc.director.loadScene('GameOver')
    // Dici.js
    cc.Class({
        extends: cc.Component,
        properties: {
        },
        // LIFE-CYCLE CALLBACKS:
        // 三个碰撞函数
        onCollisionEnter (other, self) {
            console.log('enter')
        },
        onCollisionStay (other, self) {
            console.log('stay')
            cc.director.loadScene('GameOver')
        },
        onCollisionExit (other, self) {
            console.log('exit')
        },
        onLoad: function() {
            // 获取碰撞管理器
            var manager = cc.director.getCollisionManager()
            // 注册回调, 如果有碰撞则回调
            manager.enabled = true
            // debug
            manager.enabledDebugDraw = true
        }
    })
    

5. 倒计时

  • 游戏开始时初始化数据

  • 倒计时: this.schedule(this.countDown, 1)

  • 计时结束

    • 移除定时器: this.unscheduleAllCallbacks()
    • 切换至游戏结束场景: cc.director.loadScene('OverScene')
    onLoad: function() {
      this.setInputControl()
      this.player.is3DNode = true
      this.diciDis = 140  // 地刺间隔距离
      this.player.x = -this.node.width/2 + this.wallWidth
      this.player.y = this.node.height/2 - this.diciDis
      // 预加载场景
      cc.director.preloadScene('OverScene')
      this.timeLabel = cc.find('Home/timer/time').getComponent(cc.Label)
      this.scoreLabel = cc.find('Home/score').getComponent(cc.Label)
      this.startGame()
    }
    startGame: function() {
      // 初始化地刺
      this.diciArr = []
      for (var i = 0; i < 8; i++) {
        this.diciCount = i
        this.newDici()
      }
      // 初始化
      this.timeNum = 60
      this.scoreNum = 0
      this.timeLabel.string = '' + this.timeNum
      this.scoreLabel.string = '' + this.scoreNum
      // 倒计时
      this.schedule(this.countDown, 1)
    }
    countDown: function() {
      this.timeNum--
      this.timeLabel.string = '' + this.timeNum
      if (this.timeNum <= 0) { // 时间到
        // 停止计时器
        this.unscheduleAllCallbacks()
        // 游戏结束界面
        cc.director.loadScene('OverScene')
        return
      }
    }
    

6. 分数

  • 点击屏幕时分数加一
  • 将分数存到localStorage中
    • 存储: cc.sys.localStorage.setItem('score', _this.scoreNum)
    • 获取: cc.sys.localStorage.getItem('score')
  • 游戏结束界面获取分数

结束界面

  • 绑定继续游戏按钮事件

    reStartBtn: function() {
      cc.director.loadScene('MainScene')
    },
    onLoad : function() {
      cc.director.preloadScene('MainScene')
    }
    

欢迎界面

  • 按钮闪烁
doWink: function() {
    var scale1 = cc.scaleTo(0.8, 0.9)
    var scale2 = cc.scaleTo(0.8, 1)
    var anim = cc.repeatForever(cc.sequence(scale1, scale2))
    this.startBtn.runAction(anim)
}
  • 开始游戏,切换场景

音乐音效

背景

  • 添加AudioSource组件

###跳跃

  • 声明

    jumpAudio: {
        type: cc.AudioClip,
        default: null
    }
    
  • 播放

    cc.audioEngine.play(_this.jumpAudio, false, 0.2) // (audio, loop, volume)
    

打包到微信小游戏

代码包问题

代码包超过4MB不能发布问题

  • 将打包生成的res文件放线上

  • 修改根目录下main.js里的资源导入路径

    • libraryPath: 'res/import' --> libraryPath: 'http://192.168.../res/import'
    cc.AssetLibrary.init({
        libraryPath: 'http://192.168.../res/import',
        rawAssetsBase: 'http://192.168.../res/raw-',
        rawAssets: settings.rawAssets,
        packedAssets: settings.packedAssets,
        md5AssetsMap: settings.md5AssetsMap,
        subpackages: settings.subpackages
    });
    
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值