[Unity Notes] Aplicação de padrões de design no desenvolvimento de jogos

Aplicação de Padrões de Projeto no Desenvolvimento de Jogos

Recentemente, ao estudar a aplicação de padrões de design no desenvolvimento de jogos , descobri que eles podem realmente melhorar a eficiência do desenvolvimento, especialmente no ajuste e manutenção posteriores do código.
Então, escrevi este artigo e registrei brevemente minha experiência de aprendizado, para que eu possa me inspirar ao revisá-lo no futuro.

Perceber

  • Este artigo apenas resume os possíveis cenários de aplicação dos padrões de projeto no desenvolvimento de jogos com base em livros e materiais da Internet, e não explica os princípios dos padrões de projeto.
  • Em aplicações práticas, geralmente há casos em que vários padrões de projeto são usados ​​em combinação. Este artigo é classificado por padrões de design e haverá situações em que o mesmo cenário de uso aparecerá em vários padrões de design.
  • No desenvolvimento real, algumas funções podem ter outros métodos de implementação ou alguns padrões de design podem ter outros cenários de aplicação. A lista neste artigo pode estar errada ou não ser abrangente o suficiente. Suas correções e acréscimos são bem-vindos.

Padrões de design criacional

1. Solteiro

O padrão singleton é amplamente utilizado no desenvolvimento de jogos. O padrão singleton garante que haja apenas uma instância de uma classe e fornece um ponto de acesso global para obter essa instância.

cenas a serem usadas ilustrar
gerente de jogo Responsável pelo processamento da lógica central do jogo, como estado do jogo, progresso do nível, etc., pode ser usado em combinação com o modo de aparência
gerenciador de áudio Idem para o efeito
gerente de interface do usuário idem
Vários gerenciadores de módulos idem
persistência de dados idem
Cliente de jogo online Use o modo singleton para limitar o número de conexões, evitar que o uso indevido gere muitas conexões e evitar falhas no servidor
ferramenta de registro -

Embora o modo singleton seja conveniente, ele deve ser usado o mínimo possível:
"O modo singleton também viola o princípio de abertura e fechamento, pois o objeto obtido pelo método Instance é a classe de implementação e não a classe de interface. Portanto, quando o design muda ou os requisitos aumentam, o designer do programa não pode ser substituído por outras classes, mas apenas o código do programa na classe de implementação original pode ser alterado, portanto, o requisito de fechar a modificação não pode ser atendido." —— "Design
Patterns e Desenvolvimento de Jogo Perfeito"

O padrão singleton pode ser utilizado para modularizar o código.O uso direto do padrão singleton (Singleton) pode levar a confusão de código e dificuldade de manutenção por não haver restrição de acesso.
Um padrão singleton completo deve aumentar as restrições de acesso. Por exemplo, o contêiner IOC (Inversion of Control) é introduzido para obter o efeito de um modo singleton com restrições de acesso consultando o dicionário.
Se você comparar a estrutura do código do jogo com a instalação e a instância única com as linhas de conexão de vários módulos importantes, a introdução de um contêiner IOC equivale a adicionar um "gerenciador de cabos" (muitos outros padrões de design também têm essa função) .
O uso do contêiner IOC pode facilmente escrever código que esteja em conformidade com os princípios de inversão de dependência (D) e responsabilidade única (S).


2. Padrão de método de fábrica (Método de Fábrica)

O padrão de método de fábrica fornece uma maneira de separar a criação e o uso de objetos.Ao definir uma interface de fábrica, as subclasses podem decidir quais objetos específicos produzir.

cenas a serem usadas ilustrar
geração de personagem Usando o padrão de método de fábrica, você pode definir uma interface de fábrica de função e, em seguida, implementar classes de fábrica específicas para cada tipo de função (como jogadores, inimigos, NPCs, etc.), que podem ser usados ​​com o padrão de construtor
geração de ferramentas Você pode definir uma interface de fábrica de adereços e, em seguida, implementar classes de fábrica específicas para cada tipo de adereço (como armas, armaduras, consumíveis, etc.)

