--- title: Ejercicio práctico de construcción de objetos slug: Learn/JavaScript/Objects/Object_building_practice translation_of: Learn/JavaScript/Objects/Object_building_practice original_slug: Learn/JavaScript/Objects/Ejercicio_práctico_de_construcción_de_objetos ---
{{LearnSidebar}}
{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}

En los artículos anteriores se explicó lo fundamental de la teoría de los objetos en JavaScript asi como su sintaxis, para que Usted tenga un punto de partida sólido. En éste artículo, desarrollaremos un ejercicio práctico para ganar experiencia en la programación de objetos en JavaScript, con un resultado divertido y colorido.

Pre-requisitos: Conocimientos básicos de computadores. Entendimiento básico de HTML y CSS. Familiaridad con los conceptos básicos de JavaScript (vea Primeros Pasos con JavaScript y Elementos básicos de JavaScript)  y OOJS (vea Conceptos básicos de los objetos JavaScript).
Objetivos: Ganar experiencia en el uso de objetos y el uso de programación orientada a objetos en un contexto realista.

Lanzemos algunas pelotas

Es éste artículo escribiremos un programa demo del juego clásico de pelotas que rebotan para mostrar la gran útilidad de los objetos en JavaScript. En éste demo las pelotas rebotaran en la pantalla y cambiaran de color cuando choquen unas con otras. Así, al final del ejemplo tendremos algo como esto:

En este ejemplo se utilizará Canvas API para dibujar las pelotas en la pantalla y la API requestAnimationFrame para animar todo el contenido de la pantalla. No es necesario que conozca estas funciones previamente. Esperamos que al final de este artículo, quizás pueda estar interesado en explorar su uso y capacidades más en detalle. Durante este desarrollo usaremos objetos y algunas técnicas para hacer que las pelotas puedan rebotar en los bordes y comprobar cuando choquen entre ellas (ésto se conoce como detección de colisiones). 

Primeros pasos

Para comenzar haga una copia en su computador de los archivos:  index.html, style.css, y main.js. Estos contienen:

  1. Un documento HTML sencillo con un elemento <h1>, un elemento <canvas> en el que podamos dibujar los gráficos y otros elementos para aplicar los estilos CSS y el código JavaScript. 
  2. Algunos estilos sencillos que servirán para ubicar el elemento <h1>, ocultar la barra de desplazamiento y los margenes del borde de la página (para que luzca mejor).
  3. Un archivo JavaScript que sirve para definir el elemento <canvas> y las funciones que vamos a usar.

La primera parte del script es:

var canvas = document.querySelector('canvas');

var ctx = canvas.getContext('2d');

var width = canvas.width = window.innerWidth;
var height = canvas.height = window.innerHeight;

Este script obtiene una referencia del elemento <canvas>, luego llama al método getContext() para definir un contexto en el cual se pueda comenzar a dibujar. La resultado de la variable  (ctx) es el objeto que representa directamente el área de dibujo del <canvas> y permite dibujar elementos 2D en él. 

A continuación se da valor a las variables width and height que corresponden al ancho y alto del elemento canvas (representado por las propiedades canvas.width y canvas.height), de manera que el alto y ancho coincidan con el alto y ancho del navegador (viewport)  cuyos valores se obtienen directamente de las propiedades window.innerWidth window.innerHeight.

Puede ver que en el código se encadenan varias asignaciones, para obtener valores más rápidamente. Esto se puede hacer.

La última parte del script, es la siguiente:

function random(min, max) {
  var num = Math.floor(Math.random() * (max - min + 1)) + min;
  return num;
}

Esta función recibe dos números como argumentos de entrada (valor mínimo y maximo) y devuelve un número aleatorio entre ellos.

Modelando una pelota en nuestro programa

Nuestro programa tendrá montones de pelotas rebotando por toda la pantalla. Ya que todas las pelotas tendrán el mismo comportamiento, tiene sentido representarlas con un objeto. Empezamos definiendo un constructor para el objeto pelota (Ball), en nuestro código.

function Ball(x, y, velX, velY, color, size) {
  this.x = x; //posición horizontal
  this.y = y; //posición vertical
  this.velX = velX; //velocidad horizontal
  this.velY = velY; //velocidad vertical
  this.color = color; //color
  this.size = size; //tamaño
}

Aquí incluimos algunos parámetros que serán las propiedades que cada pelota necesita para funcionar en nuestro programa: 

Con esto se resuelven las propiedades del objeto, ¿Pero qué hacemos con los métodos? Ya que queremos que las pelotas realicen algo en nuestro programa. 

Dibujando las pelotas

Para dibujar, añadiremos el siguiente método draw() al prototipo del objeto Ball():

Ball.prototype.draw = function() {
  ctx.beginPath();
  ctx.fillStyle = this.color;
  ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
  ctx.fill();
}

Con esta función cada objeto pelota Ball() puede dibujarse en la pantalla utilizando el contexto 2D definido anteriormente (ctx)  

