Ir para conteúdo
Fórum CódigoFonte.net
Entre para seguir isso  
.:Luciano Augusto

Câmeras 2D em Flash.

Recommended Posts

Olá pessoal, meu nome é .:Luciano Augusto da Silva e sou Game Developer. Já desenvolvi jogos de Entretenimento e Educacionais, tanto em 2D como 3D, tenho projetos na Europa, USA e Brasil. Trabalho há mais de 8 anos com isto e publiquei 3 livros, sendo 2 de Jogos Eletrônicos. Resumindo, game é minha vida. Este game faz parte de um módulo que estou terminando do curso de jogos avançado onde você irá programar um RPG on-line para até 400 usuários, o curso avançado estará no ar ainda em 2007, saiba mais dos meus cursos em: http://www.lucianoaugusto.com.br/ead

Minha intenção com este tutorial é ensinar como projetar e programar um game RPG em Flash com suporte a Action 2.0, pouca ou nenhuma adaptação para AS3. Confesso que eu não gostava do Flash nas versões anteriores, pois sempre achei a programação muito fraca. Mas para minha surpresa melhorou muito.

O game que fiz, é baseado no RPG ZELDA. Tem um código fonte rodando a internet com este game. Eu tenho ele aqui, mas é muito mal escrito, não tem consistência de objetos nem definições claras. Então escrevi o novo código em 4 horas e ficou 50% menor comparando com o original. A única coisa que aproveitei do arquivo original foram os gráficos.

No link abaixo tem o mesmo artigo com o exemplo do game:

http://www.lucianoaugusto.com.br/flash/divulgacao/

Está muito simples de entender o código, mesmo os mais leigos irão ter pouca ou nenhuma dificuldade para interpretar.

Antes de continuar, baixe o código e o arquivo .FLA para Flash Professional 2004.

http://www.lucianoaugusto.com.br/flash/div...da_cursoRPG.fla

http://www.lucianoaugusto.com.br/flash/div..._by_luciano.txt

Lembre-se de renomear este arquivo para .as e colocar na mesma pasta do .fla para executar.

Eu tenho o costume de programar o .as em separado, instanciar todos os objetos e não programar nada dentro de Movie Clipes (com on(release) etc). Quem programa assim, não por regra, é iniciante ou "newba". Pois é muito fácil se perder na codificação se ela está um pedaço no movie outro no quadro etc. Como eu assumo projetos grandes e profissionais, acabei tendo de aprender a programar de forma que facilitasse minha depuração futura.

O código do Action Script está todo comentado, vou apenas explicar o funcionamento do game e alguns segredos.

Se olhar o código irá notar que tenho o costume de declarar as variáveis antes de começar a programar, este costume vem do Pascal que programei há muito tempo e não pense que sou velho, tenho apenas 30 anos hehe.