3. Padrão Abstract Factory (Fábrica Abstrata)

O padrão Abstract Factory fornece uma interface para criar uma série de objetos relacionados ou dependentes sem especificar suas classes concretas. O sistema pode decidir qual grupo de subclasses produzir de acordo com o ambiente de execução atual.

cenas a serem usadas ilustrar
carregamento de recursos Usando o padrão de fábrica abstrato, você pode criar classes de fábrica correspondentes para diferentes tipos de recursos, de modo a obter uma interface unificada de carregamento de recursos
criação de IU Diferentes classes de fábrica de interface podem ser fornecidas para ajudar a realizar a reutilização e personalização de componentes de interface do usuário
geração de nível Você pode criar uma classe de fábrica para diferentes tipos de nível (como floresta, deserto, cidade, etc.), que contém diferentes conteúdos e elementos gerados, e você pode usar o padrão abstrato de fábrica ao adicionar novos tipos de nível
geração de ferramentas Idem para o efeito

Padrão de fábrica abstrato e padrão de método de fábrica

Padrão de fábrica abstrato:

  • Classe Fábrica Abstrata - *Interface de Fábrica - *Classe de Implementação de Fábrica - *Produzir Produtos
  • Fácil de expandir, não é fácil de modificar

Padrão de método de fábrica:

  • Interface de Fábrica - Aulas de Implementação de Fábrica - *Produzir Produtos
  • É fácil ter muitos produtos novos e fazer a fábrica explodir

(* indica que pode haver mais de um)


4. Modo Construtor (Construtor)

O padrão builder separa o processo de construção de um objeto complexo de sua representação, de forma que o mesmo processo de construção possa criar diferentes representações de objetos. (montagem passo a passo)

cenas a serem usadas ilustrar
geração de personagem Os personagens podem ser criados em etapas e fornecem diferentes combinações (como atributos, habilidades, efeitos especiais, comportamentos de IA, etc.), o que permite a criação flexível de personagens
geração de nível O processo de construção do mapa pode ser dividido em etapas, cada etapa é responsável por processar um elemento específico do mapa (como terreno, edifícios, adereços, etc.)
geração de ferramentas Adereços e equipamentos podem ser criados em etapas (como poder de ataque, poder de defesa, durabilidade, etc.), proporcionando combinações flexíveis

5. Protótipo

O padrão Prototype cria novos objetos copiando objetos existentes (protótipos), em vez de usar métodos de construção tradicionais.

cenas a serem usadas ilustrar
Carregamento de recursos do jogo GameObject.Instance no Unity é um padrão de protótipo

Padrões de Design Comportamentais

6. Modo de estado (Estado)

O padrão State permite que um objeto mude seu comportamento quando seu estado interno muda.

cenas a serem usadas ilustrar
gerenciamento de estado de função Gerencie o status da função. Para estados como parado, correndo, pulando, patrulhando, atacando, etc., usando o padrão de estado, a lógica e o comportamento de cada estado são encapsulados em uma classe separada, tornando a lógica de alternância entre os estados do personagem mais clara
Nível de jogo ou troca de cena Gerenciar troca de nível e cena, comportamento lógico
Menu do jogo e gerenciamento de estado da interface do usuário Como menu principal, interface de configuração, menu de pausa, etc. O modo de estado pode simplificar a lógica de comutação entre essas interfaces, tornando o sistema de interface do usuário mais modular e fácil de manter

Modo de estado e máquina de estado finito (Finite State Machine, FSM)

O padrão de estado pode ser visto como uma implementação orientada a objetos de uma máquina de estado finito. Transições de estado e comportamento de estado em uma máquina de estado finito podem ser representados mais claramente usando o padrão de estado.
No desenvolvimento de jogos, o padrão de estado pode ser usado para implementar máquinas de estado finito para gerenciar transições de estado e comportamento de objetos.


