Aula XI - XII - Computação Gráfica - Capturando Teclas - Colisão/HitTest - Listener 
Autor: Cristina Jung | Publicado: 2016-04-11T22:13:00-03:00



Capturando teclas: Movimentando um Sprite utilizando teclado
Material de apoio 1:&nbsp;Javascript - Manipulação dos controles do teclado
Material de apoio 2: JavaScript.com
Material de apoio 3: EventListener


Como capturar as teclas do nosso teclado, para que possamos trabalhar o controle de um sprite ou mesmo de qualquer outro elemento que faz parte de um game?

Vamos lá!!

Primeiro vamos precisar trabalhar com os eventos de teclado, sempre lembrando que os eventos de JavaScript,&nbsp;são ações do usuário, que provocarão um "disparo" a um tipo de interatividade. Na verdade, o evento, por excelência, é o clique do mouse, porque é o único que o HTML gerencia. Porém, graças ao JavaScript nós podemos combinar funções e métodos a eventos tais como a passagem do mouse sobre uma área, a mudança de um valor e assim por diante.

São os gerenciadores de eventos que permitem associar uma ação a um evento. A sintaxe de um gerenciador de eventos é a seguinte:&nbsp;

onEvenement="Action_Javascript_ou_Function();"


Quando usamos em um link, por exemplo, a sintaxe é a seguinte:&nbsp;


&lt;a href="URL" "onEvenement='Action_Javascript_ou_Function();'"&gt;Textinho&lt;/a&gt;

Sempre e sempre serão os&nbsp;gerenciadores de eventos que permitirão associar uma ação a um evento. A sintaxe de um gerenciador de eventos é a seguinte:&nbsp;



Lista de eventos: fonte:javascript.com

-&nbsp;Abort&nbsp;(onAbort):&nbsp;Este evento acontece quando o usuário interrompe o carregamento da imagem.

- Blur (onBlur): Ocorre quando o elemento perde o foco, ou seja, quando o usuário clica fora do elemento, este não será mais selecionado como estando ativo. 

- Change (onChange):&nbsp;Ocorre quando o usuário altera o conteúdo de um campo de dados.&nbsp;
 
- Click (onClick):&nbsp;Ocorre quando o usuário clica no elemento associado ao evento.
 
- dblclick (onDblclick):&nbsp;Ocorre quando o usuário clica duas vezes no elemento associado ao evento (um hiperlink ou um elemento de formulário).&nbsp;

-&nbsp;dragdrop&nbsp;(onDragdrop):&nbsp;Ocorre quando o usuário efetua um arrastar-largar na janela do navegador.&nbsp;

-&nbsp;error&nbsp;(onError):&nbsp;É desencadeada quando ocorre um erro durante o carregamento da página.&nbsp;

- Focus (onFocus):&nbsp;Ocorre quando o usuário dá foco a um elemento, isso significa que este elemento foi selecionado como estando ativo.   &nbsp;
-&nbsp;keydown&nbsp;(onKeydown):&nbsp;Ocorre quando o usuário pressiona uma tecla do seu teclado.

-&nbsp;keypress&nbsp;(onKeypress):&nbsp;Ocorre quando o usuário mantém pressionada uma tecla do seu teclado.&nbsp;

-&nbsp;keyup (onKeyup):&nbsp;Ocorre quando o usuário solta uma tecla do seu teclado já pressionada anteriormente.

-&nbsp;Load&nbsp;(onLoad):&nbsp;Ocorre quando o navegador do usuário carrega a página em curso.

-&nbsp;MouseOver&nbsp;(onMouseOver):&nbsp;Ocorre quando o usuário põe o cursor do mouse acima de um elemento.

-&nbsp;MouseOut&nbsp;(onMouseOut):&nbsp;Ocorre quando o cursor do mouse deixa um elemento.

-&nbsp;Reset&nbsp;(onReset):&nbsp;Ocorre quando o usuário apaga os dados de um formulário com o botão Reset, por exemplo.

-&nbsp;Resize&nbsp;(onResize):&nbsp;Ocorre quando o usuário redimensiona a janela do navegador.

