Anda di halaman 1dari 16

Design Pattern - Uma Abordagem para jogos digitais

Renato Elibio de Oliveira Ribeiro1, Rainer Mansan Vieira2


1

Instituto de Informtica Universidade do Vale do Rio dos Sinos (UNISINOS) Caixa Postal 275 93.022-000 So Leopoldo RS Brazil
elibio@gmail.com, rainermv@gmail.com

Abstract. This paper explains four methodology Design Patterns in games development. The usage is based in the approach from Design Patterns in the classic solutions and come to game developer, such as know how the heuristics can be good performances. It's a view about practical model example of the good and reusable practices. Resumo. Este artigo explica em torno de quatro Padres de Projeto em desenvolvimento de jogos. O uso baseado na abordagem dos Padres de Projeto em solues clssicas e como chegam aos desenvolvedores de jogos, como conhecer como as heursticas podem resultar em boas performances. uma viso sobre o modelo de exemplo prtico dos mtodos bons e reutilizveis .

1. Introduo
Os design Patterns, traduzidos como padres de projeto so tcnicas que buscam melhoras as prxis de programao e otimizao de resultados. As quatro tcnicas enfocadas neste artigo so Template Method, Proxy, Factory Method e State, uma breve anlise de cada um e possveis solues sero aqui propostas desenvolvidas e modeladas. A contextualizao e conceituao sero abordadas por cada um dos mtodos nas pginas a seguir, explicando desta forma o funcionamento e aplicao de cada um.

2. Factory Method
O Factory Method um padro de projeto, qu possua caracterstica de agrupar famlias de Classes sem a necessidade criao concretas das mesmas. Em forma de implementao as classes do Factory Method seriam abstratas ou interfaces(para uma linguagem de programao com suporte a Interfaces). Este padro de projeto instancia(cria objetos) em suas classes concretas, deixando a responsabilidade da implementao dos mtodos para suas subclasses, ou seja cada classes tem seu prprio mtodo de execuo de uma tarefa. O padro de projeto Factory Method, muito utilizado em Frameworks (conjunto de pacotes de Classes com ferramentas para desenvolvimento de aplicativos que controla os domnios de uma aplicao).

2.1 Desenvolvimento de Jogos Digitais e suas Solues O desenvolvimento de jogos digitais envolve muitos desafios de criao e implementao, de forma geral so utilizadas diversas APIs (Application Programming Interface ou seja pacotes de programao para aplicativos), desta forma para desenvolver jogos digitais tratam-se de situao de muita programao de baixo nvel ou construo de toda estrutura de Software (programas de computador). As prticas de programao de jogos sempre envolvem a construo de Frameworks, Engines (Motores), APIs ou mdulos com funcionalidades bem definidas. As diversas situaes encontradas no desenvolvimento de jogos e a necessidade de otimizao e melhoria constante, exige que as ferramentas de criao construdas sejam extensveis, e acima de tudo simplificadas para agregao de novas funcionalidades ou novos dados inseridos em um jogo. 2.2 Abordagem em Jogos Digitais do Factory Method Os jogos necessitam de forma geral, so estendidos em vrias verses e possuem muitas mudanas de comportamentos internas. Pela anlise deste tipo de desenvolvimento e o padro de projeto Factory Method, pode-se exemplificar em um mdulo de render(desenhar), como estudo de caso. O renderizador de um jogo responsvel pela sua realizao visual, comparando com termos tcnicos da computao de aplicativos comerciais, seria responsvel pela View (viso do usurio ou jogador) da aplicao, em suma os grficos. Um mdulo de render, poderia ser otimizada em um motor que pode criar vrios jogos, deixando a responsabilidade de desenho para cada jogo, e cada jogo poderia ter seu prprio mtodo desenhar independente da plataforma ou do jogo em si. Um simples exemplo de modelo seria o visualizado abaixo na Figura 1-Mdulo Render.

Figura 1. Modelo Render

