Header Ads

Game design - Criando cenários

Postado: na M.Cassab
Estado: falta muito para as 17h30 ?
Escutando: DeepPurple - El Desdichado II (acústico)

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.

Com conceitos discutidos e compreendidos, vamos ao que interessa: a pratica.

Infelizmente, não estou com muito tempo para ficar estudando os tutoriais do site Tile based games e propor atualizações nos métodos. Por este motivo, vou postar tudo na integra, do jeito que está em ActionScript 1 mesmo.

Mas não fique desanimado. Acho que vai ser mais fácil entender o conceito usando programação em ActionScript 1 do que uma versão mais atual.

Se quiser algo mais avançado, o Matheus Prestes publicou no fórum iMasters um tutorial muito legal usando ActionScript 2. Ele até explica como montar a estrutura de classes. Se acessar o tutorial, tenha educação e poste um agradecimento para ele no fórum.

1º Passo: desenhar as imagens do cenário

Vamos continuar com o velho exemplo: uma sala sem porta com duas colunas dentro, ou seja, nosso cenário necessitará apenas de dois gráficos, uma imagem para o chão e outra para as paredes da sala.

No assunto passado (Planejando um cenário), definimos que nossa tela terá 240 de largura (width) e 180 de altura (height), com 8 colunas e 6 linhas com 30px de altura e largura.

De uma forma bem simples, no final do processo deverá ficar igual ao exemplo que o Tony disponibilizou em seu site:


Esse SFW foi criado pelo Tony para o site Tile based games
e está sendo utilizado sob sua autorização.

No Flash, crie um arquivo e altere o tamanho do palco para 240px width e 180px de height.

Em nosso exemplo, precisamos de apenas dois gráficos para representar o que é chão e o que é obstáculo (paredes e colunas). Então, para facilitar, vamos criar apenas um quadrado com duas cores.

Agora, crie um quadrado de 30px/30px e transforme em movieClip. É muito importante que o registro dele, que será utilizado como ponto zero, esteja posicionado no canto superior esquerdo para que seja inserido corretamente.

No primeiro frame, deixe a penas o contorno do quadrado e no segundo o quadro todo preenchido, além do contorno. Volte ao palco e delete o movieClip.

Abra a biblioteca e localize o movieClip que acabou de criar. Clique com o botão direito e altere suas propriedades. Em Linkage (não lembro como é na versão em português), indique um nome para relacionar o movieClip dinamicamente (vou deixar o meu como tile)e marque as opções para exportar por ActionScript e exportar no primeiro frame.

Você acabou de criar os gráficos que será usado para construir o cenário. O frame só com o contorno será utilizado para representar o chão (onde o personagem pode andar) e o preenchido para representar a área que bloqueará o caminho (as paredes e as colunas).

Agora, vamos fazer uma gambiarra para servir como plano para agrupar os objetos do cenário.

Crie outro quadrado de qualquer tamanho e transforme em movieClip. Porém, desta vez, deixe o registro no centro.

Abra a biblioteca, localize-o e altere suas propriedades, indique um nome (vou chamar o meu de empty por pura preguiça de dar um nome melhor). Não esqueça de marcar as opções para exportar por ActionScript e exportar no primeiro frame.

Ainda na biblioteca, clique duas vezes sobre ele para editá-lo e delete todo o conteúdo do key frame. É... é isso mesmo que você leu, pode excluir tudo.

Na verdade, esse movieClip é vazio mesmo. Essa gambiarra é necessária para que todas as imagens sejam inseridas dentro de um objeto. Se elas forem inseridas diretamente no palco principal (_root), você terá muito trabalho no futuro para fazer as verificações.

2º Passo: declarar as propriedades do cenário

Até agora, sua timeline principal, não deve ter apenas um único frame vazio (se não tiver, arrume). Abra o painel de ActionScript para declararmos as propriedades dos nossos objetos, começando pela matriz do cenário:

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]
];


Em nossa matriz, a posição que conter o número 1 será o obstáculo e a posição com o número 0 o chão.