-&nbsp;Select&nbsp;(onSelect):&nbsp;Ocorre quando o usuário seleciona um texto (ou uma parte de um texto) em um campo do tipo "text" ou "textarea".

-&nbsp;Submit&nbsp;(onSubmit):&nbsp;Ocorre quando o usuário clica no botão de submissão de um formulário (o botão que permite enviar o formulário).

-&nbsp;Unload&nbsp;(onUnload):&nbsp;Ocorre quando o navegador do usuário sai da página em curso.


Associação de eventos com os objetos:



EventosObjetos interessados
abortImage
blurButton, Checkbox, FileUpload, Layer, Password, Radio, Reset, Select, Submit, Text, TextArea, window
changeFileUpload, Select, Submit, Text, TextArea
clickButton, document, Checkbox, Link, Radio, Reset, Select, Submit
dblclickdocument, Link
dragdropwindow
errorImage, window
focusButton, Checkbox, FileUpload, Layer, Password, Radio, Reset, Select, Submit, Text, TextArea, window
keydowndocument, Image, Link, TextArea
keypressdocument, Image, Link, TextArea
keyupdocument, Image, Link, TextArea
loadImage, Layer, window
mousedownButton, document, Link
mousemoveNenhum especificamente
mouseoutLayer, Link
mouseoverArea, Layer, Link
mouseupButton, document, Link
movewindow
resetform
resizewindow
selecttext, Textarea
submitForm
unloadwindow




Centralizando e focando no teclado .....
Os eventos do teclado!!

onkeypress: quando uma tecla é ativada.
onkeydown: quando uma tecla é pressionada.

onkeyup: quando uma tecla é "solta".  


É muito, mas muito importante saber a diferença entre: "Onkeypress", "Onkeydown" e "Onkeyup"!!!

O "Onkeypress" será chamado duas vezes quando pressionamos uma tecla: quando o botão é pressionado e solto. Então, se atribuirmos um comportamento e/ou tratamento a este evento, precisamos saber que ele será efetuado duas vezes, quando pressionarmos sua tecla. A menos que façamos a verificação do estado da tecla (para cima ou para baixo) diretamente no código javascript).&nbsp;

Quanto aos controles do teclado, vamos nos concentrar nas três importantes propriedades:

keyCode:&nbsp;é o código numérico da tecla ativada.
altKey:&nbsp;valor booleano verdadeiro se a tecla ALT estiver ativada.
ctrlKey:&nbsp;valor booleano verdadeiro se a tecla CRTL estiver ativada.


Propriedade keyCode e lista dos valores:


Esta propriedade permite recuperar o valor integral da tecla pressionada. Logo, trata-se de um número de teclas - Clique Aqui para acessar a lista!








Trabalhando com teclado!

Vamos primeiro criar uma pasta.
Dentro desta pasta, vamos criar outra com nome de img.
Salve esta nave dentro da pasta img com nome de nave.png






Vamos criar um Doctype HTML 5!



 

  
&lt;!DOCTYPE html&gt;

&lt;html&gt;

&nbsp;&lt;head&gt;

&lt;meta charset="utf-8"&gt;



&nbsp;&nbsp;
  &lt;title&gt;Nave com tiro&lt;/title&gt;



&nbsp;&nbsp; &lt;script
  src="animacao.js"&gt;&lt;/script&gt;

&nbsp;&nbsp; &lt;script
  src="teclado.js"&gt;&lt;/script&gt;

&nbsp;&nbsp; &lt;script
  src="nave.js"&gt;&lt;/script&gt;

&nbsp;&nbsp; &lt;script
  src="tiro.js"&gt;&lt;/script&gt;

&lt;/head&gt;



&lt;body&gt;

&nbsp;&nbsp; &lt;canvas
  id="canvas_nave" width="500"
  height="500"&gt;&lt;/canvas&gt;

