quinta-feira, 14 de julho de 2016

Códigos do jogo - Minijogo HemoJump


O jogo baseado no célebre doodle Jump foi construído sem o uso de nenhuma biblioteca ou framework.O jogo é feito todo em javascript. Ele está contido numa função principal Doodle() que é chamada para dar início ao jogo.












   Logo no começo são definidas as propriedades do canvas, e a variável de estado, ‘jogando’, que será true durante e jogo e false quando o jogo acaba.   

Depois temos uma secção para armazenamento das variáveis responsáveis por armazenar os áudios, e, logo em seguida, por armazenar as imagens: A dos botões de reset e menu, a do frame que ficará atrás do score para dar contraste à fonte, e a do background.


Um destaque fica para função onload da imagem de background, que irá chamar a função de clip, que irá posicionar e escalonar o background no canvas.


Um detalhe importante é que não podemos mover objetos dentro do canvas, por isso, precisamos limpá-lo a cada frame, e isso se faz possível com a seguinte função, que irá limpar e desenhar um quadrado com a cor determinada através do ctx.filStyle.


Também é definida uma transparência para nosso contexto, visando conferir um visual mais flúido.


Depois, nós temos duas funções que irão desenhar círculos em tamanhos e posições aleatórias. Esses, vão representar as hemácias no sangue. Por isso, também há uma função MoveHemacias que garante que estas não fiquem estáticas. Essa função será chamada sempre, com um parâmetro de velocidade. Ou seja, elas sempre estarão se movendo, não importa se o hemocinho esteja estacionário em relação ao background. Todavia, elas também são chamadas quando o hemocinho progride na fase(‘sobe’ em relação ao canvas), gerando também uma movimentação relativa.


Agora nós temos o nosso objeto Hemocinho, nele estão contidas todas os atributos e métodos que o personagem vai poder exercer dentro do jogo, todavia, ao declara um objeto com tantos métodos surge um problema.
Toda método que possui uma função aninhada, quando esta é chamada, muda o escopo da função inicial comprometendo o valor do ‘this’ como será explicado em detalhes mais adiante:


Uma função pode ser um método em javascript, basta que para isso, ela seja declarada como uma propriedade de um objeto. Quando há uma chamada ao método, this é uma referência ao objeto ao qual o método pertence.


Todavia se há uma função dentro desse método(Função Aninhada), não conseguimos acessar o objeto utilizando a propriedade ‘this’.Para acessar essas propriedades, precisamos utilizar uma variável local que irá receber o valor do this, antes da criação da outra função.


Assim, utilizamos var that=this para que a função interna possa se referir ao objeto original.


Vejamos um exemplo:


var colours = ['red', 'green', 'blue'];
document.getElementById('element').addEventListener('click', function() {
   // this será uma referência ao ‘element’ que foi clicado.


   var isso = this;


   colours.forEach(function() {
   console.log(this);// this será ‘undefined’ já que o escopo foi perdido
//com a criação da  nova função.
 console.log(isso); //isso será uma referência ao elemento clicado, dessa
//forma recuperamos a referência ao escopo perdido.
   });
});


Funções aninhadas (Nested functions), Não possuem nada de especial, lembremos, estamos programando em javascript, que não possui o conceito de classes, ou seja,  a função ainda precisa de uma variável ‘this’, e, dependendo de como ela é chamada, se não for chamada dentro de um objeto, o padrão é o objeto global , ou seja, a janela window.


Assim perdemos o controle sobre a variável this e consequentemente sobre a execução correta do programa. As funções nada mais são que variáveis, e caso criemos uma função aninhada, o escopo da função principal será modificado. Por isso se faz necessário declarar uma variável local que irá receber o valor do this, antes que o escopo seja modificado e percamos o controle sobre o andamento do programa.


Por isso, o ‘isso’ se torna a keyword de referência.


Agora temos vários outros métodos importantes:


Primeiro temos a função pular que realiza uma condicional para checar se o hemocinho está pulando ou está caindo, para evitar pulos duplos.
Depois disso ela define a altura do pulo, fazendo o hemocinho progredir na fase.
Depois temos o método checa pulo que move o objeto hemocinho o número de pixels estabelecido pelo altura pulo no método anterior. Depois é chamada a função de movimentação das hemácias para gerar a movimentação relativa.Depois, é decrementada a altura do pulo para gerar um efeito de gravidade. Quando a altura atinge zero, as variáveis são atualizadas.


 Após o hemocinho atingir a parte mais baixa da trajetória a uma nova chamada a função de pulo dentro do método StopQueda, fazendo ,assim, ele se deslocar para cima e para baixo constantemente.
Na função de checaQueda é verificado se durante a queda o personagem permanece na área de jogo.Caso isso não aconteça, é chamada a função de GameOver. Aqui abrimos um parêntese para o caso do jogo está começando e o hemocinho ainda não ter ultrapassado o meio da tela. Assim como o jogador ainda não marcou pontos, há uma chamada a função que impede que ele caia antes mesmo de ter marcado pontos, por isso, no começo do jogo, ele colide com a parte inferior do canvas e não cai.
Logo depois temos as funções de movimentação para a esquerda ou para a direita com velocidade de 3px.
Temos também o método que irá atribuir a posição do nosso objeto.


A função draw desenha o Personagem no canvas após toda as variáveis anteriores terem sido tradas nos métodos que a antecedem.
Depois a animação é prosseguida trocando-se o quadro atual.
Depois, é ativada a movimentação do hemocinho, onde se retorna o valor inteiro mais próximo resultante das expressões de posicionamento(~~).
Por último associamos às funções moveLeft e moveRight ao movimento do mouse.


Depois temos as declarações do vetor de plataformas e depois dos métodos de colisão subsequentes.Depois toco os respectivos sons.


Depois, temos o nosso último método responsável pelo desenho das plataformas.


Logo em baixo, ocorre uma geração aleatória das plataformas baseado no tipo, podendo ser verdes, que incrementam mais a altura do pulo, ou as vermelhas.
Aqui temos a nossa função recursiva de game loop, responsável pelo completo andamento do jogo:
Nela há uma chamada aos métodos de desenho e é criada uma função de movimentação para as plataformas. Depois, utilizo uma função para escalonar a frame de acordo com a largura do score.


Por último temos a função de GameOver que irá atualizar o estado do jogo,criar a tela de menu final com alguns efeitos de gradiente e desenhar as imagens responsáveis pelos botões.


Por último temos que acompanhar a posição do mouse para detectar o clique no canvas, já que assim que uma imagem é adicionada a este não temos como adicionar um evento específico a ela, por isso, precisamos rastrear se a posição do mouse coincide com a posição em que a imagem está no canvas, e se o evento de mousedown realmente aconteceu. Por fim é realizada a troca de janelas, e a depender da escolha do usuário, ou o jogo será reiniciado, ou ele será levado à tela da sala de jogos.

Nenhum comentário:

Postar um comentário