橡皮怪勇闯地下室
主界面
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() } }
- [0, 1)随机数,
移动
-
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 } })
- 在Main.js的onLoad里边预加载游戏结束场景
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 });