Agora, vamos criar um objeto chamado "game", que será usado para agrupar todos os parâmetros de nosso cenário.

game={tileW:30, tileH:30};

Note que, dentro do objeto "game", declaramos dois parâmetros, que estão informando o tamanho de cada posição da matriz que ira compor nosso cenário.

Tome muito cuidado com esses valores, pois eles serão responsáveis pelo alinhamento dos objetos, deixando um exatamente encostado no outro.

Agora, vamos declarar as propriedades de cada "parte" de nosso cenário. Primeiro, vamos incluir uma função no objeto que criamos.

game.Tile0 = function (){};

Essa função será utilizada pelo objeto que formará o chão. Por enquanto, vamos nos limitar aos aspectos principais do objeto. O chão deve ser uma imagem que permita o personagem andar por cima. Então, vamos incluir uma propriedade indicando isso.

game.Tile0.prototype.walkable = true;

Depois, vamos informar em qual frame a imagem está localizada no movieClip.

game.Tile0.prototype.frame = 1;

Com essas três apenas, poderemos substituir a função hiTest, tornando nosso jogo um pouco mais rápido.

Agora, vamos declarar as propriedades "parte" do cenário que representará os obstáculos, contendo a pripriedade que evita andar por cima e o frame em que a imagem está localizada no movieClip.

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


3º Passo: função construtora

Depois de ter declarado todas as propriedades do jogo, vamos a função de construção.

function buildMap (map) {
     _root.attachMovie("empty", "tiles", ++d);
     game.clip=_root.tiles;
     var mapWidth = map[0].length;
     var mapHeight = map.length;
     for (var i = 0; i < mapHeight; ++i) {
         for (var j = 0; j < mapWidth; ++j) {
             var name = "t_"+i+"_"+j;
             game[name]= new game["Tile"+map[i][j]];
             game.clip.attachMovie("tile", name, i*100+j*2);
             game.clip[name]._x = (j*game.tileW);
             game.clip[name]._y = (i*game.tileH);
             game.clip[name].gotoAndStop(game[name].frame);
         }
     }
}


Calma, respire fundo e não entre em desespero. A função é bem simples, só parece ser complicada. Tecnicamente, ela está realizando as seguintes ações:

  • Anexar um movieClip na cena

  • Verificar a posição indicada na matriz

  • Criar novos objetos para cada posição

  • Anexar todos os objetos (tiles) na cena

  • Colocar os objetos (tiles) na posição correta

  • Exibir a imagem definida na matriz para cada objetos (tiles)


A primeira linha declara e nomeia a função como buildMap. Dentro dos parênteses, é indicado uma variável externa que será utilizada dentro da função. Mais para frente, essa vaariável será substituida pela matriz do cenário.

A segunda linha é responsável por criar e inserir dinamicamente um movieClip no palco.

_root.attachMovie("empty", "tiles", ++d);

Agora, vamos vincular um parâmetro ao nosso objeto "game".

game.clip=_root.tiles;

Esse parâmetro ficará responsável por anexar dinamicamente o movieClip da biblioteca e permitir que possa ser alterado por código. Isso facilitará muito para criarmos interatividade com as ações do jogador.

Agora, vamos criar duas variáveis que vão indicar qual será o tamanho (linhas e colunas) do cenário.

var mapWidth = map[0].length;
var mapHeight = map.length;


Baseado no valor dessas variáveis, criaremos um "teste de mesa" (se nunca ouviu isso antes, é bom rever seus conceitos) em que será verificado a posição de cada vetor da matriz.

