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

1、模式标准

模式名称:迭代器模式

模式分类:行为型

模式意图:提供一种方法顺序访问一个聚合对象中的各个元素,且不需要暴露该对象的内部表示.

结构图:

适用于:

1、当你需要遍历一个复杂的数据结构,如树或图,而不想公开其内部表示时。

2、当你有一个集合对象,需要提供多种遍历方式,或者需要自定义遍历方式时。

3、当你需要让代码独立于特定的类或接口,使代码能够与多种数据类型一起工作时。

主要成员:

  1. 迭代器接口 (Iterator):定义遍历元素所需的方法,例如 next(),hasNext() 等。

  2. 具体迭代器(Concrete Iterator):实现迭代器接口,并跟踪遍历的当前位置。

  3. 聚合接口(Aggregate):定义创建相应迭代器对象的接口。

  4. 具体聚合(Concrete Aggregate):实现聚合接口,返回具体迭代器的实例。

2、分析与设计

在游戏中会经常用到迭代器,一般情况下我们定义一个index,随着游戏或者操作进行index++,来进行下一步对象或者操作。这里我们用到的场景是新手指引,当某个事件发生时,新手指引聚合器创建一个指引迭代器,指引迭代器指引玩家一步一步的按顺序完成。

意图:提供一种方法顺序访问一个聚合对象(新手指引聚合器)中的各个元素(新手指引),且不需要暴露该对象的内部表示

3、开始打造

TypeScript 复制代码
// 聚合接口
export interface IAggregate {
    createIterator(): IIterator
}
TypeScript 复制代码
// 具体的新手指引聚合
export class GuideAggregate implements IAggregate {
    steps: GuideStep[] = []

    addStep(step: GuideStep) {
        this.steps.push(step)
    }

    createIterator() {
        return new GuideIterator(this.steps)
    }
}
TypeScript 复制代码
// 迭代器接口
export interface IIterator {
    hasNext(): boolean
    next(): any
}
TypeScript 复制代码
// 具体的新手指引迭代器
export class GuideIterator implements IIterator {
    private index: number = 0
    steps: GuideStep[] = []

    constructor(steps: GuideStep[]) {
        this.steps = steps
    }

    hasNext(): boolean {
        return this.index < this.steps.length;
    }
    next(): GuideStep | null {
        if (this.hasNext()) {
            return this.steps[this.index++];
        } else {
            return null;
        }
    }
}
TypeScript 复制代码
// 指引步骤
export class GuideStep {
    private onClickResolver: (() => void) | null = null;
    guideItem: IGuideItem
    constructor(_item: IGuideItem) {
        this.guideItem = _item
    }
    execute() {
        const targetNode = find(this.guideItem.targetNodePath)
        // 注册事件监听器
        targetNode.on(Node.EventType.TOUCH_START, this.handleClick)
        return targetNode // 外面要用到先返回
    }

    // 当用户点击时,解决 Promise
    private handleClick = () => {
        const targetNode = find(this.guideItem.targetNodePath)
        targetNode.off(Node.EventType.TOUCH_START, this.handleClick)
        if (this.onClickResolver) {
            this.onClickResolver();
        }
    }

    // 返回一个 Promise,该 Promise 在用户点击后被resolve
    onClick(): Promise<void> {
        console.log('等待点击')
        return new Promise((resolve) => {
            this.onClickResolver = resolve;
        });
    }
}

4、开始使用

TypeScript 复制代码
        let guides: IGuideItem[] = [{
            "group": "battle_start",
            "targetNodePath": "root/UICanvas/battle_index/help_move_up",
            "text": "点击的虚框",
            "text_size": [200, 200],
            "text_pos_index": 3
        }, {
            "group": "battle_start",
            "targetNodePath": "root/UICanvas/battle_index/help_move_up",
            "text": "点击的虚框",
            "text_size": [200, 200],
            "text_pos_index": 3
        }]
        // 开始本次的新手指引
        let guideAggregate = new GuideAggregate();
        guides.forEach((_item) => {
            guideAggregate.addStep(new GuideStep(_item));
        })

        async function runGuide(guide: GuideAggregate) {
            // 创建新手指引的指引层
            PlayerGuideSystem.createGuideNodes(comp)
            let iterator = guide.createIterator();
            while (iterator.hasNext()) {
                console.log('准备指引')
                let step = iterator.next();
                if (step !== null) {
                    step.execute();
                    await step.onClick();  // 等待用户点击
                    console.log('点击完成')
                }
            }
            // 清理新手指引的指引层
            PlayerGuideSystem.clearNodes()
            console.log('指导层清理完成')
        }
        runGuide(guideAggregate);

完工

相关推荐
AI小百科5 小时前
AI 进游戏:游戏里的 NPC 开始有自己的性格
人工智能·游戏·ai
是2的10次方啊6 小时前
设计模式与生活⑬:你坐几号线,谁来运营是另一回事
设计模式
云-缩影15 小时前
文生图技术落地:从广告到游戏,哪些场景真的能用
人工智能·游戏
hkNaruto1 天前
【AI】游戏大模型智能体OODA过程记忆问题解决方案:AgenticSTS 有界记忆契约:技术分析与流水线改造操作手册
人工智能·游戏·机器学习
Tt有了t1 天前
设计模式速查
java·python·设计模式
一条Go1 天前
四个进程,一把锁:Alioth 的告警评测为什么不需要消息队列
后端·设计模式·架构
tealcwu1 天前
【Unity基础】为什么游戏需要物理按键映射?从 Unity Input Manager 到跨引擎输入设计
java·游戏·unity
一缕82年的清风1 天前
被中产唾弃的“十元快剪”,藏着最狠的极客工程学
人工智能·设计模式
是2的10次方啊1 天前
设计模式与生活⑫:周报又到手,别从空白开始
设计模式
沐飞工具箱1 天前
游戏、漫画、视频里的外语怎么实时翻译?从 OCR + AI 原理聊聊 VoriTrans 屏幕翻译
人工智能·游戏·实时互动·音视频·自动翻译