用23种设计模式打造一个cocos creator的游戏框架----(十五)策略模式

news2024/9/19 10:41:31

1、模式标准

模式名称:策略模式

模式分类:行为型

模式意图:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。此模式使得算法可以独立于使用它们的客户而变化

结构图:

适用于:

1、许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
2、需要使用一个算法的不同变体。例如,定义一些反映不同空间的空间/时间权衡的算法当这些变体实现为一个算法的类层次时,可以使用策略模式。
3、算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
4、一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,将相关的条件分支移入它们各自的 Strategy 类中,以代替这些条件语句。 

2、分析与设计  

策略和桥接模式看起来可能非常相似,但策略模式是行为型,桥接模式是结构型。策略模式是直接引用实现类,而桥接模式是引用一个实现类的接口。当前策略模式关键是可以相互替换算法。接下来把我们曾经用过的武器替换来举例,修改一下我们的意图

意图:定义一系列的算法(武器),把它们一个个封装起来,并且使它们可以相互替换。

3、开始打造

// 武器接口
export interface IWeapon {
    useWeapon(): void;
}

// 剑
export class Sword implements IWeapon {
    useWeapon(): void {
        console.log("用剑进行攻击");
    }
}

// 斧头
export class Axe implements IWeapon {
    useWeapon(): void {
        console.log("用斧头进行攻击");
    }
}
// 弓
export class Bow implements IWeapon {
    useWeapon(): void {
        console.log("用弓箭进行攻击");
    }
}
// 近程攻击
export class MeleeAttack implements IAttackStrategy {
    attack(weapon: IWeapon): void {
        console.log("进行近程攻击:");
        weapon.useWeapon();
    }
}

【优化】结合前面的桥接模式的攻击方式,我们将攻击系统升级一下

// 攻击方式接口
export interface IAttackStrategy {
    attack(weapon: IWeapon): void;
}

// 近程攻击
export class MeleeAttack implements IAttackStrategy {
    attack(weapon: IWeapon): void {
        console.log("进行近程攻击:");
        weapon.useWeapon();
    }
}

// 远程攻击
export class RangedAttack implements IAttackStrategy {
    attack(weapon: IWeapon): void {
        console.log("进行远程攻击:");
        weapon.useWeapon();
    }
}

// 武器接口
export interface IWeapon {
    useWeapon(): void;
}

// 剑
export class Sword implements IWeapon {
    useWeapon(): void {
        console.log("用剑进行攻击");
    }
}

// 斧头
export class Axe implements IWeapon {
    useWeapon(): void {
        console.log("用斧头进行攻击");
    }
}
// 弓
export class Bow implements IWeapon {
    useWeapon(): void {
        console.log("用弓箭进行攻击");
    }
}


// 抽象战斗者
export abstract class Fighter {
    protected attackStrategy: IAttackStrategy;
    protected weapon: IWeapon;

    constructor(attackStrategy: IAttackStrategy, weapon: IWeapon) {
        this.attackStrategy = attackStrategy;
        this.weapon = weapon;
    }

    attack(): void {
        this.attackStrategy.attack(this.weapon);
    }

    // 更换武器的方法
    setWeapon(weapon: IWeapon): void {
        this.weapon = weapon;
    }
}

// 骑兵
export class Cavalry extends Fighter {
    constructor(attackStrategy: IAttackStrategy, weapon: IWeapon) {
        super(attackStrategy, weapon);
    }
}

// 弓箭手
export class Archer extends Fighter {
    constructor(attackStrategy: IAttackStrategy, weapon: IWeapon) {
        super(attackStrategy, weapon);
    }
}

 4、开始使用

export class UnitItem  extends Component implements IItem, IUnitItem {

    ad: number = 100;
    mp: number = 0;
    role: Fighter;
    private currentState: IUnitState = null;

    accept(visitor: IAttackVisitor) {
        visitor.visitUnitItem(this)
    }


    setRole(role: Fighter): void {
        this.role = role;
    }

    setWeapon(weapon: IWeapon) {
        this.role.setWeapon(weapon)
    }
    
