用23种设计模式打造一个cocos creator的游戏框架----(七)代理模式

1、模式标准

模式名称:代理模式

模式分类:结构型

模式意图:为其他对象提供一种代理以控制对这个对象的访问。

结构图:

适用于:

  1. 远程代理:也称为大使,这是最常见的类型,在分布式对象通信中被用于表示运行在不同地址空间的对象。

  2. 虚拟代理:根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。

  3. 安全代理:用来控制真实对象访问时的权限。

  4. 智能指引:当调用真实对象时,代理处理另外一些事。

代理模式主要有两个角色:

  • 代理(Proxy):保存一个引用使得代理可以访问实体。提供一个与主题的接口相同的接口,这样代理就可以用来替代实体。控制对实体的存取,并可能负责创建和删除它。

  • 实体(Real Subject):代理所代表的真实对象,是真正的被调用的对象。

2、分析与设计 

代理在日常开发中经常用到,比如通过香港服务器代理去看github上的项目。比如通过抓包工具作为代理,将app的请求过程进行拦截修改,然后在发送出去。代理虽然帮你干了你想干是事情,但是你却不知道它其实干了更多你不知道的。代理的玩法有很多,在游戏框架中我们如何使用代理模式,应该也有很多玩法,这里我只介绍其中一种。

在前端开发中vue的作者用在vue3中用proxy来取代vue2的Object.defineProperty实现响应式。游戏中也经常用到数据与视图的绑定,比如玩家的金币,在数据层player.money = 200时,我们希望页面上的所有显示金币数量的地方,都自动自动刷新视图显示为200,且如果数值不变时,你们你触发n多次player.money = 200,都不会触发刷新视图的事件。

3、开始打造

interface IObject {
    operation()
}
class RealObject implements IObject {
    operation() {

    }
}

class ProxyObject implements IObject {
    realObject: RealObject;

    constructor(realObject: RealObject) {
        this.realObject = realObject
    }

    public operation(): void {
        //在调用目标对象之前,完成一些操作
        console.log("Before Do Something");
        this.realObject.operation();
        //在调用目标对象之后,完成一些操作
        console.log("After Do Something");
    }
}

 如果是代理对象,就不用自己写一个了,用内部基于 ES6 的 Proxy 实现就够用了

const vmHandler = {
    set(obj, prop, value) {
        // 代理拦截修改
        obj[prop] = value;
        return true
    }
};
let loading_vm: ILoadingVM = {
        progress: 0
    }
let proxy_loading_vm = new Proxy(loading_vm, vmHandler)

我们的目的是给游戏框架整一个数据绑定的功能,所以这里用 ES6 的 Proxy就够了。

4、开始使用

这里用ES6 的 Proxy自带的那个代理,因为我们主要是对数据修改进行代理拦截

因为之前是考虑到多个游戏分离,所以给每个游戏整了一个IGameVM,目前简单点只给ui做了全局的vm

export class DemoVM implements IGameVM {
 
   /**
     * 
     * 唯一的方法出口
     */
    getVMs() {
        return {
            // loadingVM: this._getLoadingVM(),
            gateVM: this._getGateVM(),
            // battleVM: this._getBattleVM(),
        }
    }   

    /**
     * 动态显示数据
     */
    private proxy_gate_vm: IGateVM_JCQ = null
    private _gate_vm: IGateVM_JCQ = {
        ps: 0,
        gold: 0,
        diamond: 0,
        last_battle_id: 0 // 当前最高关卡
    }
    private _getGateVM() {
        if (!xhgame.gui.getUI(xhgame.uiid.Gate_Index)) {
            return this._gate_vm
        }
        if (this.proxy_gate_vm == null && xhgame.gui.getUI(xhgame.uiid.Gate_Index)) {
            const handler = xhgame.gui.getUI(xhgame.uiid.Gate_Index).getComponent(GateView).vmHandler
            // 设计模式12 代理模式
            this.proxy_gate_vm = new Proxy(this._gate_vm, handler);
        }
        return this.proxy_gate_vm
    }
}
export class GateView extends ViewComponent {

    private ps_lable: Label
    private gold_lable: Label
    private diamond_lable: Label
    private last_battle_lable: Label


    protected onLoad(): void {
        this.ps_lable = this.node.getChildByName('top').getChildByName('value').getComponent(Label)
        this.gold_lable = this.node.getChildByName('top').getChildByName('gold').getChildByName('value').getComponent(Label)
        this.diamond_lable = this.node.getChildByName('top').getChildByName('diamond').getChildByName('value').getComponent(Label)
        this.last_battle_lable = this.node.getChildByName('bottom').getChildByName('curBattleIdText').getComponent(Label)
    }


    get vmHandler() {
        const that = this
        return {
            set(obj: IGateVM_JCQ, prop, value) {
                // 如果原先的值一样就不做视图层的修改了
                if (prop == 'ps' && value != obj[prop]) {
                    that.ps_lable.string = value + '/3'
                }
                if (prop == 'gold') {
                    that.gold_lable.string = value
                }
                if (prop == 'diamond') {
                    that.diamond_lable.string = value
                }
                if (prop == 'last_battle_id') {
                    that.last_battle_lable.string = '当前第' + value + '关'
                }
                obj[prop] = value;
                return true
            }
        };
    }
}

    
export class xhgame {

    .....

    /** 当前游戏用到的视图绑定 */
    static get vm() {
        return gameInstance.game.getVM().getVMs()
    }

    ....
}

使用时只需要 

xhgame.vm.gateVM.gold = 200

  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cocos Creator是一款面向游戏开发者的跨平台游戏开发工具,它集成了Cocos2d-x游戏引擎和Cocos Studio编辑器,支持多种平台上的游戏开发,如iOS、Android、Windows等。 消灭星星是一款基于Cocos Creator开发的游戏。在游戏中,玩家需要消除屏幕上的星星,以获得分数。游戏开始时,屏幕上会随机生成一些星星,玩家可以通过点击相连的星星来消除它们。消除的星星越多,得到的分数就越高。玩家可以通过不断消除星星来刷新高分记录,挑战自己的极限。 在消灭星星游戏中,Cocos Creator提供了丰富的功能和工具,为游戏开发者提供了便利。开发者可以使用Cocos Creator的图形界面编辑器来创建游戏场景、导入资源和设置游戏规则等。同时,Cocos Creator还提供了强大的脚本编写功能,开发者可以使用JavaScript或TypeScript编写游戏逻辑,实现游戏中的各种功能。 除了基本的消除星星玩法,Cocos Creator还支持添加特殊道具、关卡设计、人物角色等功能。开发者可以根据自己的需求,自定义游戏的玩法和功能,使游戏更加有趣和有挑战性。 总而言之,Cocos Creator游戏开发工具提供了强大的功能和便捷的开发环境,使开发者可以轻松地开发出各种各样的游戏,包括消灭星星这样的小而精致的休闲游戏。无论是想要学习游戏开发还是实现自己的游戏创意,Cocos Creator都是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值