当前位置: 首页 > news >正文

装饰器模式:C++动态扩展游戏角色能力

一、为什么用装饰器模式

    在游戏开发中,一个角色往往有基础的攻击、防御等功能。但随着游戏设计的复杂化,角色可能需要装备武器、护甲、宝石,或者临时获得某种技能效果。

如果我们把这些额外的效果都直接写进角色类里,会导致以下问题:

  1. 角色类过于庞大,耦合了所有可能的功能;

  2. 扩展性差,新增装备或技能都要修改角色类;

  3. 组合不灵活,难以在运行时动态组合效果。

装饰器模式正好解决了这个问题。它允许我们在不修改原有角色类的前提下,动态地给角色增加装备/技能效果,而且这些效果可以灵活组合。

二、场景说明

我们设计一个简单的战斗系统:

  • 游戏里有一个基础角色(Hero),它有 attack() 方法;

  • 角色可以装备 武器(提高攻击力);

  • 角色可以装备 护甲(增加防御效果,表现为输出提示);

  • 角色可以同时拥有多种装备,比如武器 + 护甲。

如果不用装饰器模式,可能会写出 HeroWithWeaponHeroWithArmorHeroWithWeaponAndArmor 等类,数量会爆炸。
而装饰器模式只需把功能拆成一个个“装备装饰器”,然后在运行时自由组合。

三、类图

四、C++代码实现


#include <iostream>
#include <memory>
#include <string>// 抽象角色
class Character {
public:virtual ~Character() = default;virtual void attack() = 0;
};// 具体角色:英雄
class Hero : public Character {
public:Hero(const std::string& name) : m_name(name) {}void attack() override {std::cout << m_name << " 发起了普通攻击!" << std::endl;}
private:std::string m_name;
};// 装饰器基类
class Equipment : public Character {
public:Equipment(std::shared_ptr<Character> character) : m_character(character) {}void attack() override {if (m_character) {m_character->attack();}}
protected:std::shared_ptr<Character> m_character;
};// 武器装饰器
class WeaponDecorator : public Equipment {
public:WeaponDecorator(std::shared_ptr<Character> character) : Equipment(character) {}void attack() override {Equipment::attack();std::cout << ">>> 装备武器:攻击力提升!" << std::endl;}
};// 护甲装饰器
class ArmorDecorator : public Equipment {
public:ArmorDecorator(std::shared_ptr<Character> character) : Equipment(character) {}void attack() override {Equipment::attack();std::cout << ">>> 穿戴护甲:防御力提升!" << std::endl;}
};// 客户端
int main() {// 基础角色std::shared_ptr<Character> hero = std::make_shared<Hero>("勇者");std::cout << "--- 普通英雄 ---" << std::endl;hero->attack();std::cout << "\n--- 英雄装备武器 ---" << std::endl;std::shared_ptr<Character> heroWithWeapon = std::make_shared<WeaponDecorator>(hero);heroWithWeapon->attack();std::cout << "\n--- 英雄穿戴护甲 ---" << std::endl;std::shared_ptr<Character> heroWithArmor = std::make_shared<ArmorDecorator>(hero);heroWithArmor->attack();std::cout << "\n--- 英雄装备武器 + 护甲 ---" << std::endl;std::shared_ptr<Character> heroWithAll =std::make_shared<ArmorDecorator>(std::make_shared<WeaponDecorator>(hero));heroWithAll->attack();return 0;
}

程序运行结果:

--- 普通英雄 ---
勇者 发起了普通攻击!--- 英雄装备武器 ---
勇者 发起了普通攻击!
>>> 装备武器:攻击力提升!--- 英雄穿戴护甲 ---
勇者 发起了普通攻击!
>>> 穿戴护甲:防御力提升!--- 英雄装备武器 + 护甲 ---
勇者 发起了普通攻击!
>>> 装备武器:攻击力提升!
>>> 穿戴护甲:防御力提升!

代码说明:

    在这段代码里,Character 定义了角色的统一接口,Hero 作为具体实现提供了最基础的攻击行为。Equipment 则是一个抽象的装饰器,它内部保存了一个角色对象,并在调用时转发给原始角色。

