Cómo crear un juego muy simple con el elemento canvas

La programación no solo puede ser un proceso aburrido en el que solo se desarrollan aplicaciones de escritorio para ejecutivos y administrativos y páginas webs corporativas, también puede ser el inicio donde se gesta una de las principales zonas de ocio del siglo XXI: los videojuegos. Aunque seguro que lo sabes compañero programador, los videojuegos nacen de un diseñador de videojuegos, un programador y un artista. La unión de estos tres tótems desarrolla en uno de los principales entretenimientos de la actualidad.

La programación web no queda aislada de esto y, mediante ella, también es posible implementar videojuegos. En este artículo te vamos a mostrar paso por paso cómo crear un juego muy simple en canvas.

El juego es, básicamente, una suerte de “pilla-pilla” en el que controlamos a una pelota de color azul. El objetivo del juego es alcanzar a la pelota roja la cual se mueve aleatoriamente por la pantalla. Para ello, debes pinchar a lo largo de la pantalla para hacer que la pelota azul se desplace al punto designado. No subestimes al juego, a pesar de ser simple, es realmente adictivo.

En primer lugar, vamos un documento HTML con la estructura estándar y un elemento canvas tal que así:

<!DOCTYPE HTML>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <title>Simple game using CANVAS</title>
</head>
    <h1>Simple game using CANVAS</h1>
    <canvas id = "cont" height="600" width="600" >Your browser does not support canvas</canvas>
<body>
</html>

Creamos una instancia en la etiqueta script, para el objeto responsable de generar las animaciones en el canvas. Esto debe hacerse dentro de la etiqueta head.

<script type="text/javascript">
window.onload =  function(){

var element = document.getElementById("cont");
            var context = element.getContext("2d");
            if(context){
                /*Everything will be done here*/
            }
}
</script>

Ahora vamos a crear dos clases: Destiny y Bol. Si no tienes conocimientos sobre objetos en Javascript te sugiero que antes le eches una ojeada a la siguiente documentación: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript.

var Destiny = function(x,y){
// Attributes
this.x = x;
this.y = y;
this.w = 10;
this.h = 10;

// Methods
this.update = function(x,y){
    this.x = x;
    this.y = y;
    }
}

//To instantiate the object Destiny, do this:
var destiny = new Destiny(10,10);

Bien, volviendo al asunto, vamos a crear la otra clase, la que hemos llamado Bol, y vamos a definir sus métodos y atributos:

var Bol = function(x,y,r,vX,vY){
                // Attributes
                this.x = x;
                this.y = y;
                this.vX = vX;
                this.vY = vY;
                this.r = r;
                this.dX = 0;
                this.dY = 0;
                this.move = 0;
                this.sX = 1;
                this.sY = 1;

                // Function that implements update the coordinates
                this.update = function(){
                    this.x += this.vX;
                    this.y += this.vY;
                }

                // The following function checks if the blue ball touched a corner of the screen. If yes, the ball is redirected to the opposite direction.
                this.checkColision = function(){
                    if((this.x + this.r) >= widthCanvas){
                        this.vX *= -1;
                        this.sX = -this.sX;
                    }else if((this.x - this.r) < 0){
                        this.vX *= -1;
                        this.sX = -this.sX;
                    }
                    if((this.y + this.r) >= heightCanvas){
                        this.vY *= -1;
                        this.sY = -this.sY;
                    }else if((this.y - this.r) < 0){
                        this.vY *= -1;
                        this.sY = -this.sY;
                    }
                }

                /*The dX attribute is the X coordinate of Destiny object, which is the fate of the blue bol*/
                this.setDestinyX = function(x){
                    this.dX = x;
                }

                /*The dY attribute is the Y coordinate of Destiny object, which is the fate of the blue dot*/
                this.setDestinyY = function(y){
                    this.dY = y;
                }

                /*In the method below, I am setting programmatically, as do the red dot move autonomously.
                In the case below, it changes direction as the return of returnEvenOdd()
                */
                this.moveAuto = function(){
                    var x = returnEvenOdd();
                    if(x == true){
                        this.vX *= -1;
                        this.sX = -this.sX;
                    }else{
                        this.vY *= -1;
                        this.sY = -this.sY;
                    }
                }

                /*Function below recover a random value. If it is divisible by 2, returns TRUE. Otherwise, it returns FALSE*/
                function returnEvenOdd(){
                    var one;
                    var check;
                    one = Math.floor( (Math.random()*6) + 1 );
                    check = (um % 2 == 0?true:false);
                    return check;
                }

                /*
                In the method below, I am sure that the blue ball reached the orange dot (target object coordinates).
                If so, it stops. But he continues to follow

                */
                this.checkDestiny = function(){
                    if(this.move == 1){
                            /*Treating horizontal line*/
                        if(this.sX == 1){
                            if(this.x > this.dX){
                                this.sX = -this.sX;
                                this.vX *= -1;
                            }
                        }else if(this.sX == -1){
                            if(this.x < this.dX){
                                this.sX = -this.sX;
                                this.vX *= -1;
                            }
                        }

                            /*Treating vertical line*/
                        if(this.sY == 1){
                            if(this.y > this.dY){
                                this.sY = -this.sY;
                                this.vY *= -1;
                            }
                        }else if(this.sY == -1){
                            if(this.y < this.dY){
                                this.sY = -this.sY;
                                this.vY *= -1;
                            }
                        }
                        if(( this.x > (this.dX-this.vX) && this.x < (this.dX + this.vX) ) && ( this.y > (this.dY-this.vY) && this.y < (this.dY + this.vY) )){
                            this.move = 0;
                        }
                        this.update();
                    }
                }
            }

