Ir para conteúdo
Fórum Script Brasil
  • 0

Câmeras 2d No Flash!


.:Luciano Augusto

Pergunta

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 | contato@lucianoaugusto.com.br

Link para o comentário
Compartilhar em outros sites

0 respostass a esta questão

Posts Recomendados

Até agora não há respostas para essa pergunta

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...