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

游戏开发中常用的设计模式

目录

  • 前言
  • 一、工厂模式
  • 二、单例模式
  • 三、观察者模式
    • 观察者模式的优势
  • 四、状态模式
    • 状态模式的优势
  • 五、策略模式
    • 策略模式的优势
  • 六、组合模式
  • 七、命令模式
  • 八、装饰器模式

前言

本文介绍了游戏开发中常用的设计模式,如工厂模式用于创建对象,单例模式确保全局唯一,观察者模式实现对象间事件通知,状态模式管理对象状态转换,策略模式提供行为选择,组合模式构建复杂对象结构,命令模式分离操作与执行,装饰模式动态扩展功能。

  1. 单例模式:用于确保在游戏中只存在一个实例,例如游戏管理器(Game Manager)或资源管理器(Resource Manager)。
  2. 工厂模式:用于创建对象实例,例如创建不同类型的敌人(Enemy)或武器(Weapon)。
  3. 观察者模式:用于实现对象间的事件通知,例如实现角色(Character)与任务(Quest)的交互。
  4. 状态模式:用于管理游戏中对象的状态转换,例如角色在游戏中的状态(生命值、能量等)。
  5. 策略模式:用于实现不同的算法和行为,例如实现不同的AI(Artificial Intelligence)策略。
  6. 组合模式:用于创建和管理游戏中的复杂对象结构,例如实现游戏中的菜单(Menu)或场景(Scene)。
  7. 命令模式:用于将操作(操作)与其执行分离,例如实现游戏中的键盘快捷键。
  8. 装饰器模式:通过创建一个包装对象,即装饰器,来包裹真正的对象,并且在保持接口的前提下,为它提供额外的功能。

一、工厂模式

工厂模式是一种常用的设计模式,用于创建对象,它能够隐藏创建对象的复杂性,并且使代码更加灵活。在游戏开发中,工厂模式通常用于创建游戏对象、敌人、道具等。

//首先我们定义一个接口,表示我们要创建的对象:
public interface IGameObject
{void Update();
}//创建具体的游戏对象类:
public class Player : IGameObject
{public void Update(){Console.WriteLine("Player is updating.");}
}public class Enemy : IGameObject
{public void Update(){Console.WriteLine("Enemy is updating.");}
}//创建一个工厂类,用于创建游戏对象
public class GameObjectFactory
{public IGameObject CreateGameObject(string type){switch (type){case "Player":return new Player();case "Enemy":return new Enemy();default:throw new ArgumentException($"Invalid game object type: {type}");}}
}//使用工厂类来创建游戏对象:
GameObjectFactory factory = new GameObjectFactory();IGameObject player = factory.CreateGameObject("Player");
player.Update();IGameObject enemy = factory.CreateGameObject("Enemy");
enemy.Update();

二、单例模式

单例模式是一种常用的设计模式,用于确保一个类只有一个实例,并提供全局访问点。在游戏开发中,单例模式通常用于管理全局状态、资源池等。

public class GameManager
{private static GameManager _instance;// 私有构造函数,确保只能在类内部创建实例private GameManager(){// 初始化游戏管理器Console.WriteLine("GameManager initialized.");}// 全局访问点public static GameManager Instance{get{if (_instance == null){_instance = new GameManager();///懒汉式}return _instance;}}// 游戏管理器的功能public void StartGame(){Console.WriteLine("Game started.");}
}
GameManager gameManager = GameManager.Instance;gameManager.StartGame(); // Output: "Game started."GameManager gameManager2 = GameManager.Instance; // 和 gameManager 引用同一个对象

三、观察者模式

观察者模式在游戏开发中通常用于红点系统,实现观察者模式时要注意具体目标对象和具体观察者对象之间不能直接调用,否则将使两者之间紧密耦合起来,这违反了面向对象的设计原则。
观察者模式的主要角色如下:

  • 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
  • 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
  • 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
  • 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