Note que no modelo acima da Figura 1, a classe Render representa uma interface, e a MduloRender uma classe concreta, sendo a criao funo do mtodo elementoGrfico, que cria os objetos que o desenvolvedor desejar. Percebe-se no modelo aplicado que o ModuloRender no conhece os mtodos das suas subclasses, sendo elas as responsveis pela forma de desenharem a si mesmas, deixando a responsabilidade do tipo de desenho nos objetos criados. A forma apresentada deixaria o motor sem responsabilidade de renderizar cada objeto, sendo que se muda a API grfica, ou desenha de formas diferentes cada jogo. Alm de dividir as responsabilidades das classes, o desempenho do motor melhoraria do ponto de vista do papel do motor (de construir toda interao de um jogo e compor os conjuntos de mdulos com suas responsabilidades). A instanciao de objetos modularizada, facilita tambm questes de desempenho da memria, sendo que um padro de projeto do grupo de criao.

3. State - estado
O padro State relacionado a comportamento ou padro de estados, ele referencia o estado em que um objeto se encontra, e de acordo com este valor pode mudar o comportamento do algoritmo. A utilizao do padro de projeto State, trata dados internos dos objetos instanciados, desta forma ele consulta o objeto para alterar o comportamento do

programa conforme o resultado adquirido. Esta atualizao permite um maior controle em tempo de execuo por exemplo, bem como aumenta o controle de fluxo de dados. O State possui uma abstrao de contexto, ou seja uma classe abstrata que gerencia o contexto e faz as requisies de aes ao objeto, interagindo com o solicitante(Objeto/ cliente).O estado que define, a forma no qual cada objetos pode interagir no programa, e as subclasses possuem o comportamento que o contexto exige. Este padro de projeto reduz o uso excessivo do IFs (Condicional SE) , podendo aplicar regras relacionados ao estados e evocando os mtodos desejados de acordo com contexto[Silveira 2011]. 3.1 Desenvolvimento de Jogos Digitais e Estados O desenvolvimento de jogos digitais possui diversos aspectos comportamentais, em suma todos tem mudana de contexto, basta verificar um Gameplay(Jogabilidade e diverso) de um jogo, no qual encontra-se regras em todas suas fases e nveis. Os algoritmos de balanceamento, que so os responsveis pelo equilbrio do jogo, buscando um Gameplay justo, sem trapaas ou nveis de dificuldades acima das expectativas positivas ou negativas do jogador. Pode-se ento pensar no balanceamento como uma srie de estados e regras pr-definidas que comportamentalmente podem mudar o rumo de um jogo. A usabilidade de tcnicas de balanceamento e IA (Inteligncia Artificial), esto entre os procedimentos, mais complexos aos desenvolvedores, pois se tratam de metodologias que orientam todo o fluxo de jogo. 3.2 Mquina de estados em Jogos Digitais com State Os jogos necessitam de forma geral, de uma IA que controle os NPCs (Non player character ou personagens no controlados pelo jogador), tratando-os como entidades autnomas que se adaptem as regras do jogo. Entre as tcnicas de IA, a mquina de estados um elemento essencial que auxilia no controle de personagens autnomos de um jogo digital. Observe um exemplo na tabela abaixo, que simula um personagem que ataca, defende e move: Ao/ Estado Atacando Defendendo Movendo
Tabela 1. Modelo Render

Luta

Busca

Ferido

Ferido Luta Busca

A tabela acima exemplifica uma simples mquina de estado finitos, no qual possui um ciclo de comportamento do personagem, verifica-se que a necessidade de uam atualizao constante de em qual valor o estado se encontra fundamental para o funcionamento para esta tcnica.

Um modelo pensado para a Mquina de Estados proposta, criar subclasses que possuam a operao que requisita os estados dos objetos criados, logo o contexto com participao do jogador ter de atualizar os estados internos de cada NPC.

Figura 2. Modelo de Mquina de Estados

