前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ByteEdu.Com教育平台--游戏前端架构分析

ByteEdu.Com教育平台--游戏前端架构分析

作者头像
李海彬
发布2020-04-07 18:41:32
6370
发布2020-04-07 18:41:32
举报
文章被收录于专栏:Golang语言社区Golang语言社区

框架引擎:cocos creator

编程语言:JavaScript

架构目录结构:

下面我们以UIManager为例子,整体代码如下:

代码语言:javascript
复制
let Effects = {
    "NoEffect": { show: (layer) => { }, hide: (layer, finish) => { finish() }, },
}

cc.Class({
    extends: cc.Component,

    properties: {
        uiParent: cc.Node,
        mask: cc.Node, // 半透明屏蔽层
        tipTempNode: cc.Node,

        model: { // for MVC
            visible: false,
            get: function () {
                return this._model
            }
        }
    },

    onLoad: function () {
        window.UIMgr = this
        this._model = {
            prefabs: {},
            cache: {}, // layers cache
            stack: [], // layers stack
            urls: [],
        }

        this.mask.parent = this.uiParent
        this.mask.active = false
    },

    checkIsLoaded: function (key) {
        return !!this.model.prefabs[key]
    },

    syncLoad: function (key, cb) {
        cb = cb || function () { }

        let subs = key.split(':')
        let url = (subs.length == 2) ? `SubModules/${subs[0]}/prefabs/ui/${subs[1]}` : `Master/prefabs/ui/${key}`
        if (this.model.prefabs[key]) {
            cb()
        } else {
            cc.loader.loadRes(url, (err, prefab) => {
                if (err) {
                    return cc.log(err)
                }
                this.model.prefabs[key] = prefab
                this.model.urls.push(url)
                collectMgr.register(url)
                cb()
            })
        }
    },

    // usage: UIMgr.show({multi:true, effect:'MoveFromLeft', name:"MessageBox"}, ...)
    // usage: UIMgr.show("MessageBox", ...)
    show: function (name) { // params: multi, effect
        if (!name) return;

        let args = Array.prototype.slice.call(arguments)
        let params = {}
        args.splice(0, 1)

        if (typeof (name) != 'string') {
            params = name || {}
            name = params.name
            if (!name) return;
        }

        let setupLayer = (layer) => {
            let count = this.model.stack.push(layer)
            layer.node.zIndex = count * 2 + 2
            layer.node.parent = this.uiParent
            layer.effect = params['effect'] ? Effects[params['effect']] : Effects['NoEffect']
            layer.effect.show(layer)
            if (layer.node.onenter) {
                layer.node.onenter.apply(null, args)
            }
        }

        this.syncLoad(name, (url) => {
            cc.log('show ', name)

            if (params.multi || this.model.cache[name] == null) {
                let layer = {
                    name: name,
                    node: cc.instantiate(this.model.prefabs[name]),
                    pfbURL: url,
                }

                this.model.cache[name] = layer
                setupLayer(layer)
            } else {
                let layer = this.bringToTop(name)
                if (layer) { // 单个实例且此实例已经在显示中
                    if (layer.node.onenter) {
                        layer.node.onenter.apply(null, args)
                    }
                } else {
                    layer = this.model.cache[name]
                    setupLayer(layer)
                }
            }

            this.resetMask()
        })
    },

    bringToTop: function (name) {
        for (let i = 0; i < this.model.stack.length; i++) {
            let layer = this.model.stack[i]
            if (layer.name == name) {
                this.model.stack.splice(i, 1)
                this.model.stack.push(layer)
                return layer
            }
        }
        return null
    },

    topName: function () {
        return this.model.stack.length == 0 ? "" : this.model.stack[this.model.stack.length - 1].name
    },

    topNode: function () {
        return this.model.stack.length == 0 ? "" : this.model.stack[this.model.stack.length - 1].node
    },

    pop: function () {
        if (this.model.stack.length > 0) {
            this.close(this.model.stack[this.model.stack.length - 1].node)
        }
    },

    close: function (node) {
        if (node instanceof cc.Component) {
            node = node.node
        } else if (typeof (node) == 'string') {
            if (this.model.cache[node]) {
                node = this.model.cache[node].node
            } else {
                return
            }
        }

        let found = null
        for (let i = 0; i < this.model.stack.length; i++) {
            let layer = this.model.stack[i]
            if (layer.node == node) {
                this.model.stack.splice(i, 1)[0]
                found = layer
                break
            }
        }

        if (!found) {
            return
        }

        found.effect.hide(found, () => {
            found.node.parent = null
            this.resetMask()
        })
    },

    clear: function () {
        this.model.stack.forEach((layer) => {
            layer.node.parent = null
        })

        if (globalCfg.memoryCollectImmediate) {
            this.model.urls.forEach((url) => {
                collectMgr.release(url)
            })
        }

        this.model.stack.length = 0
        this.model.urls.length = 0
        this.model.cache = {}

        this.resetMask()
    },

    resetMask: function () {
        let count = this.model.stack.length
        this.mask.active = (count != 0)
        this.mask.zIndex = count * 2 + 1
    },

    showTip: function (text) {
        let node = cc.instantiate(this.tipTempNode)
        node.active = true;
        node.parent = this.tipTempNode.parent
        node.getChildByName('value').getComponent(cc.Label).string = text

        node.Run(
            cc.delayTime(2),
            cc.fadeOut(0.5),
            cc.callFunc(() => {
                node.parent = null
            })
        )
    },
});

游戏中的调用:

代码语言:javascript
复制
    UIMgr.show('MessageBox', '确定解散吗? 10S后自动取消', 'ok|cancel', (op) => {
            let agreeBool = false
            if (op == 'ok') {
                agreeBool = true
                let C2GS_OutProto = {
                    Protocol: 2,
                    Protocol2: 53,
                    OpenID: me.OpenID,
                    RoomID: mj._model.roomid,
                    SeatID: '' + mj.myPositionIndex,
                    IsAgree: agreeBool
                }
                client.send(C2GS_OutProto)
            }
        })

手机上的效果:

在我们的框架中调用还是比较简单的,我们的近期的【血战到底的课程】就是使用的本套框架,欢迎大家咨询报名。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-27,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com