WeaponDecorator 和 ArmorDecorator 继承自 Equipment,在原有攻击行为的基础上分别增加了武器和护甲的效果。

    这样,当我们在 main 函数里把英雄用不同的装饰器包裹起来时,就能够灵活地给角色动态添加功能,而且这些功能可以自由叠加,而不用修改英雄类本身。

五、总结

    装饰器模式让我们在游戏开发中能够更灵活地为角色增加装备或技能效果,而不需要写出大量的组合类。

相比继承的方式,装饰器模式具有以下优势:

  1. 解耦:角色与装备的功能独立,扩展不会影响原有类;

  2. 灵活组合:装备可以随意叠加,避免类爆炸;

  3. 符合开闭原则:增加新装备时只需写新装饰器类,不必修改已有类。

这种模式在实际游戏开发中非常实用,比如:角色技能 Buff 叠加、武器/装备系统、特效系统等。


文章转载自:

http://zU7ykhbJ.mbmtn.cn
http://BVRUZO4o.mbmtn.cn
http://s4wBkwSn.mbmtn.cn
http://lxGmajUl.mbmtn.cn
http://FEWmCTFP.mbmtn.cn
http://yE1BO0bI.mbmtn.cn
http://i8KOo3kS.mbmtn.cn
http://6XcwHT3O.mbmtn.cn
http://0B6JeIj4.mbmtn.cn
http://r0VwjBCP.mbmtn.cn
http://wg4W1TPx.mbmtn.cn
http://dRJ0cRcz.mbmtn.cn
http://7ZkvuY3X.mbmtn.cn
http://9n7kkuae.mbmtn.cn
http://filk4LNE.mbmtn.cn
http://cfk4KcJN.mbmtn.cn
http://RRgJ2oox.mbmtn.cn
http://72qtGVgC.mbmtn.cn
http://mVnC37my.mbmtn.cn
http://5CrICYy6.mbmtn.cn
http://yiLJ1IuA.mbmtn.cn
http://pG3cz5mO.mbmtn.cn
http://dmcrKjmw.mbmtn.cn
http://qry65zC2.mbmtn.cn
http://H20PwF3G.mbmtn.cn
http://nvsfUyFn.mbmtn.cn
http://4vCnnztk.mbmtn.cn
http://OkgEmSwT.mbmtn.cn
http://KOORZFYx.mbmtn.cn
http://uR8W62Tl.mbmtn.cn
http://www.dtcms.com/a/379309.html

相关文章:

  • C#线程理解
  • 2025年市场岗位专业能力认证发展指南
  • 安卓逆向(三)逆向基本环境配置
  • 2025年通信安全员【单选题】考试题库及答案
  • Nodejs(④GraphQL)
  • 01背包问题 - 动态规划最优解法(Java实现)
  • github 中的issues都有那些作用
  • 大健康时代下的平台电商:VTN平台以科研创新重构健康美丽消费生态
  • 【自记】SQL 中 GROUPING 和 GROUPING SETS 语句的案例说明
  • Codeforces Round 1048 (Div. 2)
  • CFD专栏丨ultraFluidX 动力舱热仿真
  • QTday1作业
  • Linux基本指令(7)
  • 车载数据采集(DAQ)解析
  • 计算机组成原理:定点加法、减法运算
  • Cursor 不香了?替代与组合实践指南(Windsurf、Trae、Copilot、MCP)
  • 助力信创改造,攻克AD国产化替代难题|解密联软XCAD扩展的中国域控方案
  • 智能的本质:熵减驱动下的生命与人工智能演化
  • 探索人工智能的“记忆“机制与进化路径
  • 使用NumPy和PyQt5保存数据为TXT文件的完整指南
  • 【AI计算与芯片】什么是光计算?
  • 爱校对正式入驻抖音店铺,为更多用户带来专业文字校对服务
  • 项目1——单片机程序审查,控制系统流程图和时序图
  • 完美解决:应用版本更新,增加字段导致 Redis 旧数据反序列化报错
  • 探索数据库世界:从基础类型到实际应用
  • ui指针遇到问题
  • 安卓13_ROM修改定制化-----禁用 Android 导航按键的几种操作
  • VMWare使用文件夹共享操作步骤
  • 【Nginx开荒攻略】Nginx入门:核心概念与架构设计
  • MQTT协议回顾