Header Ads

Game design - Declarando o terreno

Postado: na M.Cassab
Estado: desidratando por causa da rinite

Atribuição: Uso Não-Comercial


Creative Commons License
O conteúdo desta página foi baseado nos tutoriais contidos no site Tile based games, autorizado sob a licença Creative Commons e não pode ser utilizado para fins comerciais.

A tradução e adaptação dos textos, códigos ActionScripts e todas as outras obras originais criadas por Tonypa foram autorizada é são de propriedade dele.

Attribution: Noncommercial


Creative Commons License
The content on this page was based tutorials in the site Tile based games, licensed under a Creative Commons License and you may not use this work for commercial purposes.

The translation and adaptation of text, ActionScripts codes and all other original works created by Tonypa were authorized is are his property.

No capítulo anterior, tentei explica como funcionava uma Array com duas dimensões e concluí que dizendo que, nesse método, seria necessário dividir a cena em linhas e colunas, que seriam utilizadas mais tarde para indicar a posição dos elementos.

Vamos dizer que estou fazendo um cenário para o jogo The Legend of Zelda, em que o Link (personagem principal), está dentro de uma sala sem porta com duas colunas dentro. O cenário é bem simples, contendo apenas o chão e as paredes da sala (2 tipos de gráficos).

Depois de desenhar em um papel (toda a criação tem que ser SEMPRE no papel para a criatividade e seu estilo de traço flua melhor), digitalizar, desenhar novamente (agora sim você pode usar o Photoshop) e dividir a imagem, cheguei à conclusão de que minha cena terá 8 colunas e 6 linhas.

Sendo assim. a matriz de nossa cena ficaria assim:

myMap = [
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1]
];


Minha cena tem 2 tipos de gráficos, mas o personagem só poderá andar por cima de um deles, no nosso caso, o chão. A matriz acima representa exatamente isso: a posição com número 1 representa a parede e a posição com número 0 representa o chão.. Logo, o personagem poderá andar apenas nos locais onde houver "0".

Agora, como fazer para o sistema saber quando o personagem pode andar ou não ?

Aqui é que está o truque. Segundo o Tony, não é uma boa idéia ficar testando com o comando hitTest porque demora um pouco para retornar o resultado... nunca havia parado para pensar nisso antes.

Ele está certo. Em um jogo, temos vários tipos de objetos e cada um tem um comportamento diferente que influenciará na interatividade do jogo.

Como terreno, pode ser areia, que é parecido com o chão e permite que o personagem ande por cima, mas não com a mesma velocidade, pois se for muito fofo ou úmido (como um brejo ou areia movediça), o personagem terá mais trabalho para se deslocar. Também pode ser água, em que o personagem afunda e é obrigado a nadar.

Além de terrenos, também temos objetos que podem ser obstáculos (paredes, muros ou árvores) ou que permitam manipulação (pedra, baú ou alavanca).

Agora, imagine ficar testando toda hora qual é o elemento que ele "encostou", qual o seu comportamento e quais funções, eventos ou classes devem ser disparadas. Haja processamento.

O Tony inicia seu raciocínio indicando que devemos declarar parâmetros para cada tipo de elemento e cita uma função como exemplo para declarar uma parede:

Tile1 = function (){};
Tile1.prototype.walkable = false;
Tile1.prototype.frame = 2;


Na função acima, ele inclui uma função em um objeto chamado Tile1 (que pode ser um movieClip ou um gráfico da bilbioteca ou até uma imagem externa carregada previamente).

Dentro da função, ele declara que esse objeto barra a movimentação do personagem (walkable = false). o outro parâmetro informa qual imagem será inserida na posição da matriz, mas isso não vem ao caso agora. O que importa é que, dessa forma, posso utilizar esse comportamento para qualquer objeto que não permita a movimentação (parede, coluna, árvore, muro).

Em linguagem técnica, eu não preciso criar um evento para ser acionado quando o personagem tocar no objeto (hitTest). Posso simplesmente criar uma regra (por meio de função ou classe) na própria movimentação do personagem, que testará o valor do parâmetro. Ótimo para quem domina a Programação Orientada para o Objeto.

Como é um teste verificando um caractere e não um objeto, o processamento será mais rápido. Isso pode parecer muito trabalhoso para jogos simples, mas se estiver fazendo um jogo como o Zelda, que tem uma infinidade de fases, vai lembrar da época em que era preciso colocar uma memória de expansão no Nintendo 64 para rodar jogos pesados.

Outro benefício de se utilizar esse método é adotar uma regra padrão para um determinado local. Digamos que, em vez da sala, nossa cena (com 100 colunas por 100 linhas) fosse um campo com apenas 3 árvores.

Não preciso ficar criando uma matriz gigantesca contendo todas as 10.000 posições (lado x lado). Basta declarar que todo aquele local possui a mesma imagem e o mesmo comportamento e criar uma matriz só para os poucos objetos diferentes.

Em vez da matriz 100 x 100, você declararia tudo na classe ou função do local e a matriz ficaria reservada apenas para o que fosse exceção. Neste exemplo, nossa matriz terá apenas as 3 árvores, contendo um vetor para sua posição na cena e outro para a imagem que será utilizada.

trees = [[23,6], [37,21], [55,345]]

Claro, isso é um exemplo válido para cenários simples. Conforme a complexidade da interatividade for maior, fatalmente, a complexidade das regras e do código também será.

Portanto, não assuma tudo isso como regra dogma ou paradigma que deverá ser seguido à risca. Interprete apenas como uma opção.

Cada caso deve ser avaliado antes de iniciar o desenvolvimento. É a premissa básica de um planejamento.

O importante é que você teste as opções e conheça seus benefícios e suas limitações. O método Tile é legal e bacana, e existe um monte de modos para realizar. Mesmo assim, não serve para qualquer jogo.

Isso você só vai descobrir com o tempo, exercitando a mente e experimentando novos conceitos.

Só para fechar, o Tony ainda cita uma alternativa do livro americano Macromedia Flash MX Game Design Demystified, escrito por Jobe Makar, em que se utiliza XML para criar as matrizes.

<map>
     <row>
         <cell type="1">
         <cell type="1">
         <cell type="1">
     </row>
     <row>
         <cell type="1">
         <cell type="4">
         <cell type="1">
     </row>
     <row>
         <cell type="1">
         <cell type="1">
         <cell type="1">
     </row>
</map>


Neste exemplo, ele declarou uma matriz com 3x3 posições, sendo que o número 1 é o chão e o número 4 é a árvore. Por ser um XML, talvez seria interessante criar outros "nós", com os parâmetros de cada elemento.

Pode ser um exemplo válido, caso necessite deixar seu código mais enxuto e rápido.

Só para constar, acho essa questão de integrar XML com Flash um pouco relativa. Para inserir as informações de um XML, você terá que utilizar um objeto do ActionScript para fazer a "conexão", pois não é a linguagem nativa. Logo, terá que executar o objeto, acessar o arquivo, interpretar os dados e retornar algo.

Neste sentido, acho muito mais pratico e rápido criar um arquivo AS separado e colocar lá a matriz em ActionScript mesmo.

Bem, essa é uma discussão que não pretendo entrar no mérito. Prefiro deixar isso para os especialistas que realmente entendem do assunto.

Se quiser, volte ao índice para ver a lista completa do conteúdo.

Próximo assunto:
Planejando um cenário

Nenhum comentário

Tecnologia do Blogger.