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

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)

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【期末复习向】常见的激活函数

激活函数是非线性的函数,使用它的原因就是因为线性函数无论叠加多少层,最终带来的变化都是线性的组合,一般也只能用于线性分类,如经典的多层感知机。但是如果加上非线性的变换,根据通用近似定理,就可使得神…

持续集成交付CICD:Jenkins使用GitLab共享库实现自动上传前后端项目Nexus制品

目录 一、实验 1.GitLab本地导入前后端项目 2.Jenkins新建前后端项目流水线 3.Sonarqube录入质量阈与质量配置 4.修改GitLab共享库代码 5.Jenkins手动构建前后端项目流水线 6.Nexus查看制品上传情况 7.优化代码获取RELEASE分支 8.优化Jenkins流水线项目名称 一、实验 …

Linux环境下maven的安装

到官网下载maven 步入下面的地址选择合适的maven版本 https://dlcdn.apache.org/maven/ 以笔者为例,选择了3.5.4这个版本 将maven上传到Linux服务器并解压 tar -zxvf apache-maven-3.5.4-bin.tar.gz配置环境变量 我们使用vim编辑profile vim /etc/profile环境…

基于Spring Boot、Mybatis、Redis和Layui的企业电子招投标系统源码实现与立项流程

招投标管理系统是一款适用于招标代理、政府采购、企业采购和工程交易等领域的企业级应用平台。该平台以项目为主线,从项目立项到项目归档,实现了全流程的高效沟通和协作。通过该平台,用户可以实时共享项目数据信息,实现规范化管理…

薅github的羊毛-用pages建自己的博客或静态资源站 - 1/2

注册帐号 准备邮箱注册帐号,在注册界面输入用户名、邮箱及密码完成注册。 添加图片注释,不超过 140 字(可选) 1. 在注册成过程中,会往邮箱发送验证码,请如实填写即可 2. 验证码没错的话,就代…

LLM Agent发展演进历史(观看metagpt视频笔记)

LLM相关的6篇重要的论文,其中4篇来自谷歌,2篇来自openai。技术路径演进大致是:SSL (Self-Supervised Learning) -> SFT (Supervised FineTune) IT (Instruction Tuning) -> RLHF。 word embedding的问题:新词如何处理&…

数据结构之Map/Set讲解+硬核源码剖析

💕"活着是为了活着本身而活着"💕 作者:Mylvzi 文章主要内容:数据结构之Map/Set讲解硬核源码剖析 一.搜索树 1.概念 二叉搜索树又叫二叉排序树,他或者是一颗空树,或者是具有以下性质的树 若它…

Oracle md5

SQL CREATE OR REPLACE FUNCTION MD5(passwd IN VARCHAR2) RETURN VARCHAR2 ISretval varchar2(32); BEGINretval : utl_raw.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING > passwd));RETURN retval; END; 测试 select md5(lw112190) from dual 效果

Android Studio的代码笔记--Adapter+GridView学习

AdapterGridView学习 AdapterGridViewSimpleAdapterGridViewactivity_main.xmlappicon.xmlMainActivity 自定义BaseAdapterGridView已下载应用PackageInfoAppAdapterMainActivity2 其他获取已下载应用信息函数获取所有应用信息函数ImageView产生圆角的方法背景设置很渐变设置选…

Matter分析与安全验证

本文作者:杉木涂鸦智能安全实验室 什么是matter Matter是一项智能家居的开源标准,由连接标准联盟制定、认证、推广,该标准基于互联网协议(IP),遵循该标准的智能家居设备、移动应用程序和云服务能够进行互…

three.js(一)

文章目录 three.js环境搭建正文补充 示例效果知识点补充1:一个标准的html知识点补充2:原生的前端框架和Vue框架的区别原生的前端框架Vue框架声明式编程和响应式编程 three.js环境搭建 正文 搭建 Three.js 的环境通常包括以下几个步骤: 1.创建项目目录&#xff1a…

Linux的基本指令和权限的知识

学前的建议:大家不要太关注指令是啥,记不住怎么办(没事,想用时去查就好了),这篇文章重点部分是围绕指令的周边知识。毕竟指令是“死肌肉”,而一些关于Linux和操作系统的理论知识才是最重要滴&am…

懒惰的数独——lodash的shuffle方法实现随机打乱的效果

1.效果 2.代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title></title><script src"https://cdn.jsdelivr.net/npm/vue2.5.17/dist/vue.js"></script><script src&q…

Unity_FairyGUI发布导入Unity编辑器资源报错

Unity_FairyGUI发布导入Unity编辑器资源报错 报错&#xff1a; FairyGUI: settings for Assets/UI/XMUI/XMSubway_atlas0.png is wrong! Correct values are: (Generate Mip Mapsunchecked) UnityEngine.Debug:LogWarning (object) FairyGUI.UIPackage:LoadAtlas (FairyGUI.P…

用于 ChatGPT 的 FPGA 加速大型语言模型

简介&#xff1a;大型语言模型 近年来&#xff0c;大型语言模型 &#xff08;LLM&#xff09; 彻底改变了自然语言处理领域&#xff0c;使机器能够生成类似人类的文本并进行有意义的对话。这些模型&#xff0c;例如 OpenAI 的 GPT&#xff0c;具有惊人的理解和生成语言的能力。…

Stable Video Diffusion: Scaling Latent Video Diffusion Models to Large Datasets

Stable video diffusion&#xff1a;将潜在视频扩散模型扩展到大型数据集 可以做到&#xff1a;文本-视频的生成、&#xff08;文本-&#xff09;图像-视频的生成、通过图像-视频微调进行多视图合成 摘要 我们提出了Stable video diffusion——一种用于高分辨率、最先进的文…

re:Invent 云端历程:Swami Sivasubramanian 博士主题演讲-数据共生与开放

re:Invent 云端历程&#xff1a;Swami Sivasubramanian 博士主题演讲-数据共生与开放 亚马逊云科技 re:Invent 大会简介 亚马逊云科技 re:Invent 是亚马逊云科技为全球云计算社区举办的学习大会。是云计算领域的行业风向标&#xff0c;科技界的全球年度重磅盛会。 亚马逊云科…

Sketch for Mac:实现你的创意绘图梦想的矢量绘图软件

随着数字时代的到来&#xff0c;矢量绘图软件成为了广告设计、插画创作和UI设计等领域中必不可少的工具。在众多矢量绘图软件中&#xff0c;Sketch for Mac&#xff08;矢量绘图软件&#xff09;以其强大的功能和简洁的界面脱颖而出&#xff0c;成为了众多设计师的首选。 Sket…

Json数据报文解析-Gson库-JsonObject类-JsonParse类-JsonArray类

一、前言 本文我们将介绍如何解析Json数据&#xff0c;主要通过Gson库中的相关类来实现。 二、详细步骤 首先&#xff0c;我们要拿到一个基础的Json数据&#xff0c;这里将以下面的Json数据作为示例&#xff1a; {"code":"1","msg":"ok&q…

***Cpolar配置外网访问和Dashy

Dashy是一个开源的自托管的导航页配置服务,具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一些网站聚合起来放在一起,形成自己的导航页。一款功能超强大,颜值爆表的可定制专属导航页工具 结合cpolar内网工具,我们实现无需部署到公网服务器…