7. Modo Mediador (Mediador)

O modo intermediário é usado para reduzir o acoplamento entre vários objetos e concentrar a interação entre os objetos em um "objeto intermediário" para processamento. (hub de interação entre vários subsistemas)

cenas a serem usadas ilustrar
Interação entre subsistemas Pode ser usado como um hub de interação entre os subsistemas do jogo
sistema de IU O modo intermediário pode ser usado para extrair o relacionamento complexo de interação da interface do usuário de cada elemento da interface do usuário e concentrá-lo em um objeto intermediário para processamento
interação entre personagens A lógica de interação, como diálogos e transações entre funções, pode ser separada dos objetos de função e objetos intermediários podem ser introduzidos para processamento
sistema de eventos Concentre a lógica de processamento de eventos, como jogadores sendo derrotados e itens sendo coletados em um objeto intermediário para simplificar o processo de publicação e assinatura de eventos (recomenda-se o modo de observador)

8. Estratégia

O padrão Strategy permite alterar dinamicamente o comportamento de um objeto em tempo de execução. Usando o padrão Strategy, você pode encapsular um conjunto de algoritmos intercambiáveis ​​em um conjunto de classes independentes, simplificando seu código e melhorando a capacidade de manutenção e extensibilidade.

cenas a serem usadas ilustrar
Cálculo de atributos de personagem Você pode usar o padrão de estratégia para separar diferentes atributos e métodos de cálculo para fácil modificação e uso
geração de nível Diferentes algoritmos de geração de nível podem ser encapsulados como um conjunto de classes independentes, e a estratégia de geração de nível pode ser alternada dinamicamente conforme necessário em tempo de execução
Ajuste de Dificuldade do Jogo idem

Padrão de Estratégia vs. Padrão de Estado

"Estado é alternar entre um grupo de estados, e há um relacionamento correspondente e conectado entre os estados; Estratégia é composta por um grupo de classes que não têm relacionamento e não conhecem a existência umas das outras. O estado é limitado pelo regras de comutação da máquina de estados, no
projeto Todos os estados possíveis serão definidos no estágio inicial, mesmo que sejam adicionados posteriormente, eles precisam ser relacionados aos estados existentes, em vez de adicioná-los assim que quiserem; Estratégia é um padrão de design formado pelo encapsulamento de algoritmos de computação, e não há relação entre os algoritmos. Dependência, novos algoritmos podem ser adicionados ou substituídos imediatamente." ——
"Padrões de design e desenvolvimento perfeito de jogos"


9. Método de modelo

O padrão de método de modelo define o esqueleto de um algoritmo em um método e abstrai algumas etapas repetitivas de subclasses para superclasses. Dessa forma, os métodos de modelo permitem que as subclasses redefinam certas etapas de um algoritmo sem alterar a estrutura do algoritmo. (Processo geral)

cenas a serem usadas ilustrar
Carregamento de nível A estrutura básica do carregamento de nível (como pré-carregamento de recursos, inicialização de cenas, carregamento de personagens etc.)
sistema de realização Você pode usar o padrão de método modelo para definir uma classe abstrata de conquistas, que contém métodos básicos de verificação de conquistas e implementa lógica específica de verificação de conquistas em subclasses
Entrar no jogo online O processo de login é corrigido por meio do modo de método de modelo, como exibir a tela de login, selecionar o método de login, inserir a senha da conta, enviar uma solicitação ao servidor etc., para que a subclasse da função de login possa realizar operações específicas

10. Modo de comando (Comando)

命令模式将请求封装为对象,将客户端的不同请求参数化,并配合队列、记录、复原等方式来执行请求操作。