using System.Collections.Generic;
using UnityEngine;//抽象类 观察者
public interface Observer
{void response(); //反应
}//被观察者
public class ConcreteSubject
{public static ConcreteSubject _instance = null;protected List<Observer> observers = new List<Observer>();public void Init(){}public static ConcreteSubject Instance(){if (_instance == null){_instance = new ConcreteSubject();}return _instance;}//增加观察者方法public void add(Observer observer){observers.Add(observer);}//删除观察者方法public void remove(Observer observer){observers.Remove(observer);}public void notifyObserver(){Debug.Log("具体目标发生改变...");foreach(Observer obs in observers){obs.response();}}
}//具体观察者1
public class ConcreteObserver1 : MonoBehaviour , Observer
{private void Start(){ConcreteSubject.Instance().add(this);}public void response(){Debug.Log("具体观察者1作出反应!");}private void OnDestroy(){ConcreteSubject.Instance().remove(this);}
}//具体观察者2
public class ConcreteObserver2 : MonoBehaviour, Observer
{private void Start(){ConcreteSubject.Instance().add(this);}public void response(){Debug.Log("具体观察者2作出反应!");}private void OnDestroy(){ConcreteSubject.Instance().remove(this);}}

观察者模式的优势

  1. 松散耦合:观察者模式允许构建松散耦合的类关系,这在游戏开发中非常重要,因为它可以降低系统各部分之间的耦合度。
  2. 提高系统的灵活性和可维护性:观察者模式不仅能够降低系统各部分之间的耦合度,还能提高系统的灵活性和可维护性。
  3. 解耦和事件驱动:观察者模式特别适用于需要响应UI事件或进行成就系统设计的场景,它允许完全解耦控制逻辑和UI事件处理。

四、状态模式

状态模式的优势

  1. 封装状态转换:状态模式将状态转换的逻辑封装到状态类内部,使得状态之间的切换变得明确和集中。
  2. 简化复杂条件逻辑:通过将不同状态的行为分割开来,状态模式减少了对象间的相互依赖,提高了可维护性和可扩展性。
  3. 清晰的状态管理:特别是在Unity引擎中,状态模式帮助游戏场景的切换和管理变得更加清晰。

五、策略模式

如何在Unity中实现策略模式以优化角色行为和AI策略?

在Unity中实现策略模式以优化角色行为和AI策略,可以按照以下步骤进行:

  1. 定义策略类:首先,将不同的行为或算法封装成独立的类(策略)。每个策略类代表一种特定的行为或算法。例如,可以为角色攻击、移动、防御等行为分别创建一个策略类。
  2. 使用接口或抽象类:为了使策略类之间可以互相替换,建议使用接口或抽象类来定义每种策略需要实现的方法。这样可以确保所有策略类都遵循相同的协议。
  3. 动态选择和切换策略:在运行时根据需要动态选择和切换不同的策略。这可以通过检查游戏中的某些条件或事件来实现。例如,当敌人接近玩家时,可以选择攻击策略;当敌人远离玩家时,可以选择逃跑策略。
  4. 避免条件语句过多:使用策略模式可以有效减少代码中的条件语句,从而避免代码变得臃肿和难以维护。通过将具体算法实现从具体的业务逻辑中分离出来,可以让算法的变化独立于使用算法的客户端。
  5. 示例代码:以下是一个简单的示例代码,展示了如何在Unity中实现策略模式:
// 攻击策略类
public class AttackStrategy : IStrategy
{public void PerformAction(){Debug.Log("Attacking");}
}// 移动策略类
public class MoveStrategy : IStrategy
{public void PerformAction(){Debug.Log("Moving");}
}// 防御策略类
public class DefenseStrategy : IStrategy
{public void PerformAction(){Debug.Log("防御");}
}// 策略选择器
public class StrategySelector
{private IStrategy _strategy;public void SetStrategy(IStrategy strategy){_strategy = strategy;}public void PerformAction(){_strategy.PerformAction();}
}// 主脚本
public class Player : MonoBehaviour
{private StrategySelector _selector;void Start(){_selector = new StrategySelector();_selector.SetStrategy(new AttackStrategy());_selector.PerformAction(); // 输出:Attacking// 根据条件切换策略if (playerHealth < 50){_selector.SetStrategy(new DefenseStrategy());_selector.PerformAction(); // 输出:防御}}
}

策略模式的优势

