Cavaleiro

HTML5/JavaScript para Jogos (Parte 8)

Se você perdeu a parte anterior, veja-a aqui: Parte 7

A maior lição que aprendi no desenvolvimento desta parte foi a seguinte:

Se você desenhar uma imagem de outro domínio, i.e., o endereço de origem da imagem não for o mesmo da sua página, você será impedido de ler o seu canvas, pois isso poderia causar uma falha de segurança caso a imagem externa fosse trocada por código malicioso.

Assim, conforme a explicação que encontrei no stackoverflow

http://stackoverflow.com/questions/15502999/javascript-getimagedata-after-fillrect-and-drawimage

isso pode ser solucionado hospedando-se a imagem junto com sua página ou codificando-a na própria página. A primeira solução não é possível com o JS Bin, uma vez que não temos acesso ao servidor. Dessa forma, vamos codificar a imagem da seguinte maneira:

  1. Abra um codificador de imagens: http://www.greywyvern.com/code/php/binary2base64
  2. Cole a URL da imagem: http://orig13.deviantart.net/2af0/f/2008/134/6/0/allen_sprite_sheet_x4_by_kirby144.png
  3. Gere o resultado e cole-o no bloco de notas

Agora, para termos uma referência da imagem no JavaScript, vamos acrescentar a imagem ao código HTML, após o segundo canvas, da seguinte forma

<html>
  <head>
    <script type="text/javascript" src="sprites.js"></script>
  </head>
  <style>
    canvas {
      border: 1px solid black;
    }
  </style>
  <body>
    <p>Use as setas do teclado para mover a personagem</p>
    <canvas id="idCanvas" width="640" height="480">
      Seu navegador não tem suporte ao 'canvas'.
    </canvas>
    <p><i>Canvas</i> de teste</p>
    <canvas id="idCanvas2" width="640" height="480">
      Seu navegador não tem suporte ao 'canvas'.
    </canvas>
    <img id="sprite_img" alt="Embedded Image" width="400" src="..." />
  </body>
</html>

substituindo as reticências na linha 19 (mas deixando as aspas) por aquele código gigantesco da imagem. Tome cuidado para não apagar o que vem em seguida, ou o código da página não será mostrado corretamente. Repare que demos o id sprite_img, que será usado para referenciar a imagem no JavaScript. Ainda, caso queira esconder a imagem, uma vez que ela será desenhada no canvas, altere a tag img para o seguinte

<img id="sprite_img" alt="Embedded Image" width="400" style="display: none;" src="..." />

Então, vamos alterar a referência externa à imagem para a nossa referência codificada. No método window.onload, onde tínhamos

  spritesheet2 = new Image();
  spritesheet2.src = "http://orig13.deviantart.net/2af0/f/2008/134/6/0/allen_sprite_sheet_x4_by_kirby144.png";
  spritesheet2.onload = function() {
      requestAnimationFrame(secondLoop);
  }; 

altere para

  spritesheet2 = new Image();
  spritesheet2.src = document.getElementById("sprite_img").src;
  spritesheet2.onload = function() {
    sx = canvas2.width-spritesheet2.width;
    sy = canvas2.height-spritesheet2.height;

    requestAnimationFrame(secondLoop);
  }; 

onde as variáveis sx e sy foram incluídas para termos uma referência da origem do desenho do spritesheet.

Finalmente, vamos ler um pedaço da imagem e redesenhá-lo em outro lugar através da seguinte alteração

var sx;
var sy;
var boySprite;

function secondLoop(timestamp) {
  ctx2.clearRect(0, 0, canvas.width, canvas.height);
  x2 = x2 + dx2;
  
  if (x2 > canvas.width) {
    x2 = 0;
  }
  
  ctx2.strokeRect(x2, 20, 100, 200);
  ctx2.drawImage(spritesheet2, canvas.width-spritesheet2.width, canvas.height-spritesheet2.height);
  boySprite = ctx2.getImageData(sx, sy, 65, 80);
  ctx2.putImageData(boySprite, 0, 240);
  
  requestAnimationFrame(secondLoop);
}


Verifique que a leitura da imagem é feita com ctx2.getImageData, onde os valores 65 e 80 são a largura e altura, respectivamente, de uma subimagem (e que eu descobri por tentativa e erro), que é gravada na variável boySprite. Então, a subimagem é redesenhada na posição (0, 240) com o método ctx2.putImageData.

Perceba que este não é o método usado para desenhar os sprites da personagem no primeiro canvas. Apesar do trabalho para codificar a imagem e da quantidade de “lixo” acrescentada ao código, o fato de poder gravar uma subimagem em uma variável vai facilitar nossa vida em artigos posteriores.

Veja, também, que há um bug: se você mover o retângulo para a direita até que ele atinja a spritesheet, a parte do retângulo que estiver na área lida também será redesenhada na área menor com origem em (0, 240). Isso também poderá vir a ser útil, então não vamos corrigir por enquanto.

Para ver o código e fazer seus próprios testes, acesse

http://jsbin.com/hizale

Até a próxima!

Anúncios

2 comentários sobre “HTML5/JavaScript para Jogos (Parte 8)

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s