Mueve la bola

Esta traducción está incompleta. Por favor, ayuda a traducir este artículo del inglés.

Este es el segundo paso en los 10 del tutorial de Canvas para el desarrollo de juegos. Puedes encontrar el código fuente de como debería quedar después de completar la lección en Gamedev-Canvas-workshop/lesson2.html.

Ya sabes cómo dibujar una pelota del trabajo realizado en el artículo anterior, así que ahora vamos a hacer que se mueva. Técnicamente, estaremos pintando la pelota en la pantalla, borrándola y luego pintándola de nuevo en una posición ligeramente diferente cada fotograma para dar la   impresión de movimiento - al igual que funciona el movimiento con las películas.

 

Definiendo un bucle de dibujo

Para mantener la actualización constante del dibujo en el lienzo (canvas) en cada fotograma, necesitamos definir una función de dibujo que se ejecutará una y otra vez, con un conjunto diferente de valores de variable cada vez para cambiar posiciones del objetoe, etc. Puedes ejecutar una función una y otra vez utilizando una función de sincronización de JavaScript, como setInterval() or requestAnimationFrame().

Elimina todo el JavaScript que tienes actualmente dentro de tu archivo HTML, excepto las dos primeras líneas, y añade lo siguiente debajo de ellas. La función draw () se ejecutará dentro de setInterval cada 10 milisegundos:

function draw() {
    // drawing code
}
setInterval(draw, 10);

Gracias a la naturaleza infinita de setInterval, la función draw () se llamará cada 10 milisegundos por siempre, o hasta que lo detengamos. Ahora, vamos a dibujar la bola agrega lo siguiente dentro de tu función draw ():

ctx.beginPath();
ctx.arc(50, 50, 10, 0, Math.PI*2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();

Prueba tu código actualizado ahora — la bola debería repintarse en cada fotograma (frame).

Haciendo que se mueva

No notaremos que la bola que está siendo repintada constantemente en el momento, pues no se está moviendo. Vamos a cambiar eso. En primer lugar, en lugar de una posición codificada en (50, 50) definiremos un punto de inicio en la parte central inferior del lienzo en las variables llamadas x e y, a continuación, debemos usarlas para definir la posición en la que se dibuja el círculo.

Primero, agrega las dos líneas siguientes sobre tu función draw (), para definir x e y:

 

var x = canvas.width/2;
var y = canvas.height-30;

A continuación actualiza la función draw() para usar las variables x e y en el método arc(), como se muestra en la siguiente línea resaltada:

function draw() {
    ctx.beginPath();
    ctx.arc(x, y, 10, 0, Math.PI*2);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
}

Ahora viene la parte importante: queremos añadir un valor pequeño a x e y después de que cada fotograma se haya dibujado para que parezca que la pelota se está moviendo. Definamos estos valores pequeños como dx y dy y establezcamos sus valores en 2 y -2 respectivamente. Agrega lo siguiente debajo de sus definiciones de variables x e y:

var dx = 2;
var dy = -2;

Lo último que hay que hacer es actualizar x e y con nuestra variable dx y dy en cada fotograma, de modo que la bola será pintada en la nueva posición en cada actualización. Agrega las dos nuevas líneas siguientes indicadas a continuación a la función draw ():

The last thing to do is to update x and y with our dx and dy variable on every frame, so the ball will be painted in the new position on every update. Add the following two new lines indicated below to your draw() function:

function draw() {
    ctx.beginPath();
    ctx.arc(x, y, 10, 0, Math.PI*2);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
    x += dx;
    y += dy;
}

Guarda el código de nuevo y pruébalo en tu navegador. Esto funciona bien, aunque parece que la bola está dejando un rastro detrás de ella:

Limpiando el  lienzo antes de cada fotograma

 
La bola está dejando un rastro porque estamos pintando un nuevo círculo en cada fotograma sin quitar el anterior. No te preocupes, porque hay un método para eliminar contenido de lienzo: clearRect (). Este método toma cuatro parámetros: las coordenadas x e y de la esquina superior izquierda de un rectángulo y las coordenadas x e y de la esquina inferior derecha de un rectángulo. Todo el área cubierta por este rectángulo será despejada de cualquier contenido previamente pintado allí.
 

Añade la siguiente nueva línea resaltada a la función draw():

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(x, y, 10, 0, Math.PI*2);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
    x += dx;
    y += dy;
}

Guarda tu código e inténtalo de nuevo, y esta vez verás el movimiento de la bola sin un rastro. Cada 10 milisegundos se despeja el lienzo, se dibujará el círculo azul (nuestra pelota) en una posición determinada y los valores x e y se actualizarán para el siguiente fotograma.

Limpiando nuestro códigoCleaning up our code

Vamos a añadir más y más comandos a la función draw () en los próximos artículos, por lo que es bueno mantenerlo lo más simple y limpio posible. Comencemos moviendo el código de dibujo de bola a una función separada.

Reemplaza la función draw() existente con las dos funciones siguientes:

function drawBall() {
    ctx.beginPath();
    ctx.arc(x, y, 10, 0, Math.PI*2);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
}

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawBall();
    x += dx;
    y += dy;
}

Compara tu código

Puedes comprobar el código terminado de este artículo por ti mismo en la demostración en vivo a continuación, y jugar con ella para entender mejor cómo funciona:

Ejercicio: intenta cambiar la velocidad de la bola en movimiento o la dirección hacia la que se mueve.

Siguientes pasos

Hemos dibujado nuestra bola y hemos hecho que se mueva, pero cuando supera el borde del canvas, desaparece. En el terecer tema exploraremos como hacer que rebote en las paredes.

Etiquetas y colaboradores del documento

 Colaboradores en esta página: jolosan, emolinerom
 Última actualización por: jolosan,