  1. 算法独立性:策略模式使得算法可以独立于使用它的客户端变化。这意味着可以根据不同的游戏状态、角色类型或玩家选择,动态地改变游戏的行为。
  2. 灵活性和多态性:通过将算法封装在独立的策略类中,策略模式提供了一种更灵活的方式来处理多态行为。这使得算法的变化不会影响到使用这些算法的客户。
  3. 简化复杂条件逻辑:策略模式能够减少对象间的相互依赖,并且将与特定状态相关的行为局部化到一个状态中,从而满足单一职责原则。游戏开发设计模式之策略模式

六、组合模式

七、命令模式

八、装饰器模式

相关文章:

游戏开发中常用的设计模式

目录 前言一、工厂模式二、单例模式三、观察者模式观察者模式的优势 四、状态模式状态模式的优势 五、策略模式策略模式的优势 六、组合模式七、命令模式八、装饰器模式 前言 本文介绍了游戏开发中常用的设计模式&#xff0c;如工厂模式用于创建对象&#xff0c;单例模式确保全…...

【PyCharm】远程连接Linux服务器

【PyCharm】相关链接 【PyCharm】连接Jupyter Notebook【PyCharm】快捷键使用【PyCharm】远程连接Linux服务器【PyCharm】设置为中文界面 【PyCharm】远程连接Linux服务器 PyCharm 提供了远程开发的功能&#xff0c;使得开发者可以在本地编辑代码或使用服务器资源。 下面将详…...

InVideo AI技术浅析(五):生成对抗网络

一、特效生成 1. 工作原理 特效生成是计算机视觉中的高级应用,旨在通过算法生成高质量的视觉特效,如风格迁移、图像到图像的翻译等。InVideo AI 使用生成对抗网络(GAN)来实现这一功能。GAN 通过生成器和判别器两个网络的对抗训练,生成逼真的视觉特效。 2. 关键技术模型…...

Spring自定义BeanPostProcessor实现bean的代理

上文中&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145241149 大致了解了spring aop的代理的实现&#xff0c;其实就是有个BeanPostProcessor代理了bean对象。 本文直接编写最简单的代码直观感受下 bean A: Service public class A {public A() {System.…...

【HF设计模式】06-命令模式

声明&#xff1a;仅为个人学习总结&#xff0c;还请批判性查看&#xff0c;如有不同观点&#xff0c;欢迎交流。 摘要 《Head First设计模式》第6章笔记&#xff1a;结合示例应用和代码&#xff0c;介绍命令模式&#xff0c;包括遇到的问题、采用的解决方案、遵循的 OO 原则、…...

Linux使用SSH连接GitHub指南

基础配置流程 步骤1:生成SSH密钥 打开终端:首先,打开你的Linux终端。 生成SSH密钥对:输入以下命令来生成一个新的SSH密钥对: ssh-keygen -t rsa -b 4096 -C "your_email@example.com"-t rsa:使用RSA加密算法生成密钥。-b 4096:密钥长度为4096位,增加安全性。…...

v2富文本框封装 @wangeditor/editor-for-vue

1 组件封装 <template><div class"editor-container"><div class"editor-wrapper"><Toolbarstyle"border-bottom: 1px solid #ccc":editor"editor":defaultConfig"toolbarConfig":mode"mode&quo…...

【分类】【损失函数】处理类别不平衡:CEFL 和 CEFL2 损失函数的实现与应用

引言 在深度学习中的分类问题中&#xff0c;类别不平衡问题是常见的挑战之一。尤其在面部表情分类任务中&#xff0c;不同表情类别的样本数量可能差异较大&#xff0c;比如“开心”表情的样本远远多于“生气”表情。面对这种情况&#xff0c;普通的交叉熵损失函数容易导致模型…...

AUTOSAR从入门到精通-自动驾驶测试技术

目录 前言 算法原理 测试场景定义与作用 测试场景要素 测试场景分类 场景信息提取与挖掘方法 自动驾驶感知测试分类 自动驾驶图像系统测试 自动驾驶激光雷达系统测试 自动驾驶融合感知系统测试 自动驾驶仿真测试 1. 功能安全 2. 预期功能安全 3. 软件测试 4.敏捷…...

优化大型语言模型的表达能力和依赖关系:理论

摘要 随着自然语言处理技术的发展&#xff0c;大型语言模型&#xff08;LLM&#xff09;已经成为理解和生成人类语言的强大工具。然而&#xff0c;如何有效提升这些模型的表达能力以及捕捉长距离依赖关系仍然是一个挑战。本文通过具体实例探讨了词表大小&#xff08;em_size&a…...

在Ubuntu下使用Wine运行MobaXterm并解决X服务器问题

MobaXterm是一款功能强大的终端模拟器&#xff0c;集成了SSH客户端和X服务器&#xff0c;常用于远程服务器管理。在Ubuntu下&#xff0c;我们可以通过Wine运行MobaXterm&#xff0c;同时解决X服务器问题&#xff0c;实现远程图形界面转发。这对于需要远程使用ROS&#xff08;如…...

【鸿蒙】0x02-LiteOS-M基于Qemu RISC-V运行

OpenHarmony LiteOS-M基于Qemu RISC-V运行 系列文章目录更新日志OpenHarmony技术架构OH技术架构OH支持系统类型轻量系统&#xff08;mini system&#xff09;小型系统&#xff08;small system&#xff09;标准系统&#xff08;standard system&#xff09; 简介环境准备安装QE…...

SW - 钣金零件保存成DWG时,需要将折弯线去掉

文章目录 SW - 钣金零件保存成DWG时&#xff0c;需要将折弯线去掉概述笔记备注END SW - 钣金零件保存成DWG时&#xff0c;需要将折弯线去掉 概述 如果做需要弯折的切割件&#xff0c;最好做成钣金零件。 最近做了几个小钣金(将钣金展开&#xff0c;建立新草图&#xff0c;在2…...

JAVA使用自定义注解,在项目中实现EXCEL文件的导出

首先定义一个注解 Retention(RetentionPolicy.RUNTIME) Target(ElementType.FIELD) public interface Excel {/*** 导出时在excel中排序*/int sort() default Integer.MAX_VALUE;/*** 导出到Excel中的名字.*/String name() default "";/*** 首行字段的批注*/String …...

【GIS操作】使用ArcGIS Pro进行海图的地理配准(附:墨卡托投影对比解析)

文章目录 一、应用场景二、墨卡托投影1、知识点2、Arcgis中的坐标系选择 三、操作步骤1、数据转换2、数据加载3、栅格投影4、地理配准 一、应用场景 地理配准是数字化之前必须进行的一项工作。扫描得到的地图数据通常不包含空间参考信息&#xff0c;需要通过具有较高位置精度的…...

flutter在使用gradle时的加速

当我使用了一些过时的插件的时候&#xff0c;遇到了一些问题 比如什么namespace 问题等&#xff0c;因为有些插件库没有更新了&#xff0c;或者最新版本处于测试阶段 于是我就删除这些旧插件(不符合我要求的插件) 于是根据各论坛的解决方法去做了以下的工作 1:项目中删除了这…...

ABP - 缓存模块(1)

ABP - 缓存模块&#xff08;1&#xff09; 1. 与 .NET Core 缓存的关系和差异2. Abp 缓存的使用2.1 常规使用2.2 非字符串类型的 Key2.3 批量操作 3. 额外功能 1. 与 .NET Core 缓存的关系和差异 ABP 框架中的缓存系统核心包是 Volo.Abp.Caching &#xff0c;而对于分布式缓存…...

二、点灯基础实验

嵌入式基础实验第一个就是点灯&#xff0c;地位相当于编程界的hello world。 如下为LED原理图&#xff0c;要让相应LED发光&#xff0c;需要给I/O口设置输出引脚&#xff0c;低电平&#xff0c;二极管才会导通 2.1 打开初始工程&#xff0c;编写代码 以下会实现BLINKY常亮&…...

双端队列实战 实现滑动窗口 用LinkedList的基类双端队列Deque实现 洛谷[P1886]

集合 关系 介绍 Deque 是一个接口 LinkedList 是这个接口的实现类 题目 输入输出 滑动窗口 基于双端队列实现 Deque<Integer> deque new LinkedList<>(); 滑动窗口代码 public static List<Integer> maxSlidingWindow(int[] nums, int k) {List<Int…...

HTML<img>标签

例子 如何插入图片&#xff1a; <img src"img_girl.jpg" alt"Girl in a jacket" width"500" height"600"> 下面有更多“自己尝试”的示例。 定义和用法 该<img>标签用于在 HTML 页面中嵌入图像。 从技术上讲&#x…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...