使用cocos creator制作小游戏总结

要点

  • UI界面重构:可以把设计稿作为最底层节点,逐步把节点对齐设计稿,这样可以免计算节点位置。
  • 使用 VS Code 激活脚本编译(快捷键ctrl+p):配置地址
  • 少使用active属性,使用其会触发递归遍历场景,开销较大,可以通过设置opacityscale,或者修改位移达到隐藏和显示的效果
  • 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 -a "Google Chrome" --args --disable-web-security —user-data-dir

  • 对于打包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信息,通过更新二维数组信息,以更新界面UI

  • iphoneX以及高屏适配问题:在设计分辨率使用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

你可能感兴趣的:(使用cocos creator制作小游戏总结)