Ya se puede empezar a testear el objeto.

  1. Guarde el código hasta ahora, y cargue el archivo HTML en un navegador.
  2. Abra la consola de JavaScript en el navegador, y refresque la página, para que el tamaño del canvas modifique sus dimensiones adaptándose al viewport con la consola abierta. 
  3. Teclee lo siguiente en la consola para crear una nueva pelota.
    var testBall = new Ball(50, 100, 4, 4, 'blue', 10);
  4. Pruebe a llamar a las variables miembro:
    testBall.x
    testBall.size
    testBall.color
    testBall.draw()
  5. Al teclear la última línea, debería ver que la pelota se dibuja en alguna parte del canvas

Actualizando los datos de la pelota

Ahora podemos dibujar una pelota en una posición dada, pero para empezar a moverla, se necesita una función de actualización de algún tipo. Podemos añadir el código a continuación, al final del archivo de JavaScript, para añidir un método de actualización update() en el prototipo de la clase Ball()

Ball.prototype.update = function() {
  if ((this.x + this.size) >= width) {
    this.velX = -(this.velX);
  }

  if ((this.x - this.size) <= 0) {
    this.velX = -(this.velX);
  }

  if ((this.y + this.size) >= height) {
    this.velY = -(this.velY);
  }

  if ((this.y - this.size) <= 0) {
    this.velY = -(this.velY);
  }

  this.x += this.velX;
  this.y += this.velY;
}

Las cuatro primeras partes de la función verifican si la pelota a alcanzado el borde del canvas. Si es así, se invierte la dirección de la velocidad, para que la pelota se mueva en la dirección contraria. Así, si la pelota va hacia arriba, (velY positiva) , entonces la velocidad vertical es cambiada, para que se mueva hacia abajo (velY negativa).

Los cuatro posibles casos son: 

En cada caso, se ha tenido en cuenta el tamaño (size) de la pelota en los cálculos, ya que las coordenadas x e y corresponden al centro de la pelota, pero lo que queremos ver es el borde de la pelota cuando choca con el perímetro del canvas — que la pelota rebote, cuando está a medio camino fuera de el —.

Las dos últimas líneas de código, suman  la velocidad en x (velX) al valor de la coordenada x  , y el valor de la velocidad en y (velY)  a la coordenada y —  con esto se consigue el efecto de que la pelota se mueva cada vez que este método es llamado. 

Llegados a este punto: ¡continuemos, con las animaciones!

Animando las pelotas

Hagamos esto divertido! Ahora vamos a empezar a añadir pelotas al canvas, y animándolas.

1. Primero, necesitamos algún sitio donde guardas las pelotas. El siguiente arreglo hará esta función — añádela al final de tu código. 

var balls = [];

Todos los programas que generan animaciones normalmente tienen un bucle de animación, que sirve para actualizar los datos del programa, para entonces generar la imagen correspondiente; esta es la estrategia básica para la mayor parte de juegos y programas similares. 

2. Añadamos las siguientes instrucciones al final del código: 

function loop() {
  ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
  ctx.fillRect(0, 0, width, height);

  while (balls.length < 25) {
    var size = random(10,20);
    var ball = new Ball(
      // la posición de las pelotas, se dibujará al menos siempre
      // como mínimo a un ancho de la pelota de distancia al borde del
      // canvas, para evitar errores en el dibujo
      random(0 + size,width - size),
      random(0 + size,height - size),
      random(-7,7),
      random(-7,7),
      'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')',
      size
    );
    balls.push(ball);
  }

  for (var i = 0; i < balls.length; i++) {
    balls[i].draw();
    balls[i].update();
  }

  requestAnimationFrame(loop);
}

Nuestra función de bucle: loop(), hace lo siguiente: 

3. Por último, pero no menos importante, añadimos la siguiente línea, al final del código.-- es necesario llamar a la función inicialmente para que la animación comience. 

loop();

Eso es todo para la parte básica — pruebe a guardar el código y refrescar el navegador para comprobar si aparecen las pelotas rebotando!

Añadiendo la detección de colisiones

Ahora, un poco de diversión, añadamos la detección de colisiones a nuestro código. Así las pelotas, sabrán cuando chocan unas contra otras.

  1. El primer paso, será añadir el código a continuación a continuación de donde se definió el método  update(). (en código de Ball.prototype.update)
    Ball.prototype.collisionDetect = function() {
      for (var j = 0; j < balls.length; j++) {
        if (!(this === balls[j])) {
          var dx = this.x - balls[j].x;
          var dy = this.y - balls[j].y;
          var distance = Math.sqrt(dx * dx + dy * dy);
    
          if (distance < this.size + balls[j].size) {
            balls[j].color = this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) +')';
          }
        }
      }
    }

    Esta función es un poco complicada, así que no hay que preocuparse mucho si de momento no se comprende del todo.  

  2. También es necesario llamar este método en cada instante de la animación. balls[i].update(); en la línea:
    balls[i].collisionDetect();
  3. Guardar y refrescar la demo de nuevo y podrá ver como las pelotas cambian de color cuando chocan entre ellas.

Nota: Si tiene problemas para hacer funcionar este ejemplo, puede comparar su código JavaScript, con el código de la version_final (y también ver como funciona al ejecutarla).

Resumen

Esperamos que se haya divertido escribiendo su propio mundo de pelotas que chocan aleatoriamente, usando objetos y programación orientada a objetos. Esto debería haberle dado una práctica útil y haber sido un buen ejemplo. 

Lea también

{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}

En este módulo