Criando um jogo Adobe Flash + Actionscript 3.0 (Prog) Part IV
Bem esse é o último post do jogo Quebra-Cabeça. Espero que esse seja o primeiro de muitos jogos a serem desenvolvidos e postados aqui no blog.
Conforme comentado anteriormente, nesse post falaremos mais de Actionscriot, mas antes de iniciarmos os códigos vamos criar o último item de Design do jogo que será as telas de “Start Game”, “Venceu” e “Perdeu”.
Então primeiro eu vou criar uma nova camada acima da Camada de Informações chamada de “Tela de Informações”.
Na sequência também já crio um novo keyframe no quadro 2 da camada Tela de Inicio, afinal não iremos precisar colocar nenhum conteúdo no quadro 1.
Menu Windows, Action ou uso o atalho F9.
Agora vamos começar a digitar o Actionscript de todo o jogo. Como o código final agora é bastante grande já vou colocá-lo comentado(ao copiar o código tome cuidado com as aspas, pois ele as inverte).
stop(); // para o script no quadro atual
import flash.utils.*; // importo uma galeria de utilidades do flash
texto_inicio.text=”Como jogar?\n\n\nMonte o quebra-cabeça encaixando as peças antes que o tempo acabe!\n\nPara começar apenas clique na tela.\n\nIniciar Jogo”; // adiciono o texto no texto_inicio;
var soma:Number = new Number(); // crio uma variável chamado soma e tipo ela como número(só pode receber números)
addEventListener(MouseEvent.MOUSE_DOWN, iniciar); //crio um ouvinte de evento quando houver o clique, inicia a função iniciar
function iniciar(Event:MouseEvent):void { //crio a função iniciar, com parâmetro de mouse com retorno nenhum (void)
tempo.text=”2:0″; // gravo dentro do tempo o valor de 2:0, lembrando que esse valor é apenas uma string
soma=0; // seto o valor inicial de soma para 0
pontos.text=”0″; // gravo dentro de pontos o valor de 0, lembrando que esse valor é apenas uma string
inicio.visible=false; //coloco o quadro do inicio como invisível
texto_inicio.visible=false; // faço o mesmo com o texto que está no inicio
inicio.mouseEnabled=false; //Essa função desabilita o mouse sobre o quadro inicio, para que não atrapalhe enquanto trabalho no quebra cabeças
texto_inicio.mouseEnabled=false; //faço o mesmo com o texto, pois se clicar no texto também ocorre o mesmo problema
for (var i = 1; i < 17; i++) { // crio uma repetição, dizendo que i deve iniciar em 1 e enquanto ele for menor que 17 (temos 16 peças), ele aumenta 1
var Totalpecas=getChildByName(”peca”+i); /* crio uma nova variável com o nome de Totalpecas e pego o nome da peça, lembra que demos os nomes de peca1, peca2 e assim por diante, então ele vai pegar o nome “peca” + i(valor de i que vai se repetir 1, 2,3, até 16 */
Totalpecas.x = Math.floor( Math.random() * (stage.stageWidth-100) ); /* coloco cada peça em uma posição x randômica, para que as peças não fiquem sempre na mesma posição dentro do tamanho máximo do meu stage e subtraio o valor de 100, para que as peças não fiquem muito nos cantos, senão assim seria muito fácil */
Totalpecas.y = Math.floor( Math.random() * (stage.stageHeight-100) ); //faço o mesmo com a posição y
Totalpecas.mouseEnabled=true; /* “ligo” a opção do mouse, agora vem a pergunta, porque fiz isso se o padrão é ser true? Simples, mais abaixo no script eu desligo(seto como false) essa opção em determinado ponto e explicarei mais abaixo */
}
var segundos:Number=0; // crio a variável segundos para criar o cronometro e coloco o valor de 0
var minuto:Number=2; // faço o mesmo para minutos, mais com o valor de 2, ou seja tem 2 minutos para montar o quebra-cabeças
var contador:Timer=new Timer(1000); /*crio uma variável chamada contador e tipo como sendo do tipo Timer e coloco o valor padrão de 1000 milisegundos, ou seja, 1 segundo. A cada um segundo ele volta a função para verificar como está o tempo atual */
contador.addEventListener(”timer”, funcTempo); // crio o ouvinte de evento do contator e chamo a função funcTempo
contador.start(); //inicio o Timer, quando se cria uma função do tipo Timer, é necessário que se inicie ela
function funcTempo(ObjTempo:TimerEvent) { /* crio a função funcTempo, passando o parâmetro como sendo do tipo TimerEvent, ou seja evento de tempo */
if (segundos>0) { // executo uma condição onde pergunto se segundos é maior que 0
segundos–; // se for, ele regride 1
} else { // senão
minuto–; //quem regride são os minutos
segundos+=59; //ao regredir um minuto, os segundos volta a valer 59
}
if (soma==80) { //executo uma segunda condição, se a soma for igual a 80(os pontos do jogador), caso o jogador ganhe!
texto_inicio.text=”Você Venceu, Parabéns\n\n\nVocê fez: “+soma+”pontos\n\n\n\nJogar Novamente?”; /* mudo o texto de texto_inicio, \n significa linha de baixo ou pular linha */
inicio.visible=true; //volto a visibilidade do quadro inicio
texto_inicio.visible=true; //também volto a visibilidade do texto
inicio.mouseEnabled=true; //também devolvo a função do mouse de clicar no quadro inicio
texto_inicio.mouseEnabled=true; // faço o mesmo com o texto
removeEventListener(MouseEvent.MOUSE_OVER, pecas); //removo o ouvinte pecas(veja mais abaixo)
removeEventListener(MouseEvent.MOUSE_DOWN, pegar); //também removo o ouvinte pegar
removeEventListener(MouseEvent.MOUSE_UP, soltar); //e o soltar (veja a explicação abaixo)
inicio.addEventListener(MouseEvent.MOUSE_DOWN, iniciar); // volto a adicionar o ouvinte de texto para o quadro inicio
texto_inicio.addEventListener(MouseEvent.MOUSE_DOWN, iniciar); //faço o mesmo com o texto
contador.stop(); //se o jogador ganhou, paro o contator
contador.removeEventListener(”timer”, funcTempo); /* e removo o ouvinte de evento, isso é necessário por dois motivos, 1 – descarrega da memoria, liberando espaço, 2 – irá zerar o contador, caso o jogador queira jogar novamente. */
}
if (minuto==0&&segundos==0) { // crio uma outra condição, caso o jogador não consiga montar as peças a tempo, ou seja, perdeu
texto_inicio.text=”Você perdeu, tente novamente\n\n\nVocê fez: “+soma+”pontos\n\n\n\nTentar Novamente?”; // adiciono o seguinte texto
inicio.visible=true; // devolvo a visibilidade do inicio
texto_inicio.visible=true; //faço o mesmo com o texto
inicio.mouseEnabled=true; // e também devolto a função de clicar no quadro inicio
texto_inicio.mouseEnabled=true; //faço o mesmo com o texto
removeEventListener(MouseEvent.MOUSE_OVER, pecas); //removo o ouvinte de evento pecas
removeEventListener(MouseEvent.MOUSE_DOWN, pegar); //também removo o ouvinte pegar
removeEventListener(MouseEvent.MOUSE_UP, soltar); // e o ouvinte soltar
contador.stop(); // paro o contator
contador.removeEventListener(”timer”, funcTempo); /* e removo o ouvinte de evento, isso é necessário por dois motivos, 1 – descarrega da memoria, liberando espaço, 2 – irá zerar o contaro, caso o jogador queira jogar novamente. */
inicio.addEventListener(MouseEvent.MOUSE_DOWN, iniciar); //volto a adicionar o ouvinte de texto para o quadro inicio
texto_inicio.addEventListener(MouseEvent.MOUSE_DOWN, iniciar); //também faço o mesmo com o texto_inicio
}
tempo.text=minuto+”:”+segundos; //retorno o valor para a caixa de tempo dos minutos e segundos restantes
}
removeEventListener(MouseEvent.MOUSE_DOWN, iniciar); /*enquanto não acontece nenhuma das condições acima, eu removo o ouvinte de evento iniciar */
addEventListener(MouseEvent.MOUSE_OVER, pecas); /*crio um novo ouvinte de evento, dessa vez com a propriedade MOUSE_OVER, ou seja quando o usuário passar o mouse sobre o(s) objeto(s) ele irá chamar a função pecas*/
}
function pecas(evt:Event):void { //crio a função pecas e passo o parâmetro evt do tipo Event
switch (evt.target.name) { // recupero o nome do objeto em qual o usuário está no momento passando o mouse por cima e pergunto:
case “tempo” : /* caso seja o tempo(campo dynamic de texto), ele não faz nada, imagina você puder ficar arrastanto a contagem de tempo, sem contar que isso poderia prejudicar o script, além de ocasionar erro. */
break; // pare aqui
case “pontos” : // caso seja pontos(campo dynamic de texto), ele também não irá fazer nada
break; //pare aqui
case “espaco1″ : //lembra das nossas peças invisiveis, não é porque elas estão invisiveis que não podem ser selecionadas, fiz isso para as 16.
break;
case “espaco2″ :
break;
case “espaco3″ :
break;
case “espaco4″ :
break;
case “espaco5″ :
break;
case “espaco6″ :
break;
case “espaco7″ :
break;
case “espaco8″ :
break;
case “espaco9″ :
break;
case “espaco10″ :
break;
case “espaco11″ :
break;
case “espaco12″ :
break;
case “espaco13″ :
break;
case “espaco14″ :
break;
case “espaco15″ :
break;
case “espaco16″ :
break;
default : //bem caso não seja nenhuma dessas opções, será o que precisamos
evt.target.addEventListener(MouseEvent.MOUSE_DOWN, pegar); /*não me importa qual peça ele pegou, o importante é que ele selecionou e ao selecionar, ele dispara a função pegar */
evt.target.addEventListener(MouseEvent.MOUSE_UP, soltar); // o mesmo irá ocorrer quando ele soltar a peça
break; //pare aqui
}
}
function pegar(Obj:Event):void { // crio a função pegar
Obj.target.startDrag(); // inicio a opção de poder arrastar a peça enquanto segura o botão do mouse apertado
Obj.target.alpha = 0.6; //também digo que a minha transparência é de 60%
}
function soltar(Obj:Event):void { //crio a função soltar
Obj.target.stopDrag(); //faço o objeto parar aonde o jogador soltou o botão do mouse
var espaco=”espaco”+Obj.target.name.substring(4,6); /*recupero os dois ultimos digitos do nome da peça(exemplo: seleciono a peca1, ele retorna 1, seleciono a peca15, ele retorna apenas 15, isso foi possivel graças ao substring, onde o valor 4, significa que eu quero que ignore os 4 primeiros caracteres pegue apenas a partir do quinto e o número 6 significa que eu quero que pare no máximo até o caracter 6 */
Obj.target.alpha = 1; //volto a transparencia da peça para 100%
var alvo = getChildByName(espaco); /* De posse da informação dos dois ultimos caracteres, eu crio uma variável que vai pegar a string acima “espaco” e vai adicionar os dois ultimos caracteres recuperados, formando assim o então espaco1, espaco2…. até o espaco16 */
if (Obj.target.hitTestPoint(alvo.x+50,alvo.y+50,true)) { /* Depois eu executo uma condição se a peça que o jogador está tentando encaixar está realmente sobre o espaço correto com uma margem de erro de 50, afinal acertar a posição exata de x e y poderia ser algo extremamente complicado */
soma+=5; //caso ele acerte soma +5 pontos
pontos.text = soma+”pts”; // retorno essa informação dentro do dynamic text pontos
Obj.target.mouseEnabled=false; /*a peça já foi encaixada, então desativo a opção de movimenta-la, para não ter um espertinho querendo fazer milhões de pontos */
Obj.target.x=getChildByName(espaco).x; //travo a peça na posição do espaço certo em x
Obj.target.y=getChildByName(espaco).y; //e no y
removeEventListener(MouseEvent.MOUSE_DOWN, pegar); // removo o ouvinte de evento pegar, descarregando da memoria
removeEventListener(MouseEvent.MOUSE_UP, soltar); //faço o mesmo com o ouvinte soltar
} else {
removeEventListener(MouseEvent.MOUSE_DOWN, pegar); /* se ainda não conseguiu encaixar no espaço correto, eu também descarrego o ouvinte da memoria para tornar o jogo mais rápido */
removeEventListener(MouseEvent.MOUSE_UP, soltar); //faço o mesmo com o soltar
}
}
Assim finalizo a última parte do Jogo: Quebra-Cabeças, algumas outras informações:
O meu aquivo .fla ficou com 320Kb
O swf ficou com apenas: 17,9Kb
Ele consome entre 6352Kb e 6380Kb de memóra, ou seja é possivel rodar até mesmo em computadores muito lentos e com pouca memória ram.
Por último o size report do jogo:
quebra-cabecas.swf Movie Report
——————————–
Metadata
——–
Bytes Value
—– —–
1049 Adobe Flash CS4 Professional 2009-05-21T19:25:16-03:00 2009-05-28T22:12:13-03:00 2009-05-28T22:12:13-03:00 xmp.iid:E4D60591DE4BDE11B4A1AD2E7C4A877D xmp.did:E4D60591DE4BDE11B4A1AD2E7C4A877D xmp.did:6823CA215546DE11A3988B60EAE2E33E xmp.iid:31407BC75F4ADE119D74E069E2B7B7C0 xmp.did:31407BC75F4ADE119D74E069E2B7B7C0 xmp.did:6823CA215546DE11A3988B60EAE2E33E application/x-shockwave-flash
Frame # Frame Bytes Total Bytes Scene
——- ———– ———– —————-
1 15165 15165 Scene 1 (AS 3.0 Classes Export Frame)
2 3261 18426
Scene Shape Bytes Text Bytes ActionScript Bytes
————————- ———– ———- ——————
Scene 1 604 249 3214
Symbol Shape Bytes Text Bytes ActionScript Bytes
————————- ———– ———- ——————
telainicio 34 0 0
peca16 72 0 0
peca15 88 0 0
peca14 88 0 0
peca13 69 0 0
peca12 98 0 0
peca11 109 0 0
peca10 104 0 0
peca9 88 0 0
peca8 87 0 0
peca7 103 0 0
peca6 99 0 0
peca5 83 0 0
peca4 64 0 0
peca3 82 0 0
peca2 81 0 0
peca1 65 0 0
espaco16 0 0 0
espaco15 0 0 0
espaco14 0 0 0
espaco13 0 0 0
espaco12 0 0 0
espaco11 0 0 0
espaco10 0 0 0
espaco9 0 0 0
espaco8 0 0 0
espaco7 0 0 0
espaco6 0 0 0
espaco5 0 0 0
espaco4 0 0 0
espaco3 0 0 0
espaco2 0 0 0
espaco1 0 0 0
Mascara_quadrado 32 0 0
img_fundo 37 0 0
Font Name Bytes Characters
———————- ——— ————–
_typewriter 35
ActionScript Bytes Location
—————— ——–
3214 Scene 1:Frame 1
Bitmap Compressed Compression
———————– ———- ——– ———–
quebra-cabecas.jpg 10004 230400 JPEG Quality=80
Abraços e até o próximo jogo.
Conforme comentado anteriormente, nesse post falaremos mais de Actionscriot, mas antes de iniciarmos os códigos vamos criar o último item de Design do jogo que será as telas de “Start Game”, “Venceu” e “Perdeu”.
Então primeiro eu vou criar uma nova camada acima da Camada de Informações chamada de “Tela de Informações”.
Na sequência também já crio um novo keyframe no quadro 2 da camada Tela de Inicio, afinal não iremos precisar colocar nenhum conteúdo no quadro 1.
Depois com a ferramenta retângulo (Rectangle Tool) vou desenhar um retangulo de forma que ele cubra todos os demais objetos(a cor do retângulo é irrelevante, podendo usar quaisquer cores):
Converto o retângulo em símbolo do tipo MovieClip, para converter o retângulo, com o objeto selecionado:
Menu Modify, Convert to Symbol… ou uso o atalho F8.
Menu Modify, Convert to Symbol… ou uso o atalho F8.
Name: telainicio
Registration: Canto superior esquerdo
Registration: Canto superior esquerdo
Vou dar um nome para o retângulo na instance name para que possa encontrá-lo através de Actionscript. Então seleciono o retângulo e coloco como nome na instance name.
Por último com a ferramenta de texto, vou criar uma caixa de texto vazia.
Com as seguintes configurações:
Dynamic Text
Character
Family: _typewriter
Size: 25.0 pt
Cor: cinza (#CCCCCC)
Essas configurações de fonte, tamanho e cor são apenas uma sugestão, podendo se trabalhar com quaisquer outras fontes, tamanhos ou cores.
Family: _typewriter
Size: 25.0 pt
Cor: cinza (#CCCCCC)
Essas configurações de fonte, tamanho e cor são apenas uma sugestão, podendo se trabalhar com quaisquer outras fontes, tamanhos ou cores.
Centralizo o texto. E por ultimo coloco o seguinte nome da instance name da caixa de texto:
Agora sim vamos para a parte de Actionscript, clico no quadro 2 da Layer Actionscript e em seguida abro o painel de Action:Menu Windows, Action ou uso o atalho F9.
Agora vamos começar a digitar o Actionscript de todo o jogo. Como o código final agora é bastante grande já vou colocá-lo comentado(ao copiar o código tome cuidado com as aspas, pois ele as inverte).
stop(); // para o script no quadro atual
import flash.utils.*; // importo uma galeria de utilidades do flash
texto_inicio.text=”Como jogar?\n\n\nMonte o quebra-cabeça encaixando as peças antes que o tempo acabe!\n\nPara começar apenas clique na tela.\n\nIniciar Jogo”; // adiciono o texto no texto_inicio;
var soma:Number = new Number(); // crio uma variável chamado soma e tipo ela como número(só pode receber números)
addEventListener(MouseEvent.MOUSE_DOWN, iniciar); //crio um ouvinte de evento quando houver o clique, inicia a função iniciar
function iniciar(Event:MouseEvent):void { //crio a função iniciar, com parâmetro de mouse com retorno nenhum (void)
tempo.text=”2:0″; // gravo dentro do tempo o valor de 2:0, lembrando que esse valor é apenas uma string
soma=0; // seto o valor inicial de soma para 0
pontos.text=”0″; // gravo dentro de pontos o valor de 0, lembrando que esse valor é apenas uma string
inicio.visible=false; //coloco o quadro do inicio como invisível
texto_inicio.visible=false; // faço o mesmo com o texto que está no inicio
inicio.mouseEnabled=false; //Essa função desabilita o mouse sobre o quadro inicio, para que não atrapalhe enquanto trabalho no quebra cabeças
texto_inicio.mouseEnabled=false; //faço o mesmo com o texto, pois se clicar no texto também ocorre o mesmo problema
for (var i = 1; i < 17; i++) { // crio uma repetição, dizendo que i deve iniciar em 1 e enquanto ele for menor que 17 (temos 16 peças), ele aumenta 1
var Totalpecas=getChildByName(”peca”+i); /* crio uma nova variável com o nome de Totalpecas e pego o nome da peça, lembra que demos os nomes de peca1, peca2 e assim por diante, então ele vai pegar o nome “peca” + i(valor de i que vai se repetir 1, 2,3, até 16 */
Totalpecas.x = Math.floor( Math.random() * (stage.stageWidth-100) ); /* coloco cada peça em uma posição x randômica, para que as peças não fiquem sempre na mesma posição dentro do tamanho máximo do meu stage e subtraio o valor de 100, para que as peças não fiquem muito nos cantos, senão assim seria muito fácil */
Totalpecas.y = Math.floor( Math.random() * (stage.stageHeight-100) ); //faço o mesmo com a posição y
Totalpecas.mouseEnabled=true; /* “ligo” a opção do mouse, agora vem a pergunta, porque fiz isso se o padrão é ser true? Simples, mais abaixo no script eu desligo(seto como false) essa opção em determinado ponto e explicarei mais abaixo */
}
var segundos:Number=0; // crio a variável segundos para criar o cronometro e coloco o valor de 0
var minuto:Number=2; // faço o mesmo para minutos, mais com o valor de 2, ou seja tem 2 minutos para montar o quebra-cabeças
var contador:Timer=new Timer(1000); /*crio uma variável chamada contador e tipo como sendo do tipo Timer e coloco o valor padrão de 1000 milisegundos, ou seja, 1 segundo. A cada um segundo ele volta a função para verificar como está o tempo atual */
contador.addEventListener(”timer”, funcTempo); // crio o ouvinte de evento do contator e chamo a função funcTempo
contador.start(); //inicio o Timer, quando se cria uma função do tipo Timer, é necessário que se inicie ela
function funcTempo(ObjTempo:TimerEvent) { /* crio a função funcTempo, passando o parâmetro como sendo do tipo TimerEvent, ou seja evento de tempo */
if (segundos>0) { // executo uma condição onde pergunto se segundos é maior que 0
segundos–; // se for, ele regride 1
} else { // senão
minuto–; //quem regride são os minutos
segundos+=59; //ao regredir um minuto, os segundos volta a valer 59
}
if (soma==80) { //executo uma segunda condição, se a soma for igual a 80(os pontos do jogador), caso o jogador ganhe!
texto_inicio.text=”Você Venceu, Parabéns\n\n\nVocê fez: “+soma+”pontos\n\n\n\nJogar Novamente?”; /* mudo o texto de texto_inicio, \n significa linha de baixo ou pular linha */
inicio.visible=true; //volto a visibilidade do quadro inicio
texto_inicio.visible=true; //também volto a visibilidade do texto
inicio.mouseEnabled=true; //também devolvo a função do mouse de clicar no quadro inicio
texto_inicio.mouseEnabled=true; // faço o mesmo com o texto
removeEventListener(MouseEvent.MOUSE_OVER, pecas); //removo o ouvinte pecas(veja mais abaixo)
removeEventListener(MouseEvent.MOUSE_DOWN, pegar); //também removo o ouvinte pegar
removeEventListener(MouseEvent.MOUSE_UP, soltar); //e o soltar (veja a explicação abaixo)
inicio.addEventListener(MouseEvent.MOUSE_DOWN, iniciar); // volto a adicionar o ouvinte de texto para o quadro inicio
texto_inicio.addEventListener(MouseEvent.MOUSE_DOWN, iniciar); //faço o mesmo com o texto
contador.stop(); //se o jogador ganhou, paro o contator
contador.removeEventListener(”timer”, funcTempo); /* e removo o ouvinte de evento, isso é necessário por dois motivos, 1 – descarrega da memoria, liberando espaço, 2 – irá zerar o contador, caso o jogador queira jogar novamente. */
}
if (minuto==0&&segundos==0) { // crio uma outra condição, caso o jogador não consiga montar as peças a tempo, ou seja, perdeu
texto_inicio.text=”Você perdeu, tente novamente\n\n\nVocê fez: “+soma+”pontos\n\n\n\nTentar Novamente?”; // adiciono o seguinte texto
inicio.visible=true; // devolvo a visibilidade do inicio
texto_inicio.visible=true; //faço o mesmo com o texto
inicio.mouseEnabled=true; // e também devolto a função de clicar no quadro inicio
texto_inicio.mouseEnabled=true; //faço o mesmo com o texto
removeEventListener(MouseEvent.MOUSE_OVER, pecas); //removo o ouvinte de evento pecas
removeEventListener(MouseEvent.MOUSE_DOWN, pegar); //também removo o ouvinte pegar
removeEventListener(MouseEvent.MOUSE_UP, soltar); // e o ouvinte soltar
contador.stop(); // paro o contator
contador.removeEventListener(”timer”, funcTempo); /* e removo o ouvinte de evento, isso é necessário por dois motivos, 1 – descarrega da memoria, liberando espaço, 2 – irá zerar o contaro, caso o jogador queira jogar novamente. */
inicio.addEventListener(MouseEvent.MOUSE_DOWN, iniciar); //volto a adicionar o ouvinte de texto para o quadro inicio
texto_inicio.addEventListener(MouseEvent.MOUSE_DOWN, iniciar); //também faço o mesmo com o texto_inicio
}
tempo.text=minuto+”:”+segundos; //retorno o valor para a caixa de tempo dos minutos e segundos restantes
}
removeEventListener(MouseEvent.MOUSE_DOWN, iniciar); /*enquanto não acontece nenhuma das condições acima, eu removo o ouvinte de evento iniciar */
addEventListener(MouseEvent.MOUSE_OVER, pecas); /*crio um novo ouvinte de evento, dessa vez com a propriedade MOUSE_OVER, ou seja quando o usuário passar o mouse sobre o(s) objeto(s) ele irá chamar a função pecas*/
}
function pecas(evt:Event):void { //crio a função pecas e passo o parâmetro evt do tipo Event
switch (evt.target.name) { // recupero o nome do objeto em qual o usuário está no momento passando o mouse por cima e pergunto:
case “tempo” : /* caso seja o tempo(campo dynamic de texto), ele não faz nada, imagina você puder ficar arrastanto a contagem de tempo, sem contar que isso poderia prejudicar o script, além de ocasionar erro. */
break; // pare aqui
case “pontos” : // caso seja pontos(campo dynamic de texto), ele também não irá fazer nada
break; //pare aqui
case “espaco1″ : //lembra das nossas peças invisiveis, não é porque elas estão invisiveis que não podem ser selecionadas, fiz isso para as 16.
break;
case “espaco2″ :
break;
case “espaco3″ :
break;
case “espaco4″ :
break;
case “espaco5″ :
break;
case “espaco6″ :
break;
case “espaco7″ :
break;
case “espaco8″ :
break;
case “espaco9″ :
break;
case “espaco10″ :
break;
case “espaco11″ :
break;
case “espaco12″ :
break;
case “espaco13″ :
break;
case “espaco14″ :
break;
case “espaco15″ :
break;
case “espaco16″ :
break;
default : //bem caso não seja nenhuma dessas opções, será o que precisamos
evt.target.addEventListener(MouseEvent.MOUSE_DOWN, pegar); /*não me importa qual peça ele pegou, o importante é que ele selecionou e ao selecionar, ele dispara a função pegar */
evt.target.addEventListener(MouseEvent.MOUSE_UP, soltar); // o mesmo irá ocorrer quando ele soltar a peça
break; //pare aqui
}
}
function pegar(Obj:Event):void { // crio a função pegar
Obj.target.startDrag(); // inicio a opção de poder arrastar a peça enquanto segura o botão do mouse apertado
Obj.target.alpha = 0.6; //também digo que a minha transparência é de 60%
}
function soltar(Obj:Event):void { //crio a função soltar
Obj.target.stopDrag(); //faço o objeto parar aonde o jogador soltou o botão do mouse
var espaco=”espaco”+Obj.target.name.substring(4,6); /*recupero os dois ultimos digitos do nome da peça(exemplo: seleciono a peca1, ele retorna 1, seleciono a peca15, ele retorna apenas 15, isso foi possivel graças ao substring, onde o valor 4, significa que eu quero que ignore os 4 primeiros caracteres pegue apenas a partir do quinto e o número 6 significa que eu quero que pare no máximo até o caracter 6 */
Obj.target.alpha = 1; //volto a transparencia da peça para 100%
var alvo = getChildByName(espaco); /* De posse da informação dos dois ultimos caracteres, eu crio uma variável que vai pegar a string acima “espaco” e vai adicionar os dois ultimos caracteres recuperados, formando assim o então espaco1, espaco2…. até o espaco16 */
if (Obj.target.hitTestPoint(alvo.x+50,alvo.y+50,true)) { /* Depois eu executo uma condição se a peça que o jogador está tentando encaixar está realmente sobre o espaço correto com uma margem de erro de 50, afinal acertar a posição exata de x e y poderia ser algo extremamente complicado */
soma+=5; //caso ele acerte soma +5 pontos
pontos.text = soma+”pts”; // retorno essa informação dentro do dynamic text pontos
Obj.target.mouseEnabled=false; /*a peça já foi encaixada, então desativo a opção de movimenta-la, para não ter um espertinho querendo fazer milhões de pontos */
Obj.target.x=getChildByName(espaco).x; //travo a peça na posição do espaço certo em x
Obj.target.y=getChildByName(espaco).y; //e no y
removeEventListener(MouseEvent.MOUSE_DOWN, pegar); // removo o ouvinte de evento pegar, descarregando da memoria
removeEventListener(MouseEvent.MOUSE_UP, soltar); //faço o mesmo com o ouvinte soltar
} else {
removeEventListener(MouseEvent.MOUSE_DOWN, pegar); /* se ainda não conseguiu encaixar no espaço correto, eu também descarrego o ouvinte da memoria para tornar o jogo mais rápido */
removeEventListener(MouseEvent.MOUSE_UP, soltar); //faço o mesmo com o soltar
}
}
Assim finalizo a última parte do Jogo: Quebra-Cabeças, algumas outras informações:
O meu aquivo .fla ficou com 320Kb
O swf ficou com apenas: 17,9Kb
Ele consome entre 6352Kb e 6380Kb de memóra, ou seja é possivel rodar até mesmo em computadores muito lentos e com pouca memória ram.
Por último o size report do jogo:
quebra-cabecas.swf Movie Report
——————————–
Metadata
——–
Bytes Value
—– —–
1049 Adobe Flash CS4 Professional 2009-05-21T19:25:16-03:00 2009-05-28T22:12:13-03:00 2009-05-28T22:12:13-03:00 xmp.iid:E4D60591DE4BDE11B4A1AD2E7C4A877D xmp.did:E4D60591DE4BDE11B4A1AD2E7C4A877D xmp.did:6823CA215546DE11A3988B60EAE2E33E xmp.iid:31407BC75F4ADE119D74E069E2B7B7C0 xmp.did:31407BC75F4ADE119D74E069E2B7B7C0 xmp.did:6823CA215546DE11A3988B60EAE2E33E application/x-shockwave-flash
Frame # Frame Bytes Total Bytes Scene
——- ———– ———– —————-
1 15165 15165 Scene 1 (AS 3.0 Classes Export Frame)
2 3261 18426
Scene Shape Bytes Text Bytes ActionScript Bytes
————————- ———– ———- ——————
Scene 1 604 249 3214
Symbol Shape Bytes Text Bytes ActionScript Bytes
————————- ———– ———- ——————
telainicio 34 0 0
peca16 72 0 0
peca15 88 0 0
peca14 88 0 0
peca13 69 0 0
peca12 98 0 0
peca11 109 0 0
peca10 104 0 0
peca9 88 0 0
peca8 87 0 0
peca7 103 0 0
peca6 99 0 0
peca5 83 0 0
peca4 64 0 0
peca3 82 0 0
peca2 81 0 0
peca1 65 0 0
espaco16 0 0 0
espaco15 0 0 0
espaco14 0 0 0
espaco13 0 0 0
espaco12 0 0 0
espaco11 0 0 0
espaco10 0 0 0
espaco9 0 0 0
espaco8 0 0 0
espaco7 0 0 0
espaco6 0 0 0
espaco5 0 0 0
espaco4 0 0 0
espaco3 0 0 0
espaco2 0 0 0
espaco1 0 0 0
Mascara_quadrado 32 0 0
img_fundo 37 0 0
Font Name Bytes Characters
———————- ——— ————–
_typewriter 35
ActionScript Bytes Location
—————— ——–
3214 Scene 1:Frame 1
Bitmap Compressed Compression
———————– ———- ——– ———–
quebra-cabecas.jpg 10004 230400 JPEG Quality=80
Abraços e até o próximo jogo.
Criando um jogo Adobe Flash + Actionscript 3.0 (Design) Part III
O palco deve estar assim agora somente com os contorno e as peças apenas coloridas na parte de fora do palco.
Menu Edit, Paste in Place ou CTRL + SHIFT + V.
Registration: Canto superior esquerdo.
Name: peca1
Registration: canto superior esquerdo
O mesmo processo que o Edit Symbol, porém só é possível editar um símbolo por vez.
Menu Edit, Edit in Place
O mesmo processo do Edit Select, porém ele mantém os outros objetos em volta a vista com opacidade.
Essas mesmas opções também se encontram clicando com o botão direito do mouse sobre o símbolo, com um diferencial:
Edit = Edit Select
Edit in Place = Edit in Place do menu Edit
Edit in new Windows = Abre o símbolo em uma nova janela para editar
Family: _typewriter
Size: 25.0pt
Cor: Preta (#000000)
Essas são uma sugestão de parâmetros para o texto, pode ser usado quaisquer outros tipos de fonte, cor e tamanho. Escrevo as palavras Tempo: e Pontos: e as posiciono acima das peças.
Agora vou posicionar todas as peças sobre os contornos como a imagem abaixo:
Isso será necessário para criarmos uma “rota de colisão”. Como a camada das peças está acima do contorno não será possível mais ver os contornos, isso não será um problema. Em seguida irei selecionar todas as peças e criar uma nova Camada abaixo da Cama Peças, chamando de Peças_invisiveis.
Logo depois crio um novo Keyframe no quadro 2 da camada Peças_invisiveis, pois não é necessário que coloquemos conteúdo no quadro 1. Para inserir um novo quadro, clico sobre o quadro 2 da camada Peças_invisiveis e:
Menu Insert, Timeline Keyframe ou uso o atalho F6.Na seqüência seleciono todas as peças e copio:
Menu Edit, Copy ou o atalho CTRL + C.
Depois seleciono a layer: Peças_invisiveis (isso é necessário, pois as peças estão em outra layer e ao selecioná-las, ele perde a seleção da layer Peças_invisiveis) e colo as peças no mesmo lugar:Menu Edit, Copy ou o atalho CTRL + C.
Menu Edit, Paste in Place ou CTRL + SHIFT + V.
Isso será necessário pelo seguinte motivo:
Lógica = Quando a Peça final sobrepuser à peça invisível, o código entenderá que aquela peça foi encaixada sobre a outra.Bom agora vou transformar todas as peças da camada Peças_invisiveis em Symbol do tipo MovieClip, como também tenho a camada das Peças que são identifica, preciso fazer com que a camada das Peças não me atrapalhe e para isso eu irei torna-a invisível, para fazer isso basta clicar na coluna que tem um Olho da camada Peças. Irá aparecer um X, indicando que a camada Peças está oculta.
E depois vou convertendo peça por peça da camada Peças_invisiveis em Sumbol do tipo MovieClip, para converter(com a peça selecionada):
Menu Modify, Convert to Symbol ou uso o atalho F8.Vou fazer isso em todas as peças, começando da esquerda para direita e de cima para baixo, com os seguintes nomes:
Name: espaco1, espaco2, espaco3, espaco4 e assim por dianteRegistration: Canto superior esquerdo.
Aproveito também para colocar os menos nomes na Instance name(espaco1, espaco2, espaco3, espaco4…) de cada peça e mudar o Alpha para 0% em Color Effect.
Ao terminar as 16 peças do quebra-cabeça, vou agora devolver visibilidade a camada Peças, já que o trabalho foi finalizado em Peças_invisiveis. Para devolver visibilidade, basta clicar no X que apareceu na coluna do olho para devolver visibilidade a camada Peças.
Agora eu vou fazer um trabalho similar com as Peças da camada Peças, com alguns diferenciais, seleciono e irei converter em símbolo do tipo MovieClip, para converter:
Menu Modify, Convert to Symbol ou uso o atalho F8Name: peca1
Registration: canto superior esquerdo
Também aproveito para colocar o mesmo nome na Instance Name de cada peça.
O diferencial além do nome será colocar a imagem correspondente aquela peça usando mascara.
Para fazer esse trabalho agora, após converter a peça em MovieClip e adicionar a instance name, eu irei editar esse símbolo MovieClip, para editar um símbolo, seleciono a peça já convertida:
Menu Edit, Edit Symbol ou uso o atalho CTRL + E
Essa opção faz com que eu edite o símbolo em uma nova área sem ver as outras peças em volta. Posso editar mais de um símbolo por vez (basta selecionar dois ou mais símbolos).
Menu Edit, Edit SelectEssa opção faz com que eu edite o símbolo em uma nova área sem ver as outras peças em volta. Posso editar mais de um símbolo por vez (basta selecionar dois ou mais símbolos).
O mesmo processo que o Edit Symbol, porém só é possível editar um símbolo por vez.
Menu Edit, Edit in Place
O mesmo processo do Edit Select, porém ele mantém os outros objetos em volta a vista com opacidade.
Essas mesmas opções também se encontram clicando com o botão direito do mouse sobre o símbolo, com um diferencial:
Edit = Edit Select
Edit in Place = Edit in Place do menu Edit
Edit in new Windows = Abre o símbolo em uma nova janela para editar
Para editar um símbolo também posso selecionar ao lado do Zoom(caixa que tem padrão 100% localizado no canto superior direito do palco) tem um botão Edit Symbol(são três figuras, um meio triangulo, um quadrado e um circulo) que tem a mesma propriedade do Edit Symbol do menu Edit. E por último e não menos importante também pode dar um duplo clique sobre o símbolo que ele aciona o: Edit in place.
Ao se editar um símbolo do tipo MovieClip, ele abre uma nova Timeline e também é possível saber que simbolo estou editando vendo na barra de navegação.
Vou criar uma nova layer, ficando com duas layers:
Depois será necessário posicionar a Layer 1 sobre a Layer 2, para fazer isso, basta clicar na Layer 1 e arrastá-la para cima da Layer 2
Agora irei renomear a Layer 1 para Mascara e a Layer 2 para Img_mascarada.
Seleciono a Camada Img_mascarada e pego o gráfico: img_fundo na Library(Biblioteca).
e arrasto até o palco, e encaixo a peça corretamente como abaixo(eu até poderia colocar no eixo x = 0 e eixo y = 0, porém isso só irá funcionar nessa primeira peça, nas demais não irá dar certo):
E para finalizar, irei até a camada Mascara e converto-a em Mask. Para converter em mascara, clico com o botão direito sobre a camada Mascara e escolho Mask.
Feito isso eu consigo o efeito que precisava que essa peça fique com apenas uma parte da imagem.
Bem agora eu volto para a Scene 1 e repito o processo com todas as peças.
Vou repetindo os processos com todas as peças até conseguir esse resultado final:
Para finalizarmos, crio uma nova camada acima da camada de Peças e chamo ela de Informações:
Em seguida adiciono um novo Keyframe no quadro 2 da Layer Informações, para criar um novo Keyframe, clico no quadro 2 da layer Informações:
Menu Insert, Timeline Keyframe ou uso o atalho F6.Por ultimo, seleciono a ferramenta de texto(no quadro 2 da camada Informações).
Com os seguintes parâmetros:
Static Text
CharacterFamily: _typewriter
Size: 25.0pt
Cor: Preta (#000000)
Essas são uma sugestão de parâmetros para o texto, pode ser usado quaisquer outros tipos de fonte, cor e tamanho. Escrevo as palavras Tempo: e Pontos: e as posiciono acima das peças.
Ainda com a ferramenta de texto, entretanto dessa vez utilizarei do tipo Dynamic, criarei duas caixas de texto.
Por ultimo adiciono e posiciono uma caixa de texto a frente de Tempo: e a outro a frente de Pontos: e adiciono uma instance name em cada uma das caixas referente aos seus respectivos itens:
Instance name tempo para a caixa de texto que está na frente do texto Tempo:
e Instance name pontos para a caixa de texto que está na frente do texto Pontos:
Assim concluo a parte III do jogo Quebra-Cabeças, no próximo e último post, falarei mais sobre Actionscript e finalizarei o jogo.
Criando um jogo Adobe Flash + Actionscript 3.0 (Prog) Part II
Complementando o post anterior, esse post será mais voltado à parte da programação Actionscript 3.0, embora ainda tenha alguns itens de design para terminar o jogo de quebra-cabeças.A primeira coisa a fazer é criar uma nova Layer e mudar o nome para Actionscript, lembrando que essa layer deve ficar acima de todas as demais Layers, esse processo é necessário, pois o Adobe Flash carrega as layer de baixo para cima, ou seja, para que ele carregue os objetos primeiros e somente depois acione as ações sobre eles.
Após criar a nova layer, seleciono o quadro um da layer actionscript e abro o painel de Actions:
Menu Window, Action (Atalho F9).
Vou criar agora o “Carregando” do jogo. Para isso vou criar duas novas camadas:
Uma irá chamar Mascara e a outra de Img_mascarada, ambas devem ficar acima da img_fundo apenas.
Em seguida vou selecionar a camada Img_mascarada e colar a imagem nas mesmas posições(x e y)da imagem fundo. Para copiá-la nas mesmas posições:
Menu Edit, Paste in Place ou use o atalho CTRL + Shift + V.
A imagem vai parecer que ganhou mais cor, mas na verdade é porque temos duas imagens uma sobrepondo à outra. Agora sim é que vou fazer com que a imagem da Img_mascarada vai ganhar literalmente cor, mudando o Alpha de 40% para 100%.
No painel de Propriedades em Color Effect mudo o alpha de 40% para 100%.
Depois disso vou selecionar a camada Mascara e criar um quadrado de 240×240 (tamanho do nosso quebra-cabeça e consequentemente da nossa imagem) sem contorno (a cor do preenchimento é irrelevante nesse momento, então pode ser selecionado qualquer cor) e irei posicionar exatamente sobre a imagem.
Agora vou selecionar o quadrado que acabei de criar e converte-lo em simbolo do tipo MovieClip, para converter seleciono e:
Menu Modify, Convert to Symbol ou use o atalho F8 (com o quadrado selecionado).
Menu Modify, Convert to Symbol ou use o atalho F8 (com o quadrado selecionado).
Name: Mascara_quadrado
Type: MovieClip
Registration: Centro inferior
Obs: Para o efeito funcionar corretamente é extremamente importante colocar o registration exatamente igual ao da foto.
Type: MovieClip
Registration: Centro inferior
Obs: Para o efeito funcionar corretamente é extremamente importante colocar o registration exatamente igual ao da foto.
Após converter, com o quadrado ainda selecionado, vou no painel de Propriedades(Properties) e dou o nome na Instance Name de barra.
Agora por último converto a Layer (camada) Mascara em Mask (mascara). Para converter em mascara, clico sobre a Layer (camada) Mascara com o botão direito do mouse e seleciono Mask.
Bom, agora é hora de voltar as Actions e fazer o “Carregando” funcionar. Para isso seleciono novamente a Layer Actionscript e abro novamente o painel de Action(Menu Window, Action ou F9) e adiciono as seguintes linhas de código:
addEventListener(Event.ENTER_FRAME, carregando);
function carregando(Obj:Event) {
var total = stage.loaderInfo.bytesTotal;
var carregado = stage.loaderInfo.bytesLoaded;
var porcentagem = Math.round(carregado*100/total);
barra.scaleY = porcentagem/100;
if (carregado >= total) {function carregando(Obj:Event) {
var total = stage.loaderInfo.bytesTotal;
var carregado = stage.loaderInfo.bytesLoaded;
var porcentagem = Math.round(carregado*100/total);
barra.scaleY = porcentagem/100;
gotoAndStop(2);
removeEventListener(Event.ENTER_FRAME, carregando);
}
}
Agora vamos entender o código:
A partir do Actionscript 3.0, você deve adicionar toda função em um ouvinte de evento:
addEventListener(Event.ENTER_FRAME, carregando);A partir do Actionscript 3.0, você deve adicionar toda função em um ouvinte de evento:
Em seguida eu crio a função carregando e adiciono um parâmetro do tipo Event(Obj:Event):
function carregando(Obj:Event) {
Aqui eu cri uma variável e chamo de total e dentro de total eu gravo as informações da quantidade total de bytes que tem o arquivo final, no caso o SWF.
var total = stage.loaderInfo.bytesTotal;
Em seguida crio uma outra variável e gravo dentro dele a quantidade de bytes que já foram descarregados ou seja, já baixaram e gravaram nos temporários da máquina do usuário.
var carregado = stage.loaderInfo.bytesLoaded;
Por último crio uma terceira variável chamada de porcentagem para fazer o calculo em porcentagem da quantidade já descarregada. A função Math.round arredonda o número para que eu não tenha porcentagem fracionada, exemplo: 10,3% passa a ser 10%.
var porcentagem = Math.round(carregado*100/total);
Depois eu pego essa informação e divido por 100 e adiciono a escala Y do quadrado desenhado, fazendo com que ela vá aumentando conforme a quantidade de itens já descarregados, pois a idéia será fazer as peças ganharem cor com a mascara no exemplo.
barra.scaleY = porcentagem/100;
Aqui faço uma condição, onde verifico se a quantidade já descarregada é igual ou maior do que o total, se for, ele irá para o quadro 2 do nosso jogo e irá remover o ouvinte de evento, descarregando assim a função da memória e liberando mais espaço.
if (carregado >= total) {
gotoAndStop(2);
removeEventListener(Event.ENTER_FRAME, carregando);
}
}
Fecho as duas chaves e está pronto o “Carregando” do jogo. Agora vou criar o quadro dois no jogo para eventualmente fazer a tela de jogo, pontuação e colocar as peças com as devidas “partes” do quebra-cabeça. Primeiro fecho a tela de actions(Menu Windows, Action ou atalho F9) e depois clico sobre a layer action e para criar um novo quadro:
Menu Insert, Timeline, Keyframe ou uso o atalho F6.
Depois vou clicar na camada da Action e no quadro 2, abro o painel de action(Menu Window, Action ou F9) e adiciono a seguinte Action:
Para que a cena fique parada no quadro 2.
Como não precisamos das peças no quadro 1, vou selecionar o quadro 1 e arrastá-lo para o quadro 2. Para isso eu seleciono o quadro 1, clico novamente, mantenho o botão do mouse apertado e arrasto para o quadro 2.
As layers: Mascara, Img_mascarada e img_fundo não serão necessárias no quadro 2, então irei selecioná-las e removerei os quadro dois, para selecionar o quadro 2 das 3 layers, seguro o SHIFT e vou clicando nos quadros 2 das três layers.
Depois de selecionado, clico com o botão direito sobre qualquer uma das três layer e escolho Remove Frames (remover quadros).
Assim concluo a parte II do Jogo Quebra-Cabeças, no próximo posto devemos voltar mais a parte de design para estruturar as peças, demarcar as partes onde irão a pontuação, o tempo para montar e os outros itens.
Nenhum comentário:
Postar um comentário