Padrões de Projeto em Games – Command | Abrindo o Jogo
Publicado em 17/07/2011, por Everton Vieira - Postado em Padrão de Projeto 6
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 Soldier, 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 Soldier. 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. Imaginem 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.
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. 😉
6 Comentários em "Padrões de Projeto em Games – Command"
Regis Machado 18/07/2011 at 10:13 - Reply
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.
Francisco Prado 08/05/2012 at 09:12 - Reply
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 08/05/2012 at 09:51 - Reply
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.
Francisco Prado 09/05/2012 at 16:10 - Reply
Legal. Eu gosto da série do AoJ sobre padrões de projeto em games, vocês pretendem continuar a seção? Abs
everton.vieira 10/05/2012 at 09:29 - Reply
Sim, estaremos logo postando mais episódios.
Edson 04/11/2016 at 08:46 - Reply
Nesse contexto Everton, na sua opinião, com quem o Padrão Command se parece mais, dentre todos os padrões existentes?