要点
- UI界面重构:可以把设计稿作为最底层节点,逐步把节点对齐设计稿,这样可以免计算节点位置。
- 使用 VS Code 激活脚本编译(快捷键ctrl+p):配置地址
- 少使用
active
属性,使用其会触发递归遍历场景,开销较大,可以通过设置opacity
,scale
,或者修改位移达到隐藏和显示的效果 - Label文字组件添加描边:LabelOutline组件
- 对象浅拷贝与深拷贝:
浅拷贝:
var obj1 = {name:'lily',age:12}
var obj2 = obj1
obj2.age = 13 //obj1,obj2的age都变成13
深拷贝:
function copy(obj){
var newObj = {}
for(var attr in obj){
newObj[attr] = obj[attr]
}
return newObj
}
var obj1 = {name:'lily',age:12}
var obj2 = copy(obj1)
obj2.age = 13
- loading的制作:
1.将`cc.Sprite`组件的`type`属性改成`FILLED`
横向loading:
fillType: HORIZONTAL
fillStart:0 //从左边开始
fillRange:0 //填充的百分比,0~1
扇形loading:
fillType: RIDICAL //扇形
fillCenter:(0.5,0.5)//中心点开始
fillStart:0.25 //最上边
fillRange:0 //填充的百分比,负为顺时针,正为逆时针
扇形讲解图:
^y
0.25|
0.375 ----|---0.125
| | |
0.5---|---|---|0----->x
| | |
0.625----|---0.875
0.75
2.通过脚本修改`fillRange`属性即可
cc.loader.onProgress = (completedCount, totalCount, item) => {
const progress = (completedCount / totalCount).toFixed(2)
// 顺时针
this.loading.getComponent('cc.Sprite').fillRange = -progress
}
}
锚点anchor:左下角是(0,0),右上角是(1,1)
当在对战游戏中出现各种动画时,譬如:2s后根据对方或者自己开始某个动画,倘若一开始回合属于对手,该动画不应该在自己回合出现。但在2s的时间内对手已经完成自己的回合,此时回合到自己,这时2s后这个动画就认为一开始是自己的回合,导致动画执行错误,此时,需要添加一些判断条件,是否开始了一回合,以防止在某段时间内参数改变导致动画出错。
随着新场景的切换,内存占用就会不断上升。除了使用
cc.loader.release
等API来精确释放不使用的资源,我们还可以使用场景的自动释放功能,在场景属性管理器
中设置自动释放资源
选项。判断是在小游戏内还是app的webview内:
cc.sys.isBrowser
-
谷歌浏览器跨域调试:要完全退出chrome浏览器后,新建一个目录用来存放谷歌调试文件,在终端输入命令:
open -n /Applications/Google\ Chrome.app/ --args --disable-web-security --user-data-dir=/Users/${你的用户名}/${新建的目录路径及名称}
- 对于打包web以及其他平台后,修改页面loading时出现的cocos creator官方的loading样式,修改该样式的方法(mac中,windows原理一样):
1.右键点击cocos creator软件选择“打开包内容”
2.去到文件路径路径:Contents/Resources/static/build-templates/shares/下修改style-mobile.css对应样式
新建资源和删除资源要从cocos creator中进行操作,不要在vs code编辑器中操作,因为在vs code中操作删除只是删除了一个文件,没有把相应的.meta文件删掉。
碰撞检测
a.在编辑器中添加Collider
,根据物体形状进行选择,使用矩形,圆形还是多边形碰撞
b.在 项目-项目设置-分组管理 中添加分组,然后勾选会进行碰撞的组,例如 灯 和 人,然后在编辑器中的Node中的Group中选择相对应的碰撞分组
c.给碰撞对象绑定组件,并在组件中添加碰撞检测代码,并做相应碰撞效果处理:
onCollisionEnter (other, self) {
console.log('on collision enter')
},
onCollisionStay (other, self) {
console.log('on collision stay')
},
onCollisionExit (other, self) {
console.log('on collision exit')
}
d.并开启碰撞检测:
this.manager = cc.director.getCollisionManager()
// 开启碰撞检测
this.manager.enabled = true
// 开启碰撞边缘绘制调试
manager.enabledDebugDraw = true
// 开启包围盒绘制调试
manager.enabledDrawBoundingBox = true
e.如果需要去掉相同预制节点中不需要进行碰撞检测的节点,可以指定节点关闭
node.getComponent(cc.CircleCollider).enabled = false
- 两人赛跑之间的位移差视觉处理:对不同物体选择不同的参照物
a.当我停止对手在跑的时候,我与背景相对静止状态,对手向前跑
b.当我跑的并且对手也在跑的时候,我和对手相对静止
c.当我跑,对手停止的时候,对手和背景相对静止
难点
- 几个场景公用一条websocket连接:建立ws模块,在游戏逻辑模块进行托管处理
// ws模块:
const WS = {
ws: null,
wsUrl: null
},
_setWsCloseFunc: function () {},
_setOpenFunc: function () {},
_setMessageFunc: function () {}
}
// 连接websocket
WS._createWebSocket = function (url) {
try {
this.ws = new WebSocket(url)
this._initEventHandle()
}
catch (e) {
console.log('catch', e)
}
}
// websocket事件
WS._initEventHandle = function () {
this.ws.onclose = () => {
this._setWsCloseFunc()
}
this.ws.onerror = (err) => {
}
this.ws.onopen = () => {
this._setOpenFunc()
}
this.ws.onmessage = (event) => {
this._setMessageFunc()
}
}
module.exports = WS
// 游戏逻辑模块
import WS from './ws'
cc.Class({
extends: cc.Component,
properties: {
},
onLoad () {
},
start () {
WS._setOpenFunc = this._setOpenFunc.bind(this)
WS._setMessageFunc = this._setMessageFunc.bind(this)
WS._setWsCloseFunc = this._setWsCloseFunc.bind(this)
},
// onclose
_setWsCloseFunc () {
},
// onopen
_setOpenFunc () {
},
// onmessage
_setMessageFunc () {
},
})
- 弹窗事件穿透:对遮罩层添加默认事件
node.on(cc.Node.EventType.TOUCH_START, () => { })
ios web中不能自动播放音频(浏览器的限制策略),必须手动触发事件播放,解决此问题,在微信中,需要用WeixinJSBridge:
WeixinJSBridge.invoke('getNetworkType', {}, (e)=> {这里执行播放音乐});
creator中开启音乐的时候默认场景间会共享这个音乐,如果需要跨场景关闭音乐,可全局保存一个audioId,用来关闭
解决多次点击动画显示问题:例如:动物弹起和坐下是两个位置变化的动画,弹起显示可移动方向箭头,如果多次点击,可能会造成动画错乱现象,可以定义好在某个动作在进行时,stop其他动画。
对于棋盘类游戏,一般分别定义一个
二维数组
存储棋盘信息,一个二维数组保存棋盘UI信息,通过更新二维数组信息,以更新界面UIiphoneX以及高屏适配问题:在设计分辨率使用
FIT HEIGHT
模式的前提下,采用整体缩放根节点的方式适配:(设计分辨率在720*1280前提下,在各种设备下,高始终是1280,宽度小于720时缩放canvas)
this.windowRatio = this.node.width / 720
if (this.node.width < 720) {
this.node.scale = this.windowRatio
}
- h5压后台游戏停止导致时间停滞问题:
a.在自己回合的时候压后台,利用setTimeout递归控制时间,每一秒进行时间设置的时候都记录两个时间戳,对这两个时间戳进行相减,如果为1,则时间正确,否则用realTime=timer - timeStamp
...
this._controlTime(turn, timer)
...
_controlTime (turn, timer) {
timer--
const timeStamp1 = Date.parse(new Date()) / 1000
setTimeout(() => {
const timeStamp2 = Date.parse(new Date()) / 1000
const timeStamp = parseInt(timeStamp2 - timeStamp1)
let realTime = 0
if (timeStamp === 1) {
realTime = timer
}
else {
realTime = timer - timeStamp
}
console.log(timeStamp, realTime)
this._controlTime(turn, realTime)
}, 1000)
}
b.在对方回合压后台,一开始记录连接ws的时候用后台的时间戳与本地时间戳做一个校准,表示服务器与客户端相差多少时间deltaTimer,在每个回合变换时间的时候,用后台的时间戳与本地时间戳和矫正时间戳做比较,设置正确的timer。
timer = serviceTimer - localTimer - deltaTimer