Ainda sobre desenvolvimentos de jogos usando AS 3.0 este post é um exemplo de como carregar um cenário com tiles. Esta técnica é muito usada em games plataforma ou RPGs com de visão isométrica, onde vários quadrados (tiles) se unem e formam uma imagem. O lugar e qual peça deve ser encaixada para formar o cenário é representado por uma matriz de coordenadas. Pensando dessa forma uma fase de Super Mario Bros nada mais é que um enorme vetor multidimensional :P
Antes de codificar no flash é preciso um arquivo png com os tiles que formarão seu cenário. No Google imagens é possível encontrar esses arquivos rapidamente. Para este exemplo vou usar os tiles de um dos games de Zelda (Zelda tileSet).
Note as dimensões do bloco de tiles: 256 x 2272 pixels. Esse bloco é formado por tiles de 32 x 32 pixels. Sendo assim podemos mapear esta figura como uma matriz de 7 colunas por 70 linhas onde cada elemento é um tile (tendo a primeira coluna como 0 ).
O trabalho seria muito grande para montar um cenário escolhendo os tiles e anotando sua respectiva posição para gerar a matriz de referencia da cena. Por esta razão vamos usar um editor de mapas que alem de facilitar as coisas evita alguns erros.
Atualmente estou usando o Mappy que bem simples e gratuito ( http://www.tilemap.co.uk/ ).
1- No editor de mapas, click em “new map” e escolha 32 x 32 pixels para o tamanho de cada tile e 3 x 3 para o tamanho do mapa em si .
Após gerar seu mapa click em File>Import e escolha o tileset do zelda e crie seu mapa.
Escolha “Custom>Export Flash ActionScript”, para o valor de ajuste coloque “-1” pois o Mappy cria sempre um tile vazio no tileset.
O arquivo ActionScript gerado é um vetor multidimensional com os números dos tiles usados no mapa.
2- No flash crie um novo arquivo para ActionScript 3.0. E vamos aos códigos.
var loader:Loader;
var screenBitmapData:BitmapData;
var tilesBitmapData:BitmapData;
var screenBitmap:Bitmap;
var mapRows:int=3;
var mapCols:int=3;
var tileSize:int=32;
var mapWidth:int=mapRows*tileSize;
var mapHeight:int=mapCols*tileSize;
loader = responsável por carregar o tileset do zelda.
tilesBitmapData = armazena o tileset após ser carregado.
screenBitmapData = armazena os tiles montados.
screenBitmap = armazena os tiles montados para a exibição na tela.
mapRows e mapCols = tamanho a matriz .
mapWidth e mapHeight = tamanho do mapa.
var mapArray:Array = new Array(mapRows);
for (var i = 0; i < mapRows; i++) {
mapArray[i] = new Array(mapRows);
}mapArray = ([
[416,417,418],
[424,425,426],
[432,433,434]
] );
Declaração de um array de duas dimensões (matriz 3 x 3). E atribuição da matriz gerada pelo Mappy ao vetor multidimensional.
tiles();
function tiles() {
loader = new Loader();
loader.contentLoaderInfo.addEventListener
(Event.COMPLETE,loadComplete);
loader.load(new URLRequest("zelda_tile.png"));
}
Instanciamos o objeto da classe Loader, e adicionamos um Listener que chamará a função loadComplete quando zelda_tile.png for carregado. O arquivo zelda_tile.png deve estar mesma pasta que o arquivo swf.
function loadComplete(e:Event):void {
tilesBitmapData=Bitmap(loader.content).bitmapData;
copyTiles();
}
Como não podemos manipular pixels pelo objeto loader , copiamos o tileset para um objeto da classe BitmapData. (Para passar o arquivo png para o objeto BitmapData temos que chamar loader.content como Bitmap e usar a propriedade bitmapData)
function copyTiles():void {
screenBitmapData=new BitmapData
(mapWidth,mapHeight,false,0x000000);
for (i=0; i < mapRows; i++) {
for (var j=0; j< mapCols; j++) {
var tileNum:int=int(mapArray[i][j]);
var destY:int=i*tileSize;
var destX:int=j*tileSize;
var sourceX:int=(tileNum % 8)*tileSize;
var sourceY:int=(int(tileNum/8))*tileSize;screenBitmapData.copyPixels
(tilesBitmapData,newRectangle
(sourceX,sourceY,tileSize,tileSize),
new Point(destX,destY));
}}
screenBitmap=new Bitmap(screenBitmapData);
addChild(screenBitmap);
screenBitmap.x=32;
screenBitmap.y=32;
}
O objeto screenBitmapData é instanciado nas dimensões de 96 x 96 pixels, sem transparência, e com fundo preto.
O loop for é usado para varrer o vetor e encontrar o número de cada tile e partir desde a referência de como montar o mapa.
destY e destX = guardam o ponto X e Y de onde um tile deve ser colocado. Por exemplo: O tile [0] [0] terá sua extremidade esquerda colocada nos pontos 0, 0.
sourceX e sourceY= guardam o ponto X e Y de um tile a ser usado. Exemplo : O elemento [0][0] é o tile número 416. Para X temos (416 mod 8) que é zero multiplicado pelo tamanho do tile. Desta forma encontramos em que coluna está o tile 416. ( O resto da divisão de 416 por 8 é zero) . Em Y temos 1664 (a parte inteira da divisão de 416 por 8 multiplicado pelo tamanho do tile).
Assim o elemento [0][0] é o tile 416 e esta no pixel 0 em X e o pixel 1664 em Y.
Os tiles são copiados um a um para o BitmapData passando para método copyPixels a origem e o destino dos pixels.
No final apenas instaciamos o Bitmap com o BitmapData já pronto e adicionamos no Display list
O resultado dessa experiencia está abaixo:





