Tratamento de Choque para jogo em javaScript
São duas imagens onde as dimensões de cada quadrado possuem w e h de 17 pixeis.
O fonte e as duas imagens:
<html>
<body onload="startGame()">
<script>
//=================================================================================================
// Autor: Luiz Augusto S. Prado - 2018
// javaScript: Game
//=================================================================================================
window.requestAnimationFrame = function()
{
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||window.oRequestAnimationFrame ||
function(f)
{
window.setTimeout(f,1e3/60);
}
}();
getNumber = function(str)
{
var r = Number( str.charCodeAt(0) )
if(r>47 && r<58) r-=48
if(r>64 && r<91) r-=55
if(r>96 && r<123)r-=87
return r;
}
paintImagem = function(ctx, ctx2, pos_x_0, pos_y_0, tamanhox, tamanhoy, pos_x_f, pos_y_f, escala, ang)
{
ctx.translate( pos_x_f, pos_y_f );
ctx.rotate(-ang * Math.PI / 180);
ctx.drawImage(ctx2, pos_x_0, pos_y_0, tamanhox, tamanhoy, escala, escala, escala, escala);
ctx.rotate(ang * Math.PI / 180);
ctx.translate( -pos_x_f, -pos_y_f);
}
Hero = function()
{
this.onde_estou = "no_mapa"
this.speedX = 0;
this.speedY = 0;
this.color = "red";
this.width = 16;
this.height = 16;
}
paintHero = function(mapa)
{
mapa.ctx.fillStyle = mapa.hero.color;
mapa.ctx.fillRect(mapa.canvas.width/2, mapa.canvas.height/2, 16, 16)
}
Ground = function(x0, y0, xf, yf)
{
this.x = xf/2*17
this.y = yf*17
this.onde_estou = "no_mapa"
this.width = 17;
this.height = 17;
this.px = x0*this.width;
this.py = y0*this.height;
}
Item = function(x0, y0, xf, yf)
{
this.x = xf/2*17
this.y = yf*17
this.onde_estou = "no_mapa"
this.width = 17;
this.height = 17;
this.px = x0*this.width;
this.py = y0*this.height;
}
paintMap= function(mapa)
{
var ctx = mapa.ctx;
var arq = mapa.arquivo_mapas;
var w=mapa.canvas.width/2
var h=mapa.canvas.height/2;
for(var py=0; mapa.mapa!=null && py<mapa.mapa.length; py++ )
{
for(var px=0; px<mapa.mapa[py].length; px++ )
{
if( mapa.mapa[py][px]!=null )
{
var m = mapa.mapa[py][px];
var tm=m.width;
paintImagem(ctx, arq, m.px, m.py, tm, tm, m.x-mapa.hero.x+w-4, m.y-mapa.hero.y+h-4, tm+2, 0)
}
}
}
}
paintItens = function(mapa)
{
var ctx = mapa.ctx;
var arq = mapa.arquivo_itens;
var w=mapa.canvas.width/2
var h=mapa.canvas.height/2;
for(var py=0; mapa.itens!=null && py<mapa.itens.length; py++ )
{
for(var px=0; px<mapa.itens[py].length; px++ )
{
if( mapa.itens[py][px]!=null )
{
var m = mapa.itens[py][px];
var tm=m.width;
paintImagem(ctx, arq, m.px+mapa.time*tm, m.py+1, tm, tm-1, m.x-mapa.hero.x+w-4, m.y-mapa.hero.y+h-4, tm+2, 0)
}
}
}
}
function createItens()
{
var str = document.getElementById("itens").value
str = str.replace(new RegExp(/ /, 'gi'), "");
var res = str.split("|\n");
var array_final = new Array();
for(var py=0; py<res.length-1; py++)
{
array_final[py]=[]
for(var px=0; px<res[py].length; px+=2)
{
if( res[py].charAt(px)!='3' && res[py].charAt(px+1)!='z' )
{
array_final[py][px/2] = new Item(getNumber( res[py].charAt(px)) , getNumber( res[py].charAt(px+1) ), px, py );
}
}
}
return array_final;
}
function createMapa()
{
var str = document.getElementById("mapa").value
str = str.replace(new RegExp(/ /, 'gi'), "");
var res = str.split("|\n");
var array_final = new Array();
for(var py=0; py<res.length-1; py++)
{
array_final[py]=[]
for(var px=0; px<res[py].length; px+=2)
{
if( res[py].charAt(px)!='3' && res[py].charAt(px+1)!='z' )
{
array_final[py][px/2] = new Ground(getNumber( res[py].charAt(px)) , getNumber( res[py].charAt(px+1) ) , px, py );
}
}
}
return array_final;
}
/*===========================================
O mapa anda ao contrário. Ele é a referência.
e1 d1 e2 d2
n1_|_|_n1 n2_|_|_n2 a. .b y1
s1_|_|_s1 s2_|_|_s2 c. .d y2
| | | | x1 x2
e1 d1 e2 d2
*/
function isHitting(obj1, obj2, tm)
{
var e1 = obj1.x - obj1.speedX -tm
var d1 = obj1.x - obj1.speedX
var n1 = obj1.y - obj1.speedY -tm
var s1 = obj1.y - obj1.speedY
var e2 = obj2.x
var d2 = obj2.x + tm
var n2 = obj2.y
var s2 = obj2.y + tm
var x1 = e1<=d2 && d2<=d1
var x2 = e1<=e2 && e2<=d1
var y1 = n1<=s2 && s2<=s1
var y2 = n1<=n2 && n2<=s1
var a = x1 && y1
var b = x2 && y1
var c = x1 && y2
var d = x2 && y2
if( a || c || b || d )
{
if( (x1 || x2) && obj1.speedY!=0 ) obj1.speedY =0
if( (y1 || y2) && obj1.speedX!=0 ) obj1.speedX =0
return true
}
return false
}
function Mapa()
{
this.start = function()
{
this.arquivo_mapas = new Image()
this.arquivo_mapas.src = "mapa.png"
this.arquivo_itens = new Image()
this.arquivo_itens.src = "itens.png"
this.canvas = document.createElement("canvas")
this.count = 0;
this.time=0;
this.ctx = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.canvas.width = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth )-70;
this.canvas.height= (window.innerHeight|| document.documentElement.clientHeight|| document.body.clientHeight)-70;
window.addEventListener('keydown', function (e)
{
window.keys = (window.keys || []);
window.keys[e.keyCode] = (e.type == "keydown") ;
})
window.addEventListener('keyup', function (e)
{
window.keys[e.keyCode] = (e.type == "keydown") ;
})
this.itens = createItens();
this.mapa = createMapa ();
this.hero = new Hero ();
this.hero.x = 0;
this.hero.y = 0;
}
this.clear = function()
{
this.canvas.width = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth )-70;
this.canvas.height= (window.innerHeight|| document.documentElement.clientHeight|| document.body.clientHeight)-70;
this.ctx.fillStyle="#99ccff";
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
}
this.calcs = function()
{
this.hero.speedX = 0;
this.hero.speedY = 0;
this.hero.w = this.canvas.width/2;
this.hero.h = this.canvas.height/2;
this.count++
if(this.count%10==0)
{
this.time++
if(this.time==4){this.time=0; this.count=0}
}
if (window.keys && window.keys[37]) {this.hero.speedX = 2; }
if (window.keys && window.keys[39]) {this.hero.speedX =-2; }
if (window.keys && window.keys[38]) {this.hero.speedY = 2; }
if (window.keys && window.keys[40]) {this.hero.speedY =-2; }
var saida=false;
for(var py=0; py<this.mapa.length; py++)
{
for(var px=0; px<this.mapa[py].length; px++)
{
if(this.mapa[py][px]!=null)
{
saida = isHitting(this.hero, this.mapa[py][px], 17)
}
if( saida ) break
}
if( saida ) break
}
this.hero.x -= this.hero.speedX;
this.hero.y -= this.hero.speedY;
}
this.paint = function()
{
paintMap (this)
paintItens(this)
paintHero (this)
}
}
var mapa;
animloop = function()
{
mapa.calcs();
mapa.clear();
mapa.paint();
requestAnimationFrame(animloop);
}
function startGame()
{
mapa = new Mapa();
mapa.start();
animloop();
}
</script>
<div id="msg">mova com o teclado.</div>
<textarea id="itens" rows="30" cols="60" style="display:none;">
3z 3z 3z 3z 3z 3z 3z 3z|
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 0g 0h 0i 0j 0k 0l 0m 0n 0o|
</textarea>
<textarea id="mapa" rows="30" cols="60" style="display:none;">
3z 3z 3z 3z 3z 3z 3z 3z|
3z 3z 3z 3z 3z 3z 3z 3z|
3z 3z 3z 3z 3z 3z 3z 3z|
3z 3z 3z 3z 3z 60 10 10|
00 10 10 10 10 61 11 11|
11 11 11 11 11 11 11 11|
11 11 11 11 11 11 11 11|
11 11 11 11 11 11 11 11|
11 11 11 11 11 11 11 11|
11 11 11 11 11 11 11 11|
</textarea>
</body>
</html>