Comentários
- " Talvez haja outro design mais específico para a programação de jogos padrões que eu nem conheço? " – não, esses padrões são genéricos e se aplicam mais para estender os recursos da linguagem que você ' re usin g. Eles não têm nada a ver com o assunto da sua aplicação.
- @Kylotan Parece do meu ponto de vista limitado que, uma vez que cada padrão de design se destina a resolver um problema específico de maneira eficaz, por sua natureza alguns padrões de design seriam mais úteis do que outros, dado um conjunto de problemas específico, ou seja, neste caso, aqueles conjuntos de problemas exclusivos para o desenvolvimento de jogos. Certamente existem algumas diretrizes, ou com base na sua experiência, padrões de design específicos que você usa com mais frequência do que outros?
- Antes que alguém saia e aprenda 1000 padrões de design diferentes, leia este e este
- @ BlueRaja-DannyPflughoeft O link Secon é inválido. Você pode reenviar
Resposta
Agora, para uma resposta menos irreverente, com algumas sugestões. Não tome isso como recomendações de implementação, mais como exemplos de uso possível.
- Construtor: configure uma entidade baseada em componente por vez, com base em dados
- Método de fábrica: crie NPCs ou widgets GUI com base em uma string lida de um arquivo
- Protótipo: armazene um caractere “Elfo” genérico com propriedades iniciais e crie instâncias Elf clonando-o.
- Singleton: este espaço deliberadamente deixado em branco.
- Adaptador: incorpore uma biblioteca opcional de terceiros envolvendo-a em uma camada que se parece com o seu código existente. Muito útil com DLLs.
- Composto: faça um gráfico de cena de objetos renderizáveis ou faça uma GUI de uma árvore de Widgets
- Fachada: simplifique bibliotecas complexas de terceiros fornecendo uma interface mais simples para tornar sua vida mais fácil mais tarde.
- Flyweight: armazene os aspectos compartilhados de um NPC (por exemplo, modelos, texturas, animações) separadamente dos aspectos individuais (por exemplo. posição, saúde) em um forma principalmente transparente
- Proxy: crie pequenas classes em um cliente que representam classes maiores e mais complexas em um servidor e encaminhe solicitações pela rede.
- Cadeia de responsabilidade: manipule a entrada como uma cadeia de manipuladores, por exemplo. teclas globais (por exemplo, para capturas de tela), depois a GUI (por exemplo, no caso de uma caixa de texto estar em destaque ou um menu aberto) e o jogo (por exemplo, para mover um personagem)
- Comando: encapsular a funcionalidade do jogo como comandos que podem ser digitados em um console, armazenados e reproduzidos, ou mesmo com script para ajudar a testar o jogo
- Mediador: implemente entidades de jogo como uma pequena classe de mediador que opera em diferentes componentes (por exemplo, leitura do componente de saúde para passar os dados para o componente de IA)
- Observador: faça com que a representação renderizável de um personagem ouça eventos da representação lógica, a fim de alterar a apresentação visual quando necessário, sem a lógica do jogo precisa saber alguma coisa sobre o código de renderização
- Estado: armazene NPC AI como um dos vários estados, por exemplo. Atacando, Vagando, Fugindo. Cada um pode ter seu próprio método update () e quaisquer outros dados necessários (por exemplo, armazenar de qual personagem está atacando ou fugindo, a área em que está vagando, etc.)
- Estratégia: alternar entre heurísticas diferentes para sua pesquisa A *, dependendo do tipo de terreno em que você está, ou talvez até mesmo para usar a mesma estrutura A * para encontrar caminhos e planejamento mais genérico
- Método de modelo: configurar um rotina de “combate” genérica, com várias funções de gancho para lidar com cada etapa, por exemplo, diminuir a munição, calcular a chance de acerto, resolver acerto ou erro, calcular o dano e cada tipo de habilidade de ataque implementará os métodos em sua própria maneira específica
Alguns padrões deixados de fora por falta de inspiração.
Comentários
- Uma discussão muito esclarecedora sobre singletons pode ser encontrada aqui: misko.hevery.com / 2008/08/25 / root-cause-of-singletons
- +1 para o padrão de estratégia. Eu ' usei exatamente para o propósito declarado acima (conectar diferentes heurísticas A *).
- obrigado por esta resposta, elas parecem mais com padrão de design do que o usual " singleton " i ' m ouvindo em todos os lugares …
- Ótima lista de exemplos. Apesar do abuso crônico do padrão singleton (estado global disfarçado), existem usos legítimos: Quando ele representa um recurso do qual você realmente só possui (ou deseja) um. Isso pode ser algo como embrulhar hardware (por exemplo, teclado / mouse) ou embrulhar uma biblioteca que não é reentrante (isso acontece, e nem todos os idiomas têm palavras-chave de sincronização mágicas).
- Eu ainda não ' t use singletons para recursos de hardware – itens que você acha que ' apenas 1 tende a se multiplicar mais tarde, assim como placas de vídeo e monitores fizeram como o anos se passaram. Da mesma forma, em algumas APIs, você precisa ler 2 joysticks para entender 1 gamepad. Então, eu ' d dizer, se você só precisa de um de algo, apenas instancie um único, não ' t imponha restrições arbitrárias que provavelmente não são ' necessários.
Resposta
Eu escrevi uma livro exatamente sobre esse assunto: Padrões de programação de jogos . Os capítulos que estão lá podem ser úteis para você.
Comentários
- +1 Eu esperava que alguém tivesse linkado para isso e vejo que o autor tem! A descrição do padrão de componente foi muito útil e gosto que você tente usar exemplos de código completos para demonstrar.
- Sim – lembro-me de ter lido seu link alguns anos atrás. Você deve terminar esses artigos!
- Agora o livro está terminado 🙂
- Um recurso incrível que me ajudou a traduzir meu conhecimento de programação existente em programação para jogos. Obrigado por escrevê-lo!
- Esta explicação de padrões de programação de jogos realmente me ajudou a entender -padrões de design- de uma maneira que nenhum livro de padrões de design de software realmente ajudou! Isso é em parte o poder do desenvolvimento de jogos (exemplos concretos em uma linguagem que fala comigo e me permite melhorar meu desenvolvimento geral), mas em grande parte porque a escrita é excelente.
Resposta
Uma coisa que Brandon Eich teve o bom senso de mencionar em Codificadores no trabalho é que os padrões são hacks e soluções alternativas: [Padrões] mostram algum tipo de defeito na linguagem. Esses padrões não são gratuitos. Não há almoço grátis. Portanto, devemos procurar evolução na linguagem que adiciona as partes certas.
Como programadores de jogos, e não designers de compiladores, raramente temos a opção de evoluir as linguagens usamos, mas podemos aprender a desenvolver nosso próprio estilo para melhor se adequar a nossa linguagem e requisitos. Padrões são algumas delas, mas não usar padrões é outra parte, especialmente porque, como diz Brandon, padrões raramente funcionam sem um desempenho notável ou custo de memória ou agilidade de código. MVC simplesmente não é um ótimo padrão para muitas coisas em jogos. Singleton é uma solução alternativa para regras de inicialização estática C ++, e você provavelmente não deveria fazer isso de qualquer maneira. Factory simplifica a criação de objetos complicados – talvez seus objetos devam ser mais simples para começar. Os padrões populares são ferramentas às quais podemos recorrer quando precisamos para gerenciar algo complexo, não ferramentas que deveríamos desejar usar para construir algo complexo no início.
Um bom código (de jogo) pode usar padrões ou não. Se ele usar padrões, tudo bem – eles são uma ótima ferramenta de comunicação para explicar a estrutura do código a outros programadores em um alto nível independente de linguagem. Se você acha que o código é melhor sem usar um padrão, não se culpe isso – provavelmente é.
Comentários
- Sim, uma das coisas que ficou claro no livro original (mas muitas vezes esquecido) é que se foram escritos para C em vez de C ++ / Smalltalk, eles podem ter incluído um padrão de " Herança " e, pelo mesmo token, alguns as linguagens podem conter alguns dos padrões GoF já integrados.
- A outra coisa frequentemente esquecida no livro original (o livro original de Alexander, não GoF) é que os padrões são uma ferramenta para comunicação , não implementação . Eles permitem que os designers se comuniquem sobre a implementação em um nível superior e são identificados porque são recorrentes, não necessariamente porque devem ser usados quando possível.
- No entanto, apenas ter a terminologia pode ajudá-lo a raciocinar sobre o problema e reconhecer quando essa abordagem é uma boa solução.Os melhores padrões têm sido refinados ao longo do tempo por trabalhadores qualificados e experientes, e trabalhadores menos qualificados não descobririam os mesmos padrões sem que houvesse esses exemplos codificados.
- Concordo que ter a terminologia é ótimo, e parte da definição de um padrão é que ele é uma boa solução recorrente para algum problema. Infelizmente, os trabalhadores menos qualificados tendem a encontrar principalmente Singleton e aplicá-lo a todos os problemas, mesmo quando ainda não há um problema.
- Obrigado por esta resposta; Sinto-me aliviado ao ler que os padrões de design são feitos para resolver problemas criados pelo design do ' do software. Acho que a estrutura de um grande software deve ser pensada do início ao fim antes de começar a codificar qualquer coisa. Você pode ' nem sempre implementar funcionalidades uma vez por vez, às vezes você tem que pensar sobre cada recurso específico e verificar se ganhou ' Não mexa na estrutura global do software ou apenas atrapalhe a maneira como o software deve se comportar. Dividir tarefas para vários programadores pode, às vezes, criar contradições …
Resposta
Claro, como outros disseram , todos os padrões são úteis nas circunstâncias certas e parte do aprendizado de como usá-los é aprender quando usá-los. No entanto, o excelente livro Core Techniques and Algorithms in Game Programming de Daniel Sanchez-Crespo Dalmau, lista seis padrões de programação e seis padrões de usabilidade como especialmente útil na programação de jogos.
Programação:
- Singleton: Eu não odeio esse aqui como muitas pessoas; ele pode ser usado para coisas como o single- jogador jogador ou leitor de teclado.
- Fábrica: permite criar e destruir objetos de forma eficiente.
- Estratégia: permite alterar estratégias de IA de maneira elegante.
- Índice espacial : Ajuda a realizar consultas em conjuntos de dados espaciais.
- Composto: Configura uma hierarquia de objetos útil.
- Flyweight: libera memória ao generalizar coisas como inimigos idênticos.
Usabilidade:
- Shield: protege contra ativação acidental de ações dramáticas.
- Estado: dicas visuais do mundo / status da IU.
- Cancelamento do modo automático: faz com que o jogo funcione de forma mais intuitiva.
- Ímã ismo: orientação automática e seleção de unidade fácil.
- Foco: eliminando elementos de interface do usuário que distraem.
- Progresso: universalmente útil.
O livro, é claro , entra em mais detalhes sobre cada um deles.
Comentários
- Obrigado pela contribuição! Eu não tinha conhecimento desse livro, mas vou examiná-lo agora como resultado de sua postagem. Obrigado novamente!
- Singleton para o leitor de teclado é exatamente a situação em que eu tenho que perguntar – Você realmente não pode simplesmente torná-lo um ponteiro global definido no início de sua função principal? Você já instanciou acidentalmente dois leitores de teclado?
- Por favor, odeie o singleton. Ele faz duas coisas mal. Acesso global e aridade. Freqüentemente, os desenvolvedores pensam em acesso global == singleton. Existem muito poucos problemas além do necessário para um singleton verdadeiro, e possivelmente alguns mais que são mais elegantes quando resolvidos com um singleton.
Resposta
Sistemas de entidades são um bom tipo de padrão. Não é exatamente um padrão de design, pois não é estritamente OOP. No entanto, você pode misturá-lo com OOP.
Alguns links bons (comece de cima para a introdução):
- http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=387
- http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/
- http://games.fh-hagenberg.at/wiki/index.php?title=Componentbased_entity_systems
Comentários
- " ' não é exatamente um padrão de design, pois ' não é estritamente [sic] OOP. " Os padrões de design não têm nada a ver com OOP; se houver alguma coisa, OOP em si é um padrão de design. Os padrões de design aparecem não apenas fora da OOP, mas inteiramente fora do desenvolvimento de software.
- Existem
OOP design patterns
que normalmente mostram relacionamentos e interações entre classes / objetos. E existem muitos outros padrões de design. OOP é um conjunto de conceitos, não realmente um padrão.Design pattern
também é um conceito. - Em vez de falar sobre semântica, você deve ' avaliar a utilidade de a resposta que dei?
Resposta
Todos eles. Exceto Singleton. [/ flippancy]
Comentários
- Você poderia citar um ou dois padrões de design que ' tenho usado frequentemente no desenvolvimento de jogos e por que motivo?Como um novato em relação aos padrões de projeto, " todos eles " não é uma resposta particularmente útil. Obrigado por responder.
- Perguntar " quais padrões você usou? " é como perguntar " quais nomes de variáveis você usou? " Tudo se resume a estilo pessoal e requisitos e domínio. Em algum ponto, você provavelmente usará qualquer padrão que ' já tenha sido nomeado. Você provavelmente usará muitos mais que não foram nomeados e talvez até invente alguns novos.
- @ jcurrie33: desculpe, eu simplesmente não consegui ' resistir a ter uma escavação em singletons primeiro. 😉
Resposta
Não realmente sobre padrões, mas sobre os princípios básicos por trás deles. Em “Design Patterns: Elements of Reusable Object-Oriented Software” (1995) , o bando de quatro (Gamma, Erich; Richard Helm, Ralph Johnson e John Vlissides) recomenda apenas dois princípios para design orientado a objetos: (1) programar para uma interface e não para uma implementação e (2) favorece a composição de objetos em vez da herança de classes.
Esses 2 princípios são muito úteis em muitas tarefas do jogo desenvolvimento. Por exemplo, muitos programadores de jogos usaram uma hierarquia de classes profunda para representar as entidades do jogo. Há outra abordagem baseada na composição – objetos de jogo baseados em componentes. Artigo sobre essa abordagem. Ainda mais links . É um exemplo de padrão Decorator .
Comentários
- Componentes usados em o design do jogo é mais como um padrão de estratégia com estado – que é naturalmente expresso como fechamentos fora de C / C ++ / Java / C # e como objetos componentes dentro deles. O padrão do decorador é mais como um proxy; sua propriedade e fluxo de dados são opostos aos que normalmente queremos dizer quando falamos sobre sistemas de componentes em jogos.
- Os componentes também precisam se comunicar entre si, trazendo padrões como Mediator, Observer e Composer. " Jogo baseado em componente " é um padrão de design composto por si só.
- @CodexArcanum, Observer, definitivamente , mas nem sempre Mediador (em vez disso, pode-se usar a Cadeia de Responsabilidade). É Composer apenas se GameObject (composto de GameObjectComponent) for o próprio GameObjectComponent (não necessariamente).
Resposta
O padrão de modelo curiosamente recorrente pode ser realmente útil para evitar métodos virtuais e a penalidade de desempenho que pode vir das chamadas de função virtual.
Isso pode ser o padrão apropriado quando você realmente não precisa ter um contêiner do tipo de classe base que tem a interface que você está procurando, mas você gostaria de ter comportamentos e interfaces com nomes semelhantes.
Por exemplo, você pode usar isso ao compilar classes para várias plataformas ou mecanismos (dx vs. opengl) onde a variação do tipo é conhecida em tempo de compilação.
Comentários
- Eu sempre odiei que a camada de abstração do sistema operacional fosse virtual. Ela ' não é como você ' Eu sempre precisarei de dois sistemas camadas. É muito melhor usar CRTP.
- M aybe, eu ' sou apenas velho, mas não ' nem mesmo usaria CRTP para DX / OpenGL ou interfaces de plataforma. É ' muito lento para compilar – Eu ' d apenas usar typedefs. CRTP é bom quando você deseja compartilhar interfaces e implementações entre classes, mas não tem outra relação, não quando você deseja apenas escolher uma estrutura ou outra.
Resposta
Um padrão de design que desenvolvi ao longo de muitos anos, e que tem sido espetacularmente útil para mim, é algo que chamo de “conjuntos de definições intermediários”; como resumi-lo em termos GOF parece ser controverso, mas esta pergunta que escrevi sobre isso no StackOverflow dá alguns detalhes sobre isso.
O conceito central é que alguma propriedade de um modelo, como a espécie de uma criatura, é configurada de forma que cada valor possível para a propriedade tenha um objeto de definição correspondente – um único objeto compartilhado por valor – que especifica seu comportamento , e são acessados por meio de um corretor central (que, no caso do GOF, pode ser um Registro, uma Fábrica ou ambos). No meu uso, eles também são geralmente acessados por meio de chaves escalares, para facilitar a ligação fraca para fins de morfismo em tempo de execução.
Comentários
- Eu não ' não vejo como isso é um singleton e ao discutir o padrão flyweight a palavra " registro " é redundante. Isso é apenas peso-insatisfatório.
- Meu entendimento do thread do SO foi que as pessoas identificaram Singleton como parte dele por causa das definições sendo configuradas como classes. No que diz respeito ao Registro, não ' não vejo como ele pode ser redundante quando pode ser substituído ou combinado com o Factory.
- -1, até o limite os padrões referem-se à comunicação rápida, esta é provavelmente a maior falha que ' já vi. Eu realmente não posso ' não levar essa descrição a sério.
- Jesus, me perdoe por não ser tão simples para você. Você vai votar contra a resposta de " Sistemas de entidades " porque não é ' t instantaneamente resumível em termos GOF?
- Alguma quantidade de " cortador de biscoitos, " ou pelo menos clareza semântica , é exatamente o que os padrões devem ser para serem úteis. Termos como " flyweight " e " singleton " como são comumente entendidos, são mutuamente exclusivos. A primeira é sobre o compartilhamento automático de dados entre várias instâncias; a segunda é sobre ter exatamente uma instância. Eu ' não estou dizendo que sua escolha de design é inútil ou mesmo ruim, mas estou " perto o suficiente " nomes de padrão juntos apenas confundem mais a todos. (Por favor, não ' anote os votos pessoalmente, especialmente no CW.)