&nbsp;&nbsp; &lt;script&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  // canvas e contexto

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  var canvas = document.getElementById('canvas_nave');

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  var context = canvas.getContext('2d');

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  // teclado e animação (game engine)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  var teclado = new Teclado(document);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  var animacao = new Animacao(context);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  // sprite da nave e sua imagem

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  var imgNave =
  new Image();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  imgNave.src = 'img/nave.png';&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var
  nave = new Nave(context, teclado, imgNave);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  animacao.novoSprite(nave);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  // para a nave atirar

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  teclado.disparou(ESPACO, function() {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nave.atirar();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  });

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  // quando carregar a imagem, iniciar a animação

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  imgNave.onload = function() {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Centralizada na horizontal,
  alinhada embaixo na vertical

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nave.x = canvas.width / 2 -
  imgNave.width / 2;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nave.y = canvas.height - imgNave.height;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nave.velocidade
  = 5;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; animacao.ligar();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  }

&nbsp;&nbsp;
  &lt;/script&gt;

&lt;/body&gt;



&lt;/html&gt;

 

Links:
animação
teclado
nave
tiro

___________________________________________________________________

addEventListener()

Método que registra uma única espera de evento em um único alvo. O alvo do evento pode ser um único elemento em um documento, o documento em si, uma janela, ou um XMLHttpRequest = um XMLHttpRequest é um objeto JavaScript que foi projetado pela Microsoft e adotado pela Mozilla, Apple e Google, ou seja, pelos motores de renderização dos navegadores. Este agora está sendo padronizado no W3C. Ele fornece uma maneira fácil de recuperar dados em uma URL. Documentação relacionada em 24 de novembro de 2005.

Retornando ao EventListener podemos registrar mais de uma espera de evento como alvo de execução, para isso, basta chamar addEventListener() para o mesmo alvo mas com diferentes tipos de evento ou captura de parâmetros!!

Sintaxe:

elemento.addEventListener('keyup', function(evento) {
&nbsp; &nbsp; &nbsp; teclado.pressionadas[evento.keyCode] = false;
&nbsp; &nbsp; &nbsp;&nbsp;});

____________________________________________________________________

LINK DE RELATÓRIO DE EXEMPLO
autores: FILIPE MARRION FROZZA FONTES, GABRIEL JOB LINCK e RAFAEL DE OLIVEIRA FANTINEL - Turma da Tarde

____________________________________________________________________

Colisão e HitTest


Colisão:&nbsp;É a parte mais básica de qualquer game desenvolvido! Pertence a própria física do jogo ao engine do jogo. Por exemplo, quando dois objetos se encontram (colidem) eles podem:
- Aplicar dano ao adversário- Desta colisão podemos definir uma pontuação- Desta pontuação podemos avançar de níveis- Definição entre interações entre os personagens, inimigos e/ou obstáculos do game.
De acordo com o Livro&nbsp;Desenvolva Jogos com HTML e JavaScript, a colisão é um dos métodos mais simples para detectar as colisões. A colisão pode ser configurada por meio da criação de uma caixa delimitadora&nbsp;(bounding box)&nbsp;ao redor de cada sprite e verificar a interseção entre os retângulos. Quando estes retângulo se tocarem, ocorre a colisão.
HitTest é uma classe que verifica se um ou mais objetos se encontram parcialmente dentro da área de um outro.&nbsp;
Link1
Link2
Link3




De acordo com o Livro&nbsp;Desenvolva Jogos com HTML e JavaScript, a colisão é um dos métodos mais simples para detectar as colisões. A colisão pode ser configurada por meio da criação de uma caixa delimitadora&nbsp;(bounding box)&nbsp;ao redor de cada sprite e verificar a interseção entre os retângulos. Quando estes retângulo se tocarem, ocorre a colisão.







Na imagem acima, estamos vendo a interseção dos bouding box. Este tipo de colisão no jogo Sonic pode provocar dano aos adversários.



Podemos utilizar também, vários bouding box para configurar o nosso personagem, assim conseguiremos controlar de forma mais eficiente os ataques.
As colisões serão configuradas de acordo com as áreas de interseção dos objetos.









Pela geometria, dois retângulos se intersectam se:



- (x1 + largura1) &gt; x2 E

- x1 &lt; (x2 + largura2) E

- (y1 + altura1) &gt; y2 E

- y1 &lt; (y2 + altura2)







Classe Colisor:





Classe é uma estrutura que descreve estados e comportamentos de um determinado objeto.



No Javascript utilizamos uma função para criar a classe.&nbsp;Para criar propriedades podemos usar a palavra&nbsp;var&nbsp;ou&nbsp;this. Se utilizarmos a palavra&nbsp;var o atributo vai ficar privado&nbsp;e se utilizarmos a palavra&nbsp;this o atributo vai ficar publico.





function nome_da_classe() {&nbsp;

&nbsp; &nbsp; &nbsp; var avatar;&nbsp;

&nbsp; &nbsp; &nbsp; this.nome;&nbsp;

}



function document_OnLoad() {

&nbsp; &nbsp; &nbsp; &nbsp; nome_da_classe = new nome_da_classe();&nbsp;

&nbsp; &nbsp; &nbsp; &nbsp;nome_da_classe.nome = 'Maria';&nbsp;

}





Neste Tutorial, podemos encontrar facilmente como trabalharmos com Classe no JavaScript!





Exemplo de Colisão!



HTML

JS - Colisão

JS - Bolinhas

Exemplo 2
HTML Brick
JS - Colisão



Exemplo 3
Exemplo de script para colisão:
var MB_checkCollides = function() {
&nbsp; &nbsp; &nbsp; &nbsp; var loopIndex = &nbsp;MB_collides.length,&nbsp;
   element,
   p1, p2,
   p1Top, p1Bottom, p1Left, p1Right,
   p2Top, p2Bottom, p2Left, p2Right;
  
  while(loopIndex--) {
   p1 = MB_collides[loopIndex];
   p1Top = p1.posY + p1.collisionZone.top;
   p1Bottom = p1.posY + p1.height - p1.collisionZone.bottom;
   p1Left = p1.posX + p1.collisionZone.left;

   p1Right = p1.posX + p1.width - p1.collisionZone.right;
for(element in MB_collides[loopIndex].hitEvents){
  &nbsp;&nbsp;&nbsp;  p2 = MB_fixedIndexColl[element];
  &nbsp;&nbsp;&nbsp;  p2Top = p2.posY + p2.collisionZone.top;
    p2Bottom = p2.posY + p2.height - p2.collisionZone.bottom;
    p2Left = p2.posX + p2.collisionZone.left;
    p2Right = p2.posX + p2.width - p2.collisionZone.right;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/*
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MB_mainContext.moveTo(p2Right, p2Top);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MB_mainContext.lineTo(p2Right, p2Bottom);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MB_mainContext.lineTo(p2Left, p2Bottom);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MB_mainContext.lineTo(p2Left, p2Top);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MB_mainContext.lineTo(p2Right, p2Top);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MB_mainContext.stroke();
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; */
    if (!(
     (p1Top  &gt; p2Bottom) || &nbsp;&nbsp;
     (p1Bottom &lt; p2Top)&nbsp; || &nbsp;&nbsp;
     (p1Left  &gt; p2Right)&nbsp; || &nbsp;&nbsp;
     (p1Right &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt; p2Left)
    )){
      //console.dir(MB_collides[loopIndex].hitEvents)
      MB_collides[loopIndex].hitEvents[element]();
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; };
_________________________________________________________
Na continuação do exemplo, as áreas de colisão, são configuradas em cada classe dos inimigos!
&nbsp;playerConf : {
&nbsp; &nbsp; &nbsp; &nbsp; 'filename':'odys',
&nbsp; &nbsp; &nbsp; &nbsp; 'width':80,
&nbsp; &nbsp; &nbsp; &nbsp; 'height': 90,
&nbsp; &nbsp; &nbsp; &nbsp; 'frames': 3,
&nbsp; &nbsp; &nbsp; &nbsp; 'animations':1,
&nbsp; &nbsp; &nbsp; &nbsp; 'animationSpeed':5,
&nbsp; &nbsp; &nbsp; &nbsp; 'shadowDistance':80,
&nbsp; &nbsp; &nbsp; &nbsp; 'collisionZone':{top:50, right:23, bottom:0, left:7}
&nbsp; &nbsp; },&nbsp;
_________________________________________________________
**** código base do game Odyssey