Criação de games – Campo Minado em AS3Olá pessoal, Vamos criar mais um joguinho, que vai apresentar a programação de games com o AS3. Pré-requisitos:Conhecimento básico em ActionScript 2.0 e 3.0 Macromedia Flash CS3 Classe EventDispatcher Objetivo:O objetivo deste tutorial é que você, ao término dele, possa entender como funciona a programação orientada a objetos de games, criar seus próprios eventos nos jogos. Procurei selecionar um jogo simples no resultado final que todo mundo conhece (campo minado), mas que no momento do desenvolvimento vai explorar sua capacidade de resolver problemas bem relacionados a programação. Visto em nÃvel de código este joguinho não é tão simples. Conceitos:Os conceitos que serão vistos aqui, são a utilização dos dispatchers para resolver alguns problemas, resolução de problemas algorÃtmicos simples, arganização dos objetos pelo AS3, duplicar movie clips com a ausência do duplicateMovieClip. ConteúdoPrimeiro vamos preparar os movie clips principais, no fim deste tutorial tem o link dos arquivos fontes, nele eu coloquei as imagens que vamos utilizar. Crie um documento novo Adobe flash CS 3 com o nome mines.fla com o background da cor #CCCCCC . Depois vá em insert > new symbol ou CTRL + F8, o novo sÃmbolo é do tipo movie clip e se chamará Mine. Neste novo movie clip vazio crie 11 Keyframes. Com exceção do primeiro Keyframe, todos os outros receberão um nome. A nome de cada frame a partir do 2° será a seguinte: _1, _2, _3, _4, _5, _6, _7, _8, die e clear. Dessa forma facilitará no momento da programação. Agora no primeiro keyframe você colocará a figura chamada square.jpg coloque nas coordenadas mostradas na figura.
Seguindo, clique no primeiro keyframe e aperte F9 para colocar o comando stop() no editor de script. Agora exatamente na mesma posição, mas no keyframe 10 que tem o nome die, coloque a figura bomb.jpg, ela será colocada na mesma posição e dimensões mostrada na figura 1, nos outros keyframes você vai apenas colocar um número no stage com a ferramenta text, seguindo a lógica número 1 no keyframe _1, 2 no jeyframe _2, todos posicionados no x=2.8 e y=0 até o keyframe _8, isso representa um determinado número de bombas que estão próximas de um quadrado (Regra do jogo), se você jogou campo minado alguma vez já observou os números que aparecem no local que clicou . Volte à cena principal, falta um botão novo jogo, que você irá achar em window > components ou aperte CTRL + F7. Escolha o Button na lista que aparecerá, arraste-o para o stage e altere seu label para novo jogo como na figura abaixo, e o nome de instância do botão é newGame_btn:
E para finalizar esta parte vamos linkar o mc Mine que acabamos de criar com o Action Script 3.0, vá na library e clique com o botão direito no mc Mine e escolha linkage, aparecerá esta janela de diálogo, configure como está mostrado.
Acabamos esta fase, agora vamos a codificação, primeiramente construiremos duas classes: a primeira é que dispara eventos, recomendo ver os tutoriais mencionados nos pré-requisitos para continuar este tutorial, neles você ira entender como funciona as classes que são dispatcher e as listeners, abaixo a classe dispatcher que chamei de DispacherObject: package
{ import flash.events.EventDispatcher; import flash.events.Event; public class DispatcherObject extends EventDispatcher { private var label:String; static var EXPLOSION:String = ‘explosion’; public function DispatcherObject(label:String) public override function toString():String public function dispatch() A classe é bem simples, possui um atributo para debugar e um estático que representa o no evento a ser disparado, chamei esse evento de explosion. Possui um construtor, um método para debugar que sobrescreve o método toString() da classe pai por meio da palavra reservada override e por fim o método que dispara o evento em si. Abaixo segue a classe listener que ‘escuta’ a classe emissora de eventos que acabamos de ver: package
{ import flash.events.IEventDispatcher; import flash.events.Event; public class ListenerObject { private var label:String; public function ListenerObject(label:String) public function addDispatcher(dispatcher:IEventDispatcher, functionHandler:Function) public function toString()
Semelhante a classe acima também possui método e atributo para debugar, e um método que recebe dois parâmetros: um é o dispatcher que ela ficará ‘ouvindo’ e o outro parâmetro e a função que será chamada no momento do disparo do evento. A próxima classe é a classe que representará cada quadrado do campo minado: package
{ import flash.display.MovieClip; import flash.display.Sprite; import flash.display.DisplayObject; import flash.events.MouseEvent; import flash.events.Event; public class Square extends Sprite { /*indica se é bomba ou não*/ private var bomb:Boolean; /*cópia do mc que representa a bomba*/ private var mc:MovieClip; /*indica quantas bombas estão perto*/ /*listeners e dispatchers*/ private var listener2:ListenerObject; private var disp:DispatcherObject; var disp2:DispatcherObject; /*construtor, recebe o mc que representa a mina e um booleano this.mc = target_mc; this.addChild ( target_mc ); this.bomb = bomb; this.mc.buttonMode = true; listener = new ListenerObject(‘CS3′); listener2 = new ListenerObject(‘ADOBE’); disp2 = new DispatcherObject(‘MINADO’); doEvents(); /* seta quantas bombas estão proximas desse Square*/ /* retorna true ou false dizendo se é bomba*/ /*seta dispachador de eventos que ‘ouvirá’ o clique em uma bomba*/ listener.addDispatcher( d, onExplosion ); /*seta quem irá disparar o armegedon*/ listener2.addDispatcher( d, explode ); /*adiciona evento de click do mouse*/ if(this.bomb) } } }; /*método de callback que será invocado quando clicar numa bomba*/ }; /*método de callback que será invocado quando houver um armagedon*/
Agora vamos a classe controladora do jogo, optei por chamá-la de Game, ela possui como um dos métodos principais um para posicionar bombas aleatoriamente no campo (método prepare()), também método para computar a proximidade de um quadrado (Square) de uma bomba (método computeProximity()). E um para criar o efeito de explosão em cadeia que é visto no jogo de campo minado, ele ocorre quando você clica em uma posição que não está proximo de nunhuma bomba, este quadrado por sua vez explode todos os seus quadrados vizinhos num raio de um quadrado. Se ele explodir um quadrado vizinho que também tem proximity igual a Zero, esse também realiza uma explosão em cadeia. Chamei este método de armagedon(). Podem abservar que todas as explosões são ativadas por eventos, e não preciso varrer o campo para ir explodindo as bombas, elas se explodem ‘sozinhas’. É como se eu fosse ligando um fio em cada uma e precisasse apertar apenas um botão para dispará-las, esse tipo de conceito ajuda em muitos tipos de jogos que existem diversos objetos para manipular. Veja a implementação abaixo: package
{ import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; public class Game extends MovieClip { /*armazena as bombas e suas informações*/ private var field:Array; /*número de bombas*/ /*dispachador de eventos*/ private var listener:ListenerObject; /*construtor da classe Game field = new Array(width); dispatcher = new DispatcherObject(‘MX’); this.listener = new ListenerObject(‘MX’); this.listener.addDispatcher( Game.dispatcher, gameOver ); function gameOver(event:Event) /* prepara o ambiente do jogo* while ( i < this.nBombs ) if (!field[iAux][jAux]) } for (i =0; i < field.length; i++) } } /*inicia o jogo, prepara depois mostra na tela*/ } /* Método responsável por computar a proximidade de cada Square de uma bomba if( i-1 >= 0 && arr[i-1][j].isBomb()) arr[i][j].setProximity( proximity ); /* Este método é responsável por criar um espécie de explosão em cadeia if (i+1 < arr.length ) if (j-1 >= 0 ) if (j+1 < arr[0].length ) if (i-1 >= 0 && j-1 >= 0 ) if (i+1 < arr.length && j+1 < arr[0].length ) if (i+1 < arr.length && j-1 >= 0 ) if (i-1 >= 0 && j+1 < arr[0].length ) } };
Agora Vamos ao código que realmente irá instanciar a classe Game para fazer nosso jogo funcionar: var game:Game;/* Novo jogo*/
function newGame( event:MouseEvent) { /* aqui removemos o jogo atual e inciamos um novo var isk:DisplayObject = null; game.init(); /*adiciona o game a lista do root isk.width = 400; newGame(null); /* aqui adicionamos o evento de clique do mouse no botão novo jogo*/ Veja que eu quando inicio um novo jogo e descubro que acabou de ser realizado um outro simplesmente crio um novo, mas e os objetos criados no jogo anterior?? Para onde vão? Para quem não sabe a máquina virtual do flash 9 foi reimplementada e possui um ótimo coletor de lixo, que se encarrega de limpar esses espaços deixados sem referência. Considerações FinaisEste é o jogo, só rodar e ver o resultado, aconselho estudar as classes de manipulação de eventos elas ajudam bastante na hora de resolver um poblema. Usando esta idéia você poderá criar outros jogos, use sua criatividade. Não pule etapas, se você estiver começando é melhor começar a programar os jogos dos tutoriais iniciais de games. Tivemos que nos adptar a ausência do duplicateMovieClip, mas que foi suprida pela forma ainda mais fácil de linkar o nome do mc como classe e apenas instanciar com o operador new o mc que se deseja duplicar, no nosso caso o mc Mine. Não tente criar jogos antes de saber programar você pode acabar se frustrando por não conseguir, nos tutoriais mostro apenas como utilizar o que você sabe de Action Script 3.0 em jogos. Aqui apresentei uma forma de criar o game. Você pode colocar novas funcionalidaes nele como timer, contador de acertos entre outros. Apenas fiz núcleo do jogo, as inovações ficam de desafio para vocês. Depois postem no fórum as suas inovações se vocês quiserem para que possamos avaliar e jogar um pouco.
Autor: Márcio Silva – Colunista de Flash & ActionSctipt MXSTUDIO. Qualquer dúvida envie um e-mail para marciosilva@mxstudio.com.br ou acesse nosso fórum |
Opa, olá marcio, bele?
seguinte cara, segui seu tutorial e talz, só que apareceu um problema que n to conseguindo resolver, procurei do que se tratava esse erro, mas de nada adianto, se vc puder me dar uma força, fico grato =)
Aqui tah o erro:
ReferenceError: Error #1069: Property disp2 not found on Square and there is no default value.
at Game/::armagedon()
at Game/::display()
at Game/init()
at Untitled_fla::MainTimeline/newGame()
at Untitled_fla::MainTimeline/Untitled_fla::frame1()
Vlw