O modelo gerado para o quadro da tabela 1 e a figura 2, mostram que todos personagens criam-se aparentemente com mtodos iguais, mas todos possuem um mtodo atualizar no qual um pode ser passado como parmetro para a Classe PersonagemEstado, que de acordo com o objeto recebido, utiliza o mtodo atualizar para sabe o estado e executar um dos mtodos implementados(atacar, mover, defender). Esta seria uma forma simplificada de interagir com uma mquina de Estados que controla os personagens de um jogo, conforme contexto(fase). Esta mudana de comportamento permite por exemplo que se crie novos comportamentos aos personagens do jogo em qualquer fase de implementao ou at expanses posteriores com portabilidade.

3. Proxy Tambm conhecido como Surrugate, o Proxy age como um marcador da localizao de outro objeto, documento, conexo ou outro recurso, mantendo uma interface para este. O Proxy pode manter uma referncia que o permite acessar

o objeto real, tambm pode controlar o acesso ao objeto real e pode ser responsvel pela sua criao e excluso.

Figura 3. Estrutura de um Proxy

3.2. Motivao Alguns objetos podem ser muito caros para serem criados na inicializao, assim, requerindo-se que sua criao seja adiada at o momento em que realmente precisamos utiliz-lo. Porm, sendo necessrio que esse adiamento no seja percebido pelas outras classes, utiliza-se um objeto Proxy que substitui temporariamente o objeto em questo, tomando conta de sua instanciao quando essa for necessria. 3.3. Aplicao O padro Proxy aplicavel sempre que h uma necessidade de uma referncia mais verstil, ou sofisticada, do que um simples apontador para um objeto. Abaixo algumas situaes comuns nas quais o padro Proxy aplicvel: Um Remote Proxy fornece um representante local para um objeto em um espao de endreamento diferente. Um Virtual Proxy cria objetos caros sob demanda, por exemplo, mantendo um Proxy para uma imagem grande que mantm seu nome de arquivo, carregando-o quando for necessrio que a imagem seja mostrada.

Um Protection Proxy controla o acesso ao objeto original, sendo teis quando estes objetos devem ter diferentes direitos de acesso. Um Smart Reference um substituto para um ponteiro que executa aes adicionais quando um objeto acessado. Usos tpicos incluem: o Contar o nmero de referncias para o objeto real, de modo que o mesmo possa ser liberado automaticamente quando no houver mais referncias. o Carregar um objeto persistente para a memria quando ele for referenciado pela primeira vez. o Verificar se o objeto real est bloqueado antes de ser acessado, para assegurar que nenhum objeto possa mud-lo.

Quando deve-se existir mltiplas cpias de um objeto complexo, possvel adaptar o padro Proxy para incorporar o Padro Flyweight, reduzindo o gasto de memria. Uma instncia do objeto complexo e mltiplos objetos proxy so criados, todos contendo uma referncia para o objeto original. Quaisquer operaes realizadas nos proxies so enviadas para o objeto original, e caso todas as instncias do proxy ficarem fora do escopo, a memria do objeto complexo pode ser desalocada. 3.4. Consequncia O padro Proxy introduz um nvel de referncia indireta no acesso a um objeto. A referncia indireta adicional tem muitos usos, dependendo de seu tipo: Proxy Remoto: oculta o fato de que um objeto reside em um espao de endereamento diferente. Proxy Virtual: pode executar otimizaes, tais como a criao de um objeto sob demanda. Proxy de proteo e Smart Reference: permitem tarefas adicionais de organizao (housekeeping) quando um objeto acessado.

Uma otimizao que o padro Proxy pode realizar chamada de copy-on-write, relacionada criao de um objeto sob demanda. Fazer a cpia de um objeto grande e complicado pode ser demasiada cara e desnessria caso essa cpia no seja modificada. Utilizando um proxy para postergar o processo de cpia, o preo da cpia do objeto pago somente quando ele for modificado. Essa abordagem pode reduzir significamente o custo computacional da cpia de objetos muito pesados. 3.4. Exemplos Exemplo 1: Um editor pode embutir objetos grficos em um documento, mas tais objetos so muito caros para serem criados, a ponto de deixar muito lenta a abertura destes documentos. A soluo evitar que todos estes objetos grficos so criados no momento da abertura, utilizando Proxies Virtuais para substituir todos os objetos que no estaro visveis em primeiro momento.

O Proxy de imagem cria a imagem real somente quando o editor solicita ao mesmo exibir a si prprio invocando sua operao de Desenho. O proxy repassa as solicitaes subsequentes diretamente para a imagem. Portanto, ele deve manter uma referncia para a imagem aps cri-la, assim como sua extenso, ou seja, sua altura e altira isso permite ao proxy esconder as solicitaes sobre o seu tamanho, oriundas do formatador, sem ter que efetivamente instanciar a imagem.

Figura 2. Diagrama de Classes do exemplo 1

O Editor acessa as imagens embutidas atravs da interface definida pela classe abstrata Grfico. ProxyImagem uma classe para imagens que so criadas sob demanda, que mantm o nome do arquivo como uma referncia para a imagem no disco e passado como um argumento para o construtor de ProxyImagem. Um ProxyImagem tambm armazena os limites da imagem (extenso) e uma referncia para a instncia real de Imagem (nome_arquivo). Essa referncia no ser vlida at que o Proxy instancie a imagem real. A operao Desenha garante que a imagem instanciada antes de repassar a ela a solicitao. GetExtenso repassa a solicitao para a imagem somente se ela estiver instanciada; caso contrrio, ProxyImagem retorna a extenso armazenada. Exemplo 2: Focando-se no desenvolvimento de jogos, poderia-se carregar Proxies para os inimigos da fase contendo seu tipo e sua localizao. O objeto ProxyInimigo carregaria o inimigo

real, contendo seu modelo, sons, e outros atributos caros somente no momento que ele ficasse prximo ao jogador a primeira vez ou quando estes fossem necessrios.

class Inimigo { void Atualiza(); void Ataca(); }