    .....
}
        let unitItem001 = xhgame.itemFactory.createUnitItem('kuloubing', UnitType.UnitSpine)
        let unitItem002 = xhgame.itemFactory.createUnitItem('kuloubing', UnitType.UnitSpine)

        unitItem001.idle()
        unitItem002.idle()

        const sword = new Sword();
        const bow = new Bow();
        const axe = new Axe();

        unitItem001.setRole(new Cavalry(new MeleeAttack(), sword));
        console.log('unitItem001(骑兵-近程)使用【剑】对unitItem002发起了攻击')
        unitItem001.attack(unitItem002)
        // 更换骑兵的武器为斧头
        unitItem001.setWeapon(axe);
        console.log('unitItem001(骑兵-近程)使用【斧头】对unitItem002发起了攻击')
        unitItem001.attack(unitItem002);

        unitItem002.setRole(new Cavalry(new RangedAttack(), bow));
        console.log('unitItem002(骑兵-远程)使用【弓】对unitItem001发起了攻击')
        unitItem002.attack(unitItem001)

总结:桥接模式在构建时定好攻击方式,策略模式在行为中使用不同的武器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1308751.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NCNN 源码学习【三】:数据处理

一、Topic:数据处理 这次我们来一段NCNN应用代码中,除了推理外最重要的一部分代码,数据处理: ncnn::Mat in ncnn::Mat::from_pixels_resize(bgr.data, ncnn::Mat::PIXEL_BGR, bgr.cols, bgr.rows, 227, 227);const float mean_v…

Github入门

简介 github是一个基于git的代码仓库,可以通过git来上传和下载代码。国内类似的有gitee。 开源项目一般会申明开源协议。我们可以基于可商用的代码开发我们自己的项目,以期进行快速开发。 一般情况下gitee上的项目基本都够我们使用了。 git基础 Git…

Caché/M 数据库上面的那个 é 怎么打

Cach/M 数据库名字上的 e 有一撇,这个 e 是法语字符,通常英语键盘还不是那么好打。 因最近在研究这个数据库,所以这个字符会用得比较多,简单点的方法就是直接用 e 代替,并且后面加个斜杆 M 用于区分英文的 Cache。 拷…

WEB 3D技术 简述React Hook/Class 组件中使用three.js方式

之前 已经讲过了 用vue结合three.js进行开发 那么 自然是少不了react 我们 还是先创建一个文件夹 终端执行 npm init vitelatest输入一下项目名称 然后技术选择 react 也不太清楚大家的基础 那就选择最简单的js 然后 我们就创建完成了 然后 我们用编辑器打开创建好的项目目…

数据结构与算法:冒泡排序

原理 从前到后,连续相连两个数对比,如果前一个数大于后一个数,则交换。 第一次: arr[0] 和 arr[1] 对比,若arr[0] 大于 arr[1], 交换两个值。 arr[1] 和 arr[2]对比,若arr[1] 大于 arr[2]&…

【大话数据结构】- 读书笔记

2023-12-13 读书笔记 第一章 数据结构绪论 逻辑结构 集合结构线性结构树形结构图形结构 物理结构 顺序存储结构链式存储结构 可能在学习的时候会困惑、不懂、不理解、不会应用,甚至不知所云,可实际上无论学什么都是通过努力才可以学到真东西。只有…

Windows、Linux 和 macOS 操作系统:操作系统大比较

目录 引言 Windows Linux macOS 1. 用户界面 1.1 Windows 1.2 Linux 1.3 macOS 2. 开发者支持 2.1 Windows 2.2 Linux 2.3 macOS 3. 安全性和稳定性 3.1 Windows 3.2 Linux 3.3 macOS 结论 引言 在计算机科学领域,操作系统是计算机系统中的核心软件…

模块四(一):搭建自己的SSR

前言:同构渲染是将服务器渲染和客户端渲染相结合的一种渲染方式,在服务端生成初始页面,提升首屏加载速度,并且有利于SEO;在客户端接管HTML,并且将静态HTML激活为数据绑定的动态HTML,为用户提供更…

(五)STM32 NVIC 中断、优先级管理及 AFIO 时钟的开启