//Definição de todas as variáveis usadas no game.
var velocidade_personagem:Number = 5;
var estado_personagem:String = "";
Declarar as variáveis no início facilita o controle sobre elas e também você começa a ter uma boa noção de quanto está usando de memória, afinal, variável funciona como um ponteiro, e ocupa memória (RAM) quando declarada. Não pense que isto é completamente inútil em Flash. Qualquer programação, independente de tecnologia ocupa memória. Aqui começa o looping (rotina que fica testando algo direto) principal do nosso game:
personagem_mc.onEnterFrame = function() {
// O objeto Key é usado para testar as teclas, ia usar Listner, mas como é um Tutorial básico
// resolvi fazer o controle de forma mais legível.
// Então: Key.DOWN é tecla para baixo e assim respectivamente.
if (Key.isDown(Key.DOWN)) {
this.gotoAndStop("walk_down");
// Estou fazendo um teste para ver se a personagem está na posição Y que quero testar, caso esteja 
// faço o terreno se mover, criando assim o efeito de câmera. Na verdade usamos este macete em RPG 
// para fazer o terreno se mover quando a personagem vai chegando perto dos limites da tela, isto evita
if (this._y>180 && terreno_mc._y>-275) {
// Caso a personagem esteja no limite indicado, o terreno se move e não ele, este efeito é muito utilizado
// em RPGs, pois simula a personagem andando normalmente e também, uma câmera acompanhando. E a grande verdade
// é que neste caso quem se move é o terreno.
terreno_mc._y -= velocidade_personagem;
limites_mc._y -= velocidade_personagem;
} else {
// Caso esteja fora dos limites, quem se move é a personagem. Vocês precisam entender que esta é a grande sacada
// para fazer um RPG, o jogo de personagem e cenário cria a ilusão de câmera no mundo 2D. 
personagem_mc._y += velocidade_personagem;
}
}
if (Key.isDown(Key.UP)) {
this.gotoAndStop("walk_up");
// Aqui também testo os limites antes de mover o terreno.
if (this._y<50 && terreno_mc._y<-3) {
terreno_mc._y += velocidade_personagem;
limites_mc._y += velocidade_personagem;
} else {
personagem_mc._y -= velocidade_personagem;
}
}
if (Key.isDown(Key.LEFT)) {
this.gotoAndStop("walk_left");
// Aqui também testo os limites antes de mover o terreno.
if (this._x<90 && terreno_mc._x<-3.5) {
terreno_mc._x += velocidade_personagem;
limites_mc._x += velocidade_personagem;
} else {
personagem_mc._x -= velocidade_personagem;
}
}
if (Key.isDown(Key.RIGHT)) {
this.gotoAndStop("walk_right");
// Aqui também testo os limites antes de mover o terreno.
if (this._x>190 && terreno_mc._x>-253.3) {
terreno_mc._x -= velocidade_personagem;
limites_mc._x -= velocidade_personagem;
} else {
personagem_mc._x += velocidade_personagem;
}
}
// Chamando a função para detectar a colisão e passando os 2 objetos
// como parâmetro. O primeiro objeto é a personagem, repsresentado por this
// o segundo objeto é a mascará de colisão. A grande sacada de usar função é que
// você testa muitas colisões com pouco código
testaColisao(this, limites_mc);
// Estou usando o mesma função para testar colisão, mas esperando um retorno de verdadeiro
// ou falso, por isto uso o IF(...) Retornando verdadeiro posso tratar o objeto.
if (testaColisao(this, terreno_mc.npc_01_mc)) {
terreno_mc.npc_01_mc._xscale = -60;
terreno_mc.sombra_npc_01_mc._xscale = -60;
//Estou abrindo o balão e passando os parâmetros, o último, 3000 é em milisegundos, ou seja 3 segundos ele fica aberto.
abreBalaoNpc(403, 323, "Olá sou o npc deste game! Muito prazer, meu nome é Lula!", 3000);
}
// Controle de ATAQUE usando a tecla SPACE e dependendo do estado do personagem, ativa uma animação
// A variável estado_personagem é setada no arquivo principal dentro do Movie do personagem
// Por falta de tempo não vou colocar um inimigo aqui, mas pode ser um tutorial futuro
if (Key.isDown(Key.SPACE)) {
if (estado_personagem == "down") {
this.gotoAndStop("attack_down");
} else if (estado_personagem == "up") {
this.gotoAndStop("attack_up");
} else if (estado_personagem == "left") {
this.gotoAndStop("attack_left");
} else if (estado_personagem == "right") {
this.gotoAndStop("attack_right");
}
}
};
Ele testa todas as ações da personagem, e controla posição X/Y, Ataque, colisão etc. Dentro deste looping temos algumas funções fabricadas em casa (não são do flash, eu que fiz), a principal é a :
testaColisao(this, limites_mc);
Esta função pega o objeto this como primeiro parâmetro, ou seja a personagem, e também qual o objeto que será a máscara de colisão. Usamos o sistema de colisão para testar quando a personagem chega nos limites do cenário por exemplo, onde ela não pode passar, ou em pedras e árvores onde ela não pode passar por cima. A rotina de colisão que escrevi, está perfeita. Ela testa a colisão pelos limites do objeto e não pelo quadrado do MovieClip, abaixo vou explicar melhor: Nesta imagem a colisão está no limite do MovieClip na parte azul, repare na bolinha acertando o limite (quadrado em volta do desenho). Isto é o padrão do FLASH: Agora usando uma técnica de programação, pegamos os valores X,Y mínimos e máximos do objeto e testamos a colisão por vértice ou edges. Com isto o sistema de colisão fica perfeito para montar limites onde as personagens podem andar ou não. Abaixo o código do sitema de colisão:
// Função criada para testar a colisão do personagem com os elementos
// do cenário que não podem ser ultrapassados ou que devam fazer alguma coisa
// Esta função é vital para o RPG. Ela além de segurar a persoangem para não passar
// por cima das coisas que há uma colisão, ela também retorna verdadeiro (true) quando
// uma colisão acontece, com isto podemos tratar a colisão e iniciar outra ação, se for
// o caso
function testaColisao(objeto:Object, objeto2:Object) {
with (eval(objeto)) {
// Esta sequência de Ifs aninhados testam os vértives (limites) de colisão
// do objeto passado como parâmetro que vai impedir que sua personagem ande
// onde não possa.
// Usar o getBounds retorna as coordenadas X e Y máximas em comparação a um objeto
// e o Stage. Com isto sabemos exatamente onde tem um objeto desenhado para fazer 
// um teste de colisão mais preciso.
if (eval(objeto2).hitTest(getBounds(_root).xMax, _y, true)) {
// Caso eu encontre um limite eu volto meu personagem e não o deixo ultrapassar
// É exatamente isto que está acontecendo na expressão abaixo.
// Esta colisão testa o lado direito da personagem
_x = _x-velocidade_personagem;
return true;
}
if (eval(objeto2).hitTest(getBounds(_root).xMin, _y, true)) {
// Esta colisão testa o lado equerdo da personagem
_x = _x+velocidade_personagem;
return true;
}
if (eval(objeto2).hitTest(_x, getBounds(_root).yMax, true)) {
// Esta colisão testa a parte inferior da personagem
_y = _y-velocidade_personagem;
return true;
}
if (eval(objeto2).hitTest(_x, getBounds(_root).yMin, true)) {
// Esta colisão testa a parte superior da personagem
_y = _y+velocidade_personagem;
return true;
}
}
}
O game na verdade se baseia nisto, não tem segredo. O lance de simulação de câmera é mais simples ainda. No código lá em cima do looping do personagem, fiz toda a simulação usando para isto o deslocamento X,Y da personagem. Ou seja, se a personagem estiver próximo do limite da tela, a tela rola para a direita ou para baixo. só usei uma condicional IF para controlar isto e o efeito é fantástico, parece que temos uma câmera seguindo a personagem.
if (this._y>180 && terreno_mc._y>-275) {
// Caso a personagem esteja no limite indicado, o terreno se move e não ele, este efeito é muito utilizado
// em RPGs, pois simula a personagem andando normalmente e também, uma câmera acompanhando. E a grande verdade
// é que neste caso quem se move é o terreno.
terreno_mc._y -= velocidade_personagem;
limites_mc._y -= velocidade_personagem;
} else {
// Caso esteja fora dos limites, quem se move é a personagem. Vocês precisam entender que esta é a grande sacada
// para fazer um RPG, o jogo de personagem e cenário cria a ilusão de câmera no mundo 2D. 
personagem_mc._y += velocidade_personagem;
}

Observem que a área vermelha é o limite, então se a personagem chegar nesta área ela para de andar e quem anda no caminho inverso é o terreno. Isto simula uma câmera.

Agora vou colocar os valores que usei no código para testar os limites, com isto você entenderá melhor:

Agora fica claro como funcionam os limites para ativar a rolagem do cenário ou não.

Este game se resume a deslocar a personagem e a tratar alguns eventos básicos, acredito que vocês não tenham dificuldade de entendê-lo.

O ratinho que está passando não programei, usei guide lines apenas, e a programação do npc está no código comentada.

Espero que gostem, aguardo perguntas e tendo tempo ajudo a melhorar este código.

.:Luciano Augusto da Silva

Game Developer

(41) 9972-6690 | [email protected]

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
Entre para seguir isso  

×
×
  • Criar Novo...