for (var i = 0; i < mapHeight; ++i) {
for (var j = 0; j < mapWidth; ++j) {


O conseito é simples: o SWF verificará se existe um vetor, qual sua posição e imagem que deverá ser exibida. Depois de fazer isso, ele passa para o próximo vetor e vai fazendo isso, ponto a ponto, até terminar a matriz.

A próxima linha criará um nome para a imagem (ou objeto) que está sendo inserida no momento. O segredo da programação é que cada elemento tenha nome, sobrenome, RG e CPF... ou algo próximo disso. No fundo, no fundo, o nome do elemento nada mais é do que sua posição na matriz.

var name = "t_"+i+"_"+j;

Agora, vamos criar uma lista dentro do objeto "game" onde será inserido o elemento atua e suas propriedades.

game[name]= new game["Tile"+map[i][j]]

Finalmente, nas próximas linhas, o raio do elemento será inserido, indicando seu nome individual, posição na tela (X e Y), altura (tileH) e largura (tileW) e qual imagem deverá ser exibida.

game.clip.attachMovie("tile", name, i*100+j*2);
game.clip[name]._x = (j*game.tileW);
game.clip[name]._y = (i*game.tileH);
game.clip[name].gotoAndStop(game[name].frame);


4º Passo: Executar a função construtora

Com a função construtora pronta, basta executála, indicando a matriz que será usada como referência.

buildMap(myMap);

Depois de tudo isso é só publicar o SWF apra ver no que vai dar.

Conclusão

Se você fez tudo certo, você terá apenas um único frame vazio em sua timeline contendo exatamente a seguinte ActionScript:

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]
];

game = {tileW:30, tileH:30};

game.Tile0 = function () { };
game.Tile0.prototype.walkable = true;
game.Tile0.prototype.frame = 1;

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

function buildMap (map) {
     _root.attachMovie("empty", "tiles", ++d);
     game.clip=_root.tiles;
     var mapWidth = map[0].length;
     var mapHeight = map.length;
     for (var i = 0; i < mapHeight; ++i) {
         for (var j = 0; j < mapWidth; ++j) {
             var name = "t_"+i+"_"+j;
             game[name]= new game["Tile"+map[i][j]];
             game.clip.attachMovie("tile", name, i*100+j*2);
             game.clip[name]._x = (j*game.tileW);
             game.clip[name]._y = (i*game.tileH);
             game.clip[name].gotoAndStop(game[name].frame);
         }
     }
}

buildMap(myMap);


Perceba que tudo foi declarado dentro do objeto "game". Logo, tudo que precisará alterar ou verificar em relação ao cenário poderá ser realizado por meio desse objeto que está agrupando todos os parâmetros e argumentos.

Isso facilitará muito sua vida no futuro, quando precisará programar eventos e outras funções.

Considerações

Provavelmente, você não deve ter entendido completamente o código... nem eu. Por isso, faça alguns estudos para perceber o potencial disso tudo.

Apenas experimentando novas possibilidades é que passará a entender como as "coisas funcionam".

Comece declarando tamanhos diferentes para as imagens para ver no que vai dar. Lá no começo, você declarou o tamanho de cada imagem assim:

game={tileW:30, tileH:30};

Experimente declarar assim, talvez mudando os valores:

game.tileW = 30;
game.tileH = 30;


Claro que se você mudar os valores vai dar erro. Mas faça mesmo assim e veja o erro. Isso pode ajudar a entender como o comando influencia na construção do cenário.

No começo, você também declarou as propriedades da imagem:

game.Tile0 = function () { };
game.Tile0.prototype.walkable = true;
game.Tile0.prototype.frame = 1;


Crie novas imagens e altere os valores. Faça um movieClip com vários frames e mude os números na matriz. Crie outros cenários e entenda como se comporta a função.

Por falar nela, a função está construindo um cenário em um único plano (bidimensional) dentro do movieClip empty. Justamente por estar dentro de um objeto, você pode criar outras funções para planos diferentes (conversaremos sobre isso no futuro), trabalhando com outras perspectivas e fundos variados.

O que você tem que ter em mente é que a função construtora necessita de uma matriz para construir o cenário e o número do Level para saber em que ordem deverá exibir.

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

Próximo assunto:
Experimentar novos cenários

Um comentário:

  1. Olá tudo bem amigão? gostei muito dos seus turtoriais, valeu em, continue sempre assim, compartilhando do connhecimento...
    vc é 10!!!!!!!!
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    ResponderExcluir

Tecnologia do Blogger.