使用场景 说明
交互逻辑 在MVC框架中,可以用于分担 Controller 层的交互逻辑,让很多混乱的交互逻辑代码从 Controller 迁移到 Command 中
操作记录 通过存储已执行的命令对象,可以轻松实现撤销和重做功能(如移动单位、放置建筑等)。可用于实时策略游戏和编辑器等场景
事件系统 可以将一系列事件通过命令模式封装起来,使其可以更灵活的调用

在凉鞋老师的框架中:

  • 事件由 系统层 向 表现层 发送
  • 表现层 只能用 Command 改变底层系统层的状态(数据)
  • 表现层 可以直接查询数据

11. 责任链模式(Chain of Responsibility)

责任链模式为请求创建了一个接收者对象链。这些接收者对象按顺序处理请求,直到其中一个处理了该请求为止。

使用场景 说明
关卡切换 可以设置各关卡切换条件,当条件达成时跳转到对应关卡。在通关判断上,可以配合策略模式,让通关规则具有其他形式变化
AI决策 将不同的AI行为链接在一起,让AI根据当前情况处理决策请求,从而实现灵活的AI行为控制

12. 观察者模式(Observer)

观察者模式定义了一种一对多的依赖关系,当一个对象(主题)的状态发生变化时,所有依赖于它的对象(观察者)都将得到通知并自动更新。

使用场景 说明
事件系统 可以实现一个全局的游戏事件系统,当某个事件触发时,所有订阅了该事件的对象都会收到通知并作出相应处理
成就系统 监测游戏中的各种事件(如角色升级、任务完成、特定敌人击败等),当满足成就条件时,自动解锁相应的成就并通知玩家

观察者模式 与 中介者模式

两者结构相同,但使用场景不同。
观察者模式可以理解为了使业务逻辑更加清晰,从中介者模式中分离出一种专门处理事件订阅与分发的设计模式(笔者的粗浅理解)。


13. 备忘录模式(Memento)

备忘录模式在不破坏对象封装的前提下,捕获对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

使用场景 说明
游戏存档 可以利用备忘录模式保存玩家的角色状态、关卡进度、游戏设置等信息
状态回滚 在角色受到负面效果或需要恢复到之前状态时,可以使用备忘录模式回滚角色属性
撤销操作 在游戏编辑器或游戏中的一些可撤销操作,可以通过备忘录模式记录并恢复对象的状态

14. 访问者模式(Visitor)

访问者模式可以定义一个能够在一个对象结构中对于所有元素执行的操作。访问者可以让你定义一个新的操作,而不必要更改到被操作元素的类接口。被访问者需要开放足够的操作方法和信息。

使用场景 说明
统计数据 在对游戏中的各种对象(如角色、敌人、道具等)进行统计时,可以使用访问者模式来实现,避免修改原有类定义
辅助管理类 当需要对各种对象(如角色、敌人、道具等)的“管理容器”类添加功能时,可以通过访问者模式减少对原有代码的更改

15. 迭代器模式(Iterator)

在不知道集合内部细节的情况下,提供一个按序方法存取一个对象集合体的每一个单元。(遍历)

使用场景 说明
遍历对象 循环语句(如 for 循环)就可以实现迭代器模式

16. 解释器模式(Interpreter)

定义一个程序设计语言所需要的语句,并提供解释来解析(执行)该语言。(翻译)

使用场景 说明
表达式计算 可以使用解释器模式来解析和计算游戏中的各种表达式

结构型 设计模式

17. 外观模式(Facade)

在游戏开发中,外观模式常被用于简化复杂系统的交互。通过为多个子系统提供一个统一的接口,将复杂的内部逻辑抽象为简单的调用。(高级封装)

使用场景 说明
音频管理器 创建一个音频管理器类,可以简化音频播放、暂停、停止等操作的调用。只需通过音频管理器接口来控制音频播放,无需关注音频资源的加载和播放器的创建
UI管理器 将UI系统中的交互逻辑,如按钮点击事件、文本显示等操作,封装在一个UI管理器类中,简化UI组件的访问和修改,同时降低UI系统与其他系统之间的耦合度
数据持久化 创建一个保存管理器类,可以简化保存和加载过程,同时方便后期扩展更多的存储功能

