sábado, 24 de março de 2018

Tratamento de Choque para jogo em javaScript



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>

Nenhum comentário: