Na última postagem desta série, Função para Detectar Colisões em Javascript, vimos como criar uma rotina de verificação de colisão entre as DIVs que representava o personagem e a árvore. Porém a solução ainda estava problemática por, principalmente, dois aspectos:
- 1- As variáveis eram globais o que dificulta a criação de novos personagens (aventureiros/árvores) e verificar a colisão entre eles; e
- 2- A rotina de colisão verificava a área inteira da div e, esta área, era maior do que o desenho do personagem. O ideal seria detectar a colisão apenas considerando a área da ‘sola do pé’ do aventureiro ou a ‘base do tronco’, da árvore.
Em resposta a estes problemas, passei a utilizar o conceito de objetos em Javascript que encapsula os atributos básicos de um personagem (aventureiro/arvore) tornando relativamente fácil a replicação deles,i.e., arvore=new personagem(...);.
Dentro deste objeto também encapsulamos uma área interna de colisão. Assim a área de colisão não é mais obrigatoriamente toda a área da div. O efeito ficou bem melhor do que o apresentado na postagem anterior.
Como última alteração significativa, ao criar um novo objeto personagem, automaticamente o novo objeto é inserido num array de personagens. Com isso fica fácil percorrer todo o array para verificar se um objeto em movimento colidiu com algum outro. Mas, antes de ver como ficou o código, veremos a aplicação em funcionamento:
Movimentação Aventureiro 1: (w,d,x,a)
Movimentação Aventureiro 2: (u,k,m,h)
Legal?
Mas se você brincou um pouco perceberá que ainda temos um problema para definir que div ficará sobre a outra. Por exemplo o tronco e raiz da árvore fica sobre a cabeça de um destes aventureiros, quando posicionamos este aventureiro embaixo da árvore. Sem falar que a div de um dos aventureiros etá sempre sobre a div do outro. Isto causa o efeito de pé de um na cabeça do outro. Mas resolver esta questão será assunto para a próxima postagem da série. No momento vamos analisar o como o código evoluiu até agora.
A primeira grande evolução, é um array de personagens. arrPersonagens se encarregará de guardar numa única estrutura todos os personagens (arvores e aventureiros)
var arrPersonagens=new Array();
Todas as variáveis, que antes eram globais, foram reorganizadas. Destas, as variáveis que eram relativas diretamente ao personagem passaram para uma estrutura única chamada personagem. Também passamos para esta mesma estrutura as funções diretamente responsáveis por manipular a mesma.O código desta estrutura está abaixo, bem comentado, com seus atributos e funções internas.
function personagem(piAreaColX, piAreaColY, piAreaColComp, piAreaColAlt, piFrameAtual, piTiraAtual, psDivPersonagem, piTamSprites)
{
var id=-1; //identifica o objeto no arrPersonagens
this.iPosTop; //posição Y do início da div do personagem
this.iPosLeft; //posição X do início da div do personagem
this.iAreaColX; //posição X, relativa a iPosLeft do início da área de colisão
this.iAreaColY; //posição Y, relativa a iPosTop do início da área de colisão
this.iAreaColComp; //Largura da área de colisão partindo de iAreaColX
this.iAreaColAlt; //Largura da área de colisão partindo de iAreaColY
var iFrameAtual=0; //A Dupla iTiraAtual,iFrameAtual marcam em conjunto [+]
var iTiraAtual=0; // a imagem corrente do spritesheet
var divPersonagem; //Faz referência ao objeto html onde será renderizado o personagem
var iTamSprites=96; //Largura e altura de cada imagem do spritesheet e div
var leftKey; //Tecla que moverá o personagem para a esquerda
var rightKey; //Tecla que moverá o personagem para a direita
var upKey; //Tecla que moverá o personagem para cima
var downKey; //Tecla que moverá o personagem para baixo
var sStatus='stoped'; //Status do personagem e animação ('stoped'|'walking')
var cVoltadoPara='L'; //Direção para onde o personagem está voltado ('N'|'L'|'S'|'O')
this.bMove=false; //Informa se um personagem é móvel (aventureiro) ou estático (árvore)
// Verifica se existe colisão entre o objeto corrente e um outro recebido por parâmetro
this.colide = function(ppersonagem){...}
//Informa que o personagem é móvel e informa as teclas de comando
this.addMov = function( pUpKey, pRightKey, pDownKey, pLeftKey) {...}
//Modifica o background da div em função da dupla (iTiraAtual,iFrameAtual)
var paint = function() {...}
//Realiza a movimentação do personagem se sStatus=='walking'
this.anime = function() {...}
//verifica a tecla pressionada e seta iTiraAtual para a animação certa
this.initAnime = function(keyCode){...}
//Interrompe a animação setando sStatus='stoped'
this.stopAnime = function(keyCode) {...}
/***** Inicializa o Personagem *****/
divPersonagem=document.getElementById(psDivPersonagem);
this.iPosTop=parseInt(divPersonagem.style.top);
this.iPosLeft=parseInt(divPersonagem.style.left);
this.iAreaColX=piAreaColX;
this.iAreaColY=piAreaColY;
this.iAreaColComp=piAreaColComp;
this.iAreaColAlt=piAreaColAlt;
iTamSprites=piTamSprites;
id=arrPersonagens.length;
arrPersonagens[id]=this;
paint();
/***** Fim da Inicialização do Personagem *****/
}
Também merece destaque a alteração feita no nosso timeout_trigger. Agora, como ele é responsável por animar vários objetos, ele percorre o arrPersonagens e, caso o personagem tenha movimento (personagem.bMove) é chamada a função de animação do mesmo.
function timeout_trigger() {
for(i=0;i
var personagem = arrPersonagens[i];
if(personagem.bMove) personagem.anime();
}
}
Ao final, a criação dos personagens propriamente dita:
perAventureiro = new personagem(20,60,26,36,0,0,'divAnime', 96);
perAventureiro2 = new personagem(20,60,26,36,0,0,'divAnime2', 96);
perArvore = new personagem(20,60,26,36,0,0,'divArvore', 96);
perAventureiro.addMov(87,68,88,65);
perAventureiro2.addMov(85,75,77,72);
timeout_init();
Querendo ver o código completo, fique a vontade para baixar o script aqui.
Pendências para a próxima postagem:
- Variar o z-index de acordo com a div do personagem; e
- Criar um novo personagem sem precisar, previamente, criar a div para o mesmo no html. Ou seja, automaticamente criar a div utilizando o DOM.
Abraços e até a próxima!
Este post foi postado quinta-feira, 16 de junho de 2011 às 9:52 e está em Programação, Programação de Jogos. Você pode verificar qualquer resposta a este post através do feed RSS 2.0.
Você pode deixar uma resposta, ou fazer um trackback de seu próprio site.
14 de outubro de 2011 às 11:14
muito bom estou esperando para ver o resto do artigo esta ajudando muito cara vlw