Está en la página 1de 9

DESCRIPCIÓN DEL PASO A PASO DEL JUEGO DE LA BOLA

Primero copiamos el código de ejemplo que esta en la pagina de threejs.org, en la cabeza o


primera parte del archivo que es el (head) tenemos un charset, el título de la página title y un poco
de CSS básico. El cuerpo (body) contiene las etiquetas canvas y script. Se realizará el juego en la
primera parte y escribiremos el código JavaScript que lo controla en el segundo. El
elemento canvas tiene el id myCanvas para que podamos hacer referencia a él con facilidad, y
mide 480 píxeles de ancho por 320 de alto. Todo el código JavaScript que se vaya a escribir se
pondrá entre las etiquetas <script> y </script>.

Para poder visualizar los gráficos en el elemento canvas, pondremos una referencia en JavaScript
para poder visualizar un cuadro de color gris en la pantalla principal que será como el tablero del
juego, la primera figura básica será un cuadrado como tablero:

var canvas = document.getElementById("myCanvas");

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

Acá se está guardando una referencia en el elemento canvas en la variable canvas. Después se


crea la variable ctx para guardar el contexto de gráficos 2D, la cual es la herramienta que se
utilizara para dibujar.

ctx.beginPath();

ctx.arc(240, 160, 20, 0, Math.PI*2, false);

ctx.fillStyle = "groen";

ctx.fill();

ctx.closePath();

En el fragmento de código anterior se utilizó los métodos beginPath() y closePath(), lo que esta
dentro de esta etiqueta de apertura y de cierre es el método arc:

 Las coordenadas x e y del centro del arco.


 El radio del arco
 Los ángulos inicial y final (en qué ángulo empezar y terminar de dibujar el círculo, en
radianes)
 La dirección hacia la que se dibujará (false para seguir el sentido de las agujas del reloj,
que es el valor por defecto, o true para el sentido contrario). Este parámetro es opcional.

Para que una misma función se ejecute una y otra vez podemos utilizar una función de
sincronización de JavaScript, como setInterval() o requestAnimationFrame().