A continuación, inicializamos las variables necesarias para echarse una partidita:

/*Capturing the width and height of the element CANVAS.*/
var heightCanvas = element.height;
var widthCanvas = element.width;

/*Defining the coordinates of the blue dot*/
var x = Math.floor((Math.random()*widthCanvas)+1);
var y = Math.floor((Math.random()*heightCanvas)+1);

/*Ray range, for collision detection between the balls*/
var r = 10;

/* Speed of the balls */
var vX = 5;
var vY = 5;

/* Instantiating the game objects */
var bol = new Bol(x,y,r,vX,vY);
var blue = new Bol(Math.floor((Math.random()*widthCanvas)+1),Math.floor((Math.random()*heightCanvas)+1),r,vX,vY);
var destiny = new Destiny(blue.x,blue.y);

/* Each ball is that balls group below */
var bols  = new Array();
bols.push(bol);
bols.push(blue);

/*Every 2 seconds, runs the method that changes the red ball position*/
setInterval(function(){ bol.moveAuto(); },2000);

/*Where they are made drawings on the screen, based on the properties of objects*/
draw();

/* Implementation of updating the properties of the objects  */
animate();

Para entender el método draw(), debes contar con un conocimiento base del "contexto" en el que funciona. http://www.creativebloq.com/design/learning-basics-html5-canvas-7112879

function draw(){
    /* Before drawing, you must clear the screen */
    context.clearRect(0,0,widthCanvas,heightCanvas);

    /* Drawing the red ball */
    context.fillStyle="#FF0000";
    context.beginPath();
    context.moveTo(bol.x,bol.y);
    context.arc(bol.x,bol.y,bol.r,0,Math.PI*2);
    context.closePath();
    context.fill();

    /* Drawing the blue ball */
    context.fillStyle="#0000FF";
    context.beginPath();
    context.moveTo(blue.x,blue.y);
    context.arc(blue.x,blue.y,blue.r,0,Math.PI*2);
    context.closePath();
    context.fill();

    /* Drawing the destination point (orange square) */
    context.beginPath();
    context.fillStyle = "#FF7F50";
    context.fillRect(destiny.x,destiny.y,destiny.w,destiny.h);
    context.fill();
}

La función animate() es el control del juego. Esta función se lleva a cabo dentro de un determinado rango de tiempo, para identificar y definir el estado del juego:

function animate(){
    bola.checkColision();
    bola.update();

    eu.checkColision();
    eu.checkDestiny();

    colision();

    draw();

    setTimeout(animate,30);
}

Cuando haces click en algún lugar de la pantalla del canvas, el target de la bola azul cambia y se dirige hacia el punto en el que se haya hecho click

element.onclick = function(e){

    /*Capturing coordinates of the click*/
    var pX;
    var pY;
    pX = e.pageX - this.offsetLeft;
    pY = e.pageY - this.offsetTop;

    eu.setDestinyX(pX);
    eu.setDestinyY(pY);
    eu.move = 1;

    destino.update(pX,pY);
//    draw();
}

La función colision() es la responsable de verificar cuando se chocan la pelota azul y la pelota roja

function colision(){
    /* Through a FOR loop, iterate the elements of variables 'bols' */
    for(var i = 0;i+1<bols.length;i++){
        var j = i+1;

        /* Recovering the two balls: a ball red and blue */


        /*  Checking if there was collision */
        if( (
                ( bols[i].x + 2*bols[i].r) > bols[j].x
                    &&
                (bols[i].x + 2*bols[i].r) < (2*bols[j].r + bols[j].x)
            ) &&
            (
                    (bols[i].y + 2*bols[i].r) > bols[j].y
                    &&
                    (bols[i].y + 2*bols[i].r) < (2*bols[j].r + bols[j].y)
            )
        ){
            alert("Congratulations!!");
          }

    }
}

Y con esto estaría todo hecho, espero que hayas podido reproducir este simple juego y que te puedas echarte tus pequeñas partidas. Por cierto, el juego lo podeís descargar desde aquí y es obra de Wagner NULL.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP