Padrões de Projeto em Games – Command

Olá gurizada, estamos de volta :)

Nova fase, novo layout, novas colunas e, principalmente, novo ritmo aqui para o Abrindo o Jogo. No retorno, nada melhor do que voltar com mais um post do arco de padrões de projeto, muito pedido pelos leitores.

Desta vez, trago para os leitores o padrão de projeto Command, muito utilizado em jogos de estratégia e editores gráficos. É comum também vermos este padrão ser utilizado em conjunto com outros, tais como o Memento.

A bibliografia técnica descreve que o comportamento deste padrão seria encapsular uma solicitação como um objeto, permitindo parametrizar clientes com diferentes solicitações, enfileirar ou fazer o registro das solicitações. Este padrão suporta operações que podem ser desfeitas.

Observe o diagrama de classes abaixo para ter uma ideia geral das classes que são necessárias para utilizar o Command.

Podemos observar no diagrama a Classe abstrata ou interface Command definindo um tipo único para todos os comandos do seu jogo. Em seguida, podemos identificar o ConcreteCommand, que seria o comando propriamente dito. Esta classe deve armazenar o objeto que receberá a ação do comando, identificado por Receiver no diagrama.

Um exemplo clássico, bastante didático, seria o de pedidos de refeições em um restaurante. O Garçom recebe uma requisição de prato específico. Neste contexto ele representa o Client em nosso diagrama de classes, criando várias ordens de pedidos para atender os clientes famintos e apressados. As ordens de pedidos, representam os Commands, com a descrição exata do que deve ser feito. O Receiver neste exemplo, é o cozinheiro, que irá executar a ação descrita no pedido, por exemplo, Bife com Fritas. Observe o diagrama abaixo:

É possível perceber que a abordagem ajuda o cozinheiro a não se perder, pois enquanto ele cozinha um dos pratos, as ordens de pedido se acumulam em uma fila.

Este padrão em game é amplamente utilizado em jogos de estratégia Point and Click, tais como Diablo, Age of Empires e até no recente StarCraft II. Um exemplo seria, ao invés de acionar diretamente o método shoot em um objeto Solder, você cria um objeto ShootCommand com esta ação e, em seguida, o executa. Ele por sua vez, que irá acionar o método shoot do objeto Solder. Esta abordagem permite que o seu game possa receber mais comandos do que realmente pode executar, pois ao finalizar um ele chama o próximo. O mesmo padrão também permite que você remova os comandos anteriores se um novo chegar.

Uma utilização muito interessante seria utilizar o Command junto com o Memento. Imagem um game em que o jogador possa criar um Checkpoint no tempo, podendo voltar para aquele momento e rever tudo o que ocorreu no game. Neste contexto, bastaria armazenar um único memento daquele momento e executar todos os comandos gerados a partir dali. A grande diferença aqui seria a redução de memória, pois não haveria a necessidade de armazenarmos todos os mementos, ocupando um grande espaço de memória.

E ai? O que acharam deste padrão? Vamos discutir mais sobre ele nos comentários.

Um grande abraço e aguardem as novidades já para o início desta semana. ;)

5 Responses to “Padrões de Projeto em Games – Command”

  • Regis Machado says:

    Boa Everton,

    Explicou bem o command, apesar de ser um dos padrões mais simples as vezes fica difícil saber como utilizado no jogo ou mesmo em um sistema.

    Eu gosto de usar muito ele principalmente com eventos, assim desacoplando totalmente a entidade, ação e comportamento..
    e deixo que um gerenciador de eventos se encarregue de executar os comandos.

    O memento mais o command também foi muito boa a dica, essa combinação é muito boa pra fazer o famoso efeito crtl+z, o que em jogos de tatics é bastante usado pra que o jogador experimente todas as possibilidades antes de passar o turno.

    Abraços.. e continuem assim.

  • Gostei do artigo, o exemplo é bem didático.
    Eu só fiquei em dúvida numa coisa: os comandos são enfileirados e executados em ordem, mas como proceder para chamar o próximo comando Y quando o comando X termina? Num caso de game, p. ex., em que uma ação leva certo tempo para realizar, outra um tempo diferente etc., seria necessário criar algum gerenciador de eventos, que irá captar quando algum Command disparar que sua ação foi completa?

    • everton.vieira says:

      Olá Francisco,

      Exatamente! As ações/command possuem uma arquitetura bem definida. Cada objeto deve possuir um “execute” e um “finish”. Seu encerramento dispara um evento, neste caso “onFinish”. O Gerenciador ouve este evento e chama o próximo comando.

Leave a Reply