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:
- Abra um codificador de imagens: http://www.greywyvern.com/code/php/binary2base64
- Cole a URL da imagem: http://orig13.deviantart.net/2af0/f/2008/134/6/0/allen_sprite_sheet_x4_by_kirby144.png
- 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
Até a próxima!
2 comentários sobre “HTML5/JavaScript para Jogos (Parte 8)”