class InimigoReal : public Inimigo { private float posio; private String tipo; private Modelo modelo;

public InimigoReal(String _tipo, float pos) { posio = pos; tipo = _tipo; modelo = CarregaModelo(tipo); sons = CarregaSons(tipo); }

private Modelo CarregaModelo(String _Tipo) { return novo_modelo; }

public void Atualiza() { cout << tipo << andou << endl; cout << tipo << atualizou animao << endl; cout << tipo << atacou! << endl

class InimigoProxy : public Inimigo { private float posio; private String tipo; private InimigoReal inimigo;

public InimigoProxy (String _tipo, float pos) { tipo = _tipo; posio = pos; }

public void Atualiza() { cout << atualizando << tipo << endl;

if (jogadorPrximo) // se monstro estiver prximo ao jogador { if (inimigo == null) inimigo = new InimigoReal(tipo); inimigo->Atualiza(); }

else{ cout << tipo << andou << endl; ; }

} }

class Esemplo int main( {

Inimigo elfo = new InimigoProxy(elfo, 15); // longe do jogador Inimigo jogador orc = new InimigoProxy(orc, 5); // prximo ao

elfo.Atualiza(); Orc.Atualiza();

return 0; } }

Sada do programa:

Atualizando Elfo Elfo andou

Atualizando Orc Orc andou Orc atualizou animao Orc atacou!

Exemplo 3: Em um jogo multiplayer, um Remote Proxy pode ser utilizado para facilitar a comunicao entre Cliente/Servidor. O programa rodando no servidor conversaria com o usurio atravs de um objeto Cliente real, e os outros jogadores atravs de um proxy cliente, que envia, pela rede, os dados para seu correspondente do outro lado (tambm um Cliente real). A utilizao de um Proxy para essa funo mantm a comunicao entre os clientes transparente.

4. Template Method
O padro de projeto Template Method definido por uma funo com comportamento abstrato que define o esqueleto de um algoritmo de uma operao, permitindo que subclasses redefinam passos deste algoritmo, sem modificar sua estrutura.

Figura 3. Estrutura de um Template

4.1. Motivao Algumas vezes, como na implementao de um framework, necessrio especificar a ordem de operaes que o mtodo utiliza, mas permitir que subclasses forneam suas prprias implementaes de algumas essas operaes. 4.2. Aplicao Um Template Method pode ser utilizado para implementar as invariantes de um algoritmo uma nica vez, deixando para as subclasses a implementao dos seus comportamentos. Tambm til para evitar a duplicao de cdigo, quando partes comuns entre subclasses podem ser fatoradas e concentradas numa s classe-me. Uma outra utilizao de Templates controlar as extenses de subclasses, sendo definido um mdodo-template que chama operaes gancho em pontos especficos - operaes gancho fornecem um comportamento padro que subclasses podem estender se necessrio. 4.3. Consequncia Template Methods so considerados fundamentais para reutilizao de cdigo, principalmente em bibliotecas de classe, pois so os meios para a fatorao dos comportamentos comuns. Esse padro de projeto utiliza, portanto, uma estrutura chamada de o princpio de Hollywood, que referencia a como uma classe-me chama as operaes de uma subclasse, ao invs do contrrio. Mtodos-template chamam os seguintes tipos de operaes: Operaes concretas Operaes concretas de AbstractClass (ou seja, operaes teis para subclasses em geral) Operaes primitivas (abstratas). Mtodos Factory. Operaes Gancho.

Quando utiliza-se um Mtodo Template, deve-se especificar quais operaes so ganchos (que podem ser redefinidas) e quais delas so abstratas (que devem ser redefinidas) os codificadores de subclasses devem compreender quais as operaes so projetadas para redefinio. Uma subclasse ainda pode estender o comportamento de uma operao de uma classe-me pela redefinio da operao e chamando a operao-me explicitamente: void DerivedClass::Operation() { ParentClass::Operation(); // comportamento estendido de DerivedClass }

4.4. Exemplos Exemplo 1: Um framework para aplicaes possui uma classe LeitorArquivos, responsvel por abrir documentos e salvar em um objeto Documento.
class LeitorArquivos { void AbreDocumento() // Template { if (!PodeAbrirDocumento(nome)){ // no consegue tratar este documento return; Documento* doc = CriaDocumento();

doc->Salvar(doc);

ApsAbrirDocumento();

} }

void CriaDocumento(); // abstrata bool PodeAbrirDocumento(); // abstrata void ApsAbriDocumento(); // abstrata };

Um usurio deste framework pode ento criar uma subclasse de LeitorImagens para atender suas necessidades especficas para a funo de abrir documento. Nesse caso uma aplicao de editor de imagens pode utilizar o leitor para abrir imagens, salvar em memria e mostrar na tela, utilizando uma subclasse LeitorImagens:

class LeitorImagens : public LeitorArquivos { void CriaDocumento(){

// L arquivo e salva pixels da imagem }

bool PodeAbrirDocumento(){ // Checa se o formato compatvel }

void ApsAbrirdocumento(){ // mostra a imagem na tela }

};

Exemplo 2: Um motor de Jogos possui uma classe Cena que guarda todos os objetos guardados nela. Quando ela carregada, chama uma funo Load (template) que carrega os objetos do mapa e ento chama uma funo Hook, que pode ser usada para fazer qualquer definio especfica da cena desejada. Desse modo, a cena ser carregada mesmo se a funo Hook no for implementada por uma subclasse.
class Cena { public: void CarregaCena();

void Hook(); private: Objeto[] array_obj; };

void Cena::CarregaCena() { for (Objeto in array_obj){ objeto.inicializa();

Hook(); }

Referncias
Silveira, Guilherme. Como no aprender orientao a objetos. http://blog.caelum.com.br/como-nao-aprender-orientacao-a-objetos-o-excesso-de-ifs/ acessado em 25/06/2012. Gamma, Erich and Richard H. and Ralph J. and n John Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software, 1994 Wikipedia article on State, http://pt.wikipedia.org/wiki/State , 25/06/12

Wikipedia article on Factory Method, http://pt.wikipedia.org/wiki/Factory_Method,


27/06/12 Wikipedia article on Proxy Pattern. en.wikipedia.org/wiki/Proxy_pattern, 27/06/12 Wikipedia article on Template Method Pattern. en.wikipedia.org/wiki/Template_method_pattern, 26/06/12