18. 桥接模式(Bridge)

桥接模式用于将抽象与实现分离,使它们可以独立地变化。使抽象类作为不同实现类间的桥梁。

使用场景 说明
角色与装备 可以将角色、装备的抽象与具体实现分离,使不同种类的角色可以搭配和使用不同种类的装备
输入系统 可以将输入设备(如键盘、鼠标、游戏手柄等)的抽象与具体实现分离,从而简化输入设备的管理和扩展,同时保持游戏逻辑的独立性
游戏资源管理 游戏资源(如纹理、模型、声音等)可能需要支持多种格式和来源(如本地文件、网络下载、内存中的数据等)。可以将资源的抽象与具体实现分离
网络系统 可以将网络协议(如TCP、UDP、Websockets等)的抽象与具体实现分离,从而简化网络协议的管理和扩展

19. 享元模式(Flyweight)

享元模式的主要目标是通过共享相同的对象,来减少内存占用和提高性能。

使用场景 说明
游戏对象属性共享 将游戏中大量具有相同属性的游戏物体中的相同部分提取出来,进行统一管理

20. 组合模式(Composite)

组合模式将对象组合成树形结构以表示层次结构。组合模式使得客户端可以以一致的方式处理单个对象和对象组合。

使用场景 说明
UI层次结构 通过使用组合模式,可以轻松地组织和管理树型UI菜单,实现事件传递和布局调整等功能
游戏任务逻辑 可以将任务、子任务和条件等逻辑元素组织成树形结构,实现逻辑的判断和执行等功能

21. 装饰模式(Decorator)

装饰模式允许在不改变原始对象结构的情况下,动态地向对象添加新功能,从而实现功能的组合和扩展。

使用场景 说明
角色属性修改 可以通过装饰模式增加角色的属性(如生命值、攻击力、防御力等)
游戏界面扩展 可以游戏界面添加额外的功能(如特效、动画、音效等),这样实现起来比较灵活,修改也方便
数据加密解密 -

装饰模式已有目标增加功能非常方便,但是要避免盲目使用导致系统过于混乱,应将可能需要的功能列在早期的开发计划中。


22. 适配器模式(Adapter)

适配器模式将一个类的接口转换成另一个类所期望的接口,使得原本接口不兼容的类可以一起工作,提高组件的复用性和扩展性。(转接口)

使用场景 说明
第三方库集成 当需要集成不同的第三方库(如广告、支付、社交等)时,可以使用适配器模式统一接口,方便切换和扩展不同的第三方库
输入设备兼容 可以统一不同输入设备(如键盘、鼠标、手柄等)的接口,实现多种输入设备的兼容和扩展
游戏引擎升级 当游戏引擎升级后,一些接口可能发生变化,使用适配器模式可以降低升级带来的影响
网络通信协议适配 在多人在线游戏中,可能需要支持多种网络通信协议(如TCP、UDP、WebSocket等),可以使用适配器模式统一接口,方便扩展和切换不同的通信协议

23. 代理模式(Proxy)

代理模式为其他对象提供一种代理以控制对这个对象的访问。代理模式可以用于延迟加载、安全控制、日志记录等功能。

使用场景 说明
优化测试 可以使用代理模式测试游戏优化的效果,以免去修改原始类的接口及实现
网络代理 在多人在线游戏中,可以使用代理模式处理与服务器的通信,方便进行数据加密、压缩、缓存等操作

在学习设计模式的过程中,我发现设计模式其实是面向对象的数据结构。
一个由0和1组成的系统,通过各种各样的数据结构和算法,层层编织出能够模拟现实的游戏世界,这实在是太美妙了!

Acho que você gosta

Origin blog.csdn.net/Dugege007/article/details/130331557
Recomendado
Clasificación