Eliminaremos todo el código JavaScript que esta en el archivo HTML, excepto las dos primeras
líneas, y agregaremos lo siguiente debajo de ellas. La función draw() se ejecutará dentro de
setInterval cada 10 milisegundos:
function draw() {

// código para dibujar

setInterval(draw, 10);

Gracias a setInterval la función draw() se llamará cada 10 milisegundos por siempre o hasta que
nosotros la detengamos. Ahora dibujaremos la bola, para esto se agrego lo siguiente dentro de la
función draw():

ctx.beginPath();

ctx.arc(50, 50, 10, 0, Math.PI*2);

ctx.fillStyle = "#0095DD";

ctx.fill();

ctx.closePath();

En este momento la bola se está dibujando cada 10 milisegundos el cual no se nota porque no hay
movimiento, se dibuja una y otra vez en el mismo sitio. Primero, en lugar de dibujar siempre en la
posición (50, 50) se definirá un punto de inicio en la parte central inferior del lienzo en las
variables llamadas x e y, a continuación, las utilizaremos para definir la posición en la que se dibuja
el círculo.

Primero, agregamos las dos líneas siguientes a la función draw (), para definir x e y:

var x = canvas.width/2;

var y = canvas.height-30;

Actualizaremos la función draw() para poder usar las variables x e y en el método arc(), como en
las siguientes líneas de código:

function draw() {

ctx.beginPath();

ctx.arc(x, y, 10, 0, Math.PI*2);

ctx.fillStyle = "#0095DD";

ctx.fill();

ctx.closePath();

Ahora el paso 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. Se definirá estos
valores pequeños como dx y dy, y establecemos sus valores en 2 y -2 respectivamente. Agregamos
lo siguiente debajo de sus definiciones de variables x e y:

var dx = 2;

var dy = -2;

Lo último que haremos para este paso es que hay que actualizar x e y con nuestras variables dx y
dy en cada fotograma, de esta forma, que la bola será pintada en la nueva posición en cada
actualización. Agregamos las dos nuevas líneas siguientes a continuación a la función draw ():

function draw() {

ctx.beginPath();

ctx.arc(x, y, 10, 0, Math.PI*2);

ctx.fillStyle = "#0095DD";

ctx.fill();

ctx.closePath();

x += dx;

y += dy;

Para que podamos detectar el choque de la bola en las paredes, verificamos si la bola está tocando
(chocando con) la pared y si es así, cambiaremos la dirección de su movimiento. Definimos una
variable llamada ballRadius que mantendrá el radio del círculo dibujado y se utilizará para los
cálculos. Añadimos esto en algún lugar por debajo de las declaraciones de variables existentes:

var ballRadius = 10;

Ahora actualizamos la línea que dibuja la bola dentro de la función drawBall() a esto:

ctx.arc(x, y, ballRadius, 0, Math.PI*2);

Hay cuatro paredes ya que el tablero del juego es un cuadrado y para rebotar la pelota miraremos
la parte de arriba. Comprobaremos que, en cada fotograma, si la pelota está tocando el borde
superior del Canvas, si es así, invertiremos el movimiento de la bola para que empiece a moverse
en la dirección opuesta y se mantenga dentro de los límites visibles. Recordando que el sistema de
coordenadas comienza desde la parte superior izquierda, llegaremos a algo como esto:

if(y + dy < 0) {

dy = -dy;

Si el valor de y de la posición de la bola es menor que cero, cambie la dirección del movimiento en
el eje y, estableciéndolo igual a sí mismo, invertido. Si la pelota se movía hacia arriba con una
velocidad de 2 píxeles por fotograma, ahora se moverá hacía arriba con una velocidad de 2 píxeles,
lo que en realidad equivale a bajar a una velocidad de 2 píxeles por fotograma.

El código anterior se ocupará de que la pelota rebote desde el borde superior, así que ahora
veremos el borde inferior:

if(y + dy > canvas.height) {

dy = -dy;

Si la posición y de la pelota es mayor que la altura del canvas (contaremos los valores y desde la
parte superior izquierda, de modo que el borde superior empezara en 0 y el borde inferior está en
480 píxeles, la altura del canvas), entonces rebota del borde inferior invirtiendo el movimiento del
eje y como antes. Podremos unir esas dos sentencias en una para ahorrar código:

if(y + dy > canvas.height || y + dy < 0) {

dy = -dy;

Para rebotar en la izquierda y la derecha, tendremos el borde superior e inferior cubiertos, todo lo
que tenemos que hacer es repetir las declaraciones de x en lugar de y:

if(x + dx > canvas.width || x + dx < 0) {

dx = -dx;

if(y + dy > canvas.height || y + dy < 0) {

dy = -dy;

Esta parte del código anteriormente mencionado se debe insertar en la función draw() antes de la
llave de cierre. Esto hará que, al momento de cargar la página, la pelota siga desapareciendo en la
pared y esto es porque se está calculando el punto de colisión de la pared y el centro de la bola, y
está mal ya que deberíamos hacerlo por su circunferencia. La bola debe rebotar justo después de
que toca la pared, no cuando ya está a medio camino en la pared, así que ajustaremos estas
declaraciones. El código quedaría de la siguiente forma:

if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {

dx = -dx;

if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {


dy = -dy;

En este siguiente paso definiremos la paleta para poder golpear la bola, empezaremos por definir
variables para poder conseguirlo, agregamos las siguientes variables en la parte de arriba nuestro
código, junto a las que ya teníamos:

var paddleHeight = 10;

var paddleWidth = 75;

var paddleX = (canvas.width-paddleWidth)/2;

la variable anteriormente definida como: paddleHeight servirá para definir la altura de la paleta,
paddleWidth la anchura y paddleX la posición en el eje X en la que empieza a dibujarse. Definimos
una función que dibujará la paleta en la pantalla, function drawBall():

function drawPaddle() {

ctx.beginPath();

ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);

ctx.fillStyle = "#0095DD";

ctx.fill();

ctx.closePath();

La paleta se puede dibujar donde queramos, pero debería responder a las acciones del
usuario. Vamos a necesitar lo siguiente:

 Dos variables para guardar la información sobre si se ha pulsado el botón izquierdo o el


derecho.

 Dos funciones (event listeners) que responden a los eventos keydowny keyup(pulsar tecla,


liberar tecla). Queremos que se ejecute algún código para manejar la paleta cuando se
pulsen los botones.

 Dos funciones que manejen los eventos keydowny keyupque se ejecutarán cuando se


pulsen los botones.

 La habilidad de mover la paleta a la izquierda ya la derecha

Se empezára por definir las variables que nos dirán si se el usuario ha pulsado un botón,
agregaremos estas líneas donde se ha definido las demás variables:

var rightPressed = false;

var leftPressed = false;


Las dos las inicializamos en false porque al principio no están pulsados los botones. Para poder
escuchar las pulsaciones de las teclas necesitaremos definir dos escuchadores de eventos,
agregaremos las líneas siguientes justo antes de setInterval()al final de nuestro código:

document.addEventListener("keydown", keyDownHandler, false);

document.addEventListener("keyup", keyUpHandler, false);

Cuando comience el evento keydownal pulsar cualquier tecla del teclado, la


función keyDownHandler()se ejecutará. Cuando se libere la tecla pulsada, se ejecutará la
función keyUpHandler(). Añadimos esto después de las líneas del addEventListener()que
acabamos de escribir:

function keyDownHandler(e) {

if(e.keyCode == 39) {

rightPressed = true;

else if(e.keyCode == 37) {

leftPressed = true;

function keyUpHandler(e) {

if(e.keyCode == 39) {

rightPressed = false;

else if(e.keyCode == 37) {

leftPressed = false;

Cuando se pulsa una tecla se ejecuta la función keyDownHandler(e), que pone en la variable "e"
los datos que necesitamos. Efectivamente, e.keyCode nos dirá qué tecla se ha pulsado. Si vale 37
es porque se ha pulsado la flecha izquierda del teclado. El código 39 representa a la flecha
derecha. Cuando se pulse la flecha izquierda pondremos leftPressed a true. Cuando se libere la
flecha izquierda pondremos leftPressed a false. De igual forma procederá el programa con la
flecha derecha, detectando el código 39 y dando los valores oportunos a la variable rightPressed.
Ahora la lógica para darle el movimiento de la paleta, tenemos que las variables que contienen la
información sobre las teclas pulsadas, los oyentes de eventos y las funciones relevantes. Ahora
vamos a mirar el código que usaremos en todo esto y moverá la paleta en la pantalla. Dentro de la
función draw() comprobaremos si está pulsada la flecha izquierda o la derecha cada vez que se
dibuje un fotograma. Nuestro código podría tener este aspecto:

if(rightPressed) {

paddleX += 7;

else if(leftPressed) {

paddleX -= 7;

Si pulsamos la flecha izquierda, la paleta se moverá 7 píxeles a la izquierda. Si pulsamos la flecha


derecha, se moverá 7 píxeles a la derecha. Aunque esto funciona bien, la paleta desaparece en los
laterales del terreno de juego si mantenemos pulsada una tecla demasiado tiempo. Se puede0
mejorar esto para que se mueva dentro de los límites del lienzo, cambiando el código así:

if(rightPressed && paddleX < canvas.width-paddleWidth) {

paddleX += 7;

else if(leftPressed && paddleX > 0) {

paddleX -= 7;

La posición paddleX que estamos utilizando variará entre 0 para el lado izquierdo y canvas.width-
paddleWidthpara el lado derecho, que es justo lo que queremos, agregamos el código anterior
dentro de la función draw(), al final, justo antes de la llave que cierra. Lo único que falta por hacer
es llamar a la función drawPaddle()desde dentro de la función draw()para que dibuje la paleta
dentro en la pantalla, justo antes de la línea que llama a la función drawBall():

drawPaddle();

A continuación, implementaremos el fin del juego, acá implementaremos el código para que la
pelota rebote en las paredes:

if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {

dx = -dx;

}
if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {

dy = -dy;

Para que la pelota solo rebote en las cuatro paredes, permitiremos que lo haga sólo en tres:
izquierda, arriba y derecha. Alcanzar la pared inferior supondrá el fin del juego. Editaremos el
segundo bloque if y lo convertiremos en un if else el cual activará el estado de final de juego,
cuando la pelota colisione con el borde inferior del terreno de juego. Por ahora nos
conformaremos con mostrar un mensaje con la función alert() y con reiniciar el juego cargaremos
la página. Modificamos el segundo if para que quede de la siguiente manera:

if(y + dy < ballRadius) {

dy = -dy;

} else if(y + dy > canvas.height-ballRadius) {

alert("GAME OVER");

document.location.reload();

Para hacer que la pelota golpee la palanca nos falta detectar la colisión de la bola y la paleta para
que pueda rebotar, volviendo hacia la zona de juego. La forma más sencilla de hacerlo es
comprobar si el centro de la bola está entre los límites izquierdo y derecho de la paleta.
Actualizamos el anterior fragmento de código, el if else de antes, para que nos quede así:

if(y + dy < ballRadius) {

dy = -dy;

} else if(y + dy > canvas.height-ballRadius) {

if(x > paddleX && x < paddleX + paddleWidth) {

dy = -dy;

else {

alert("GAME OVER");

document.location.reload();

}
REFERENCIAS BIBLIOGRAFICAS

https://threejs.org/docs/index.html#manual/en/introduction/How-to-create-VR-content

https://developer.mozilla.org/es/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/
Finishing_up

También podría gustarte