目录 1. 中断相关知识简介 1.1 什么是中断 1.2 什么是内中断、外中断 1.3 什么是可屏蔽中断、不可屏蔽中断 2. CM3 内核中断介绍 2.1 F103系统异常清单 2.2 F103 外部中断清单 3. NVIC 简介 3.1 NVIC 寄存器简介 3.2 NVIC 相关寄存器的介绍 4. 中断优先级 4.1 优先…

HarmonyOS 开发实例—蜜蜂 AI 助手

HarmonyOS 开发实例—蜜蜂 AI 助手 1. 前言 自华为宣布 HarmonyOS NEXT 全面启动,近期新浪、B 站、小红书、支付宝等各领域头部企业纷纷启动鸿蒙原生应用开发。据媒体统计,如今 Top20 的应用里,已经有近一半开始了鸿蒙原生应用开发。虽然目…

springCloud项目打包如何把jar发放到指定目录下

springCloud项目打包如何把jar发放到指定目录下 maven-antrun-plugin springCloud微服务打包jar,模块过多;我的项目模块结构如下: 我把实体类相关的单独抽离一个模块在service-api下服务单独写在service某块下, 每个模块的jar都…

SpringBoot+Vue3前后端快速整合入门

前言 最近需要维护一个个人项目,由于笔者是一个大后端,所以借此机会把前端学习过程记录一下,方便后续回顾。 前端项目初始化 安装npm 在前端项目初始化时,我们必须要安装好node,官网地址如下,因为笔者后…

Web前端 ---- 【Vue】Vue路由传参(query和params)

目录 前言 为什么用路由 路由route和路由器router Vue中路由的工作原理 安装配置vue-router 使用VueRouter 多级路由 路由传参 query传参 params传参 前言 本文介绍路由相关知识路由传参 为什么用路由 为了单页面应用开发,只更换组件,不频繁刷…

mysql数据库相关知识【MYSQL】

mysql数据库相关知识【MYSQL】 一. 库1.1 登录数据库管理系统1.2 什么是数据库1.2.1 mysqld与mysql 1.3 编码集和校验集1.3.1 什么是编码集和校验集1.3.2 查看库对应的编码集和校验集1.3.3 用指定的编码集和校验集 1.4 库的操作 一. 库 1.1 登录数据库管理系统 这个算是第一个…

vue中预览pdf的方法

使用vue-pdf 备注&#xff1a;这里只介绍了一页的pdf <div class"animation-box-pdf"><pdf :src"http://xxxx" /> </div>import Pdf from vue-pdf // src可以是文件地址url&#xff0c;也可以是文件流blob&#xff08;将blob转成url&a…

TCP/IP 四层体系结构

目录 ​编辑 导言&#xff1a; 应用层 1. HTTP&#xff08;超文本传输协议&#xff09; 2. FTP&#xff08;文件传输协议&#xff09; 3. SMTP&#xff08;简单邮件传输协议&#xff09; 4. POP3&#xff08;邮局协议第3版&#xff09; 5. IMAP&#xff08;互联网消息访…

bugku--源代码

查看源代码 发显URL编码 解码 在拼接这一串 拿着去提交就行啦

IDEA之设置主题风格为eclipse风格

设置IDEA的主题风格为eclipse风格&#xff0c;步骤如下: 1.选择File->Settings 2.选择 Plugins 3.搜索 eclipse theme&#xff0c;注意是红框里的&#xff0c;点击 install 下载后就会自动设置这个主题 4.你也可以去修改主题&#xff0c;选择 Appearance&#xff0c;设置th…

python编程需要的电脑配置,python编程用什么电脑

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python编程对笔记本电脑配置的要求&#xff0c;python编程对电脑配置的要求有哪些&#xff0c;现在让我们一起来看看吧&#xff01; 学习python编程需要什么配置的电脑 简单的来讲&#xff0c;Python的话普通电脑就可以…

EasyRecovery2024苹果电脑mac破解版安装包下载

EasyRecovery是一款操作安全、价格便宜、用户自主操作的非破坏性的只读应用程序&#xff0c;它不会往源驱上写任何东西&#xff0c;也不会对源驱做任何改变。它支持从各种各样的存储介质恢复删除或者丢失的文件&#xff0c;其支持的媒体介质包括&#xff1a;硬盘驱动器、光驱、…