26
Juego de nave espacial HTML5 - Canvas Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 1 1.- Dibujar el fondo y la nave Usa de Canvas HTML5 y JavaScript para crear un campo aleatorio de estrellas blancas y dibujar una nave espacial verde y naranja parecida a un platillo volador. Las imágenes del juego se crean con píxeles. El elemento Canvas permite colocar píxeles directamente en la pantalla mediante el modo inmediato. Esta función hace que sea muy fácil dibujar puntos, líneas y formas exactamente donde quieras y en el color que elijas. Esta muestra de código cubre las siguientes tareas que demuestran los principios básicos sobre el uso de Canvas para dibujar estos elementos de un juego: Agregar un elemento Canvas a una página web Crear un fondo negro Dibujar estrellas aleatorias en el fondo Agregar una nave espacial al fondo <!DOCTYPE html> <html> <head> <script type="text/javascript"> // This function is called on page load. function canvasSpaceGame() { // Get the canvas element. canvas = document.getElementById("myCanvas"); // Make sure you got it. if (canvas.getContext) // If you have it, create a canvas user inteface element. { // Specify 2d canvas type. ctx = canvas.getContext("2d"); // Paint it black. ctx.fillStyle = "black"; ctx.rect(0, 0, 300, 300); ctx.fill(); // Paint the starfield. stars(); // Draw space ship. makeShip(); } } // Paint a random starfield. function stars() { // Draw 50 stars. for (i = 0; i <= 50; i++) { // Get random positions for stars. var x = Math.floor(Math.random() * 299) var y = Math.floor(Math.random() * 299)

1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 1

1.- Dibujar el fondo y la nave

Usa de Canvas HTML5 y JavaScript para crear un campo aleatorio de estrellas blancas y dibujar una nave espacial

verde y naranja parecida a un platillo volador. Las imágenes del juego se crean con píxeles. El elemento Canvas

permite colocar píxeles directamente en la pantalla mediante el modo inmediato. Esta función hace que sea muy

fácil dibujar puntos, líneas y formas exactamente donde quieras y en el color que elijas.

Esta muestra de código cubre las siguientes tareas que demuestran los principios básicos sobre el uso de Canvas

para dibujar estos elementos de un juego:

Agregar un elemento Canvas a una página web

Crear un fondo negro

Dibujar estrellas aleatorias en el fondo

Agregar una nave espacial al fondo

<!DOCTYPE html>

<html>

<head>

<script type="text/javascript">

// This function is called on page load.

function canvasSpaceGame() {

// Get the canvas element.

canvas = document.getElementById("myCanvas");

// Make sure you got it.

if (canvas.getContext)

// If you have it, create a canvas user inteface element.

{

// Specify 2d canvas type.

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

// Paint it black.

ctx.fillStyle = "black";

ctx.rect(0, 0, 300, 300);

ctx.fill();

// Paint the starfield.

stars();

// Draw space ship.

makeShip();

}

}

// Paint a random starfield.

function stars() {

// Draw 50 stars.

for (i = 0; i <= 50; i++) {

// Get random positions for stars.

var x = Math.floor(Math.random() * 299)

var y = Math.floor(Math.random() * 299)

Page 2: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 2

// Make the stars white

ctx.fillStyle = "white";

// Give the ship some room.

if (x < 30 || y < 30) ctx.fillStyle = "black";

// Draw an individual star.

ctx.beginPath();

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

ctx.closePath();

ctx.fill();

}

}

function makeShip() {

// Draw saucer bottom.

ctx.beginPath();

ctx.moveTo(28.4, 16.9);

ctx.bezierCurveTo(28.4, 19.7, 22.9, 22.0, 16.0, 22.0);

ctx.bezierCurveTo(9.1, 22.0, 3.6, 19.7, 3.6, 16.9);

ctx.bezierCurveTo(3.6, 14.1, 9.1, 11.8, 16.0, 11.8);

ctx.bezierCurveTo(22.9, 11.8, 28.4, 14.1, 28.4, 16.9);

ctx.closePath();

ctx.fillStyle = "rgb(222, 103, 0)";

ctx.fill();

// Draw saucer top.

ctx.beginPath();

ctx.moveTo(22.3, 12.0);

ctx.bezierCurveTo(22.3, 13.3, 19.4, 14.3, 15.9, 14.3);

ctx.bezierCurveTo(12.4, 14.3, 9.6, 13.3, 9.6, 12.0);

ctx.bezierCurveTo(9.6, 10.8, 12.4, 9.7, 15.9, 9.7);

ctx.bezierCurveTo(19.4, 9.7, 22.3, 10.8, 22.3, 12.0);

ctx.closePath();

ctx.fillStyle = "rgb(51, 190, 0)";

ctx.fill();

}

</script>

</head>

<body onload="canvasSpaceGame()">

<h1>

Canvas Space Game

</h1>

<canvas id="myCanvas" width="300" height="300">

</canvas>

</body>

</html>

Código del cuerpo

La etiqueta del cuerpo usa la función de carga para llamar a la función canvasSpaceGame al cargar la página. La

etiqueta de Canvas es parte del cuerpo. Se especifican el ancho y alto iniciales de Canvas, así como el atributo de

Page 3: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 3

identificador. Hay que especificar el identificador para poder agregar el elemento de Canvas al modelo de objetos de

la página.

Código de script

Función canvasSpaceGame

Esta función se llama al cargar la página. Obtiene el elemento Canvas mediante el Id. de este elemento en el código

del cuerpo. Después se genera el contexto del elemento Canvas y se prepara para aceptar el dibujo. Después de

inicializar el contexto como Canvas 2D, el elemento Canvas se pinta de negro con la propiedad fillStyle y los

métodos rect y fill.

Función stars

Esta función se invoca desde canvasSpaceGame. Usa for loop para generar 50 posiciones posibles de estrellas en

una superficie x,y, y usa fillStyle para crear un color blanco. A continuación, se realiza una comprobación para ver

si las coordenadas "x" e "y" están demasiado cerca de la esquina superior izquierda. Si una estrella está demasiado

cerca de la esquina superior izquierda, se cambia fillStyle a negro para que no interfiera con la nave espacial.

Después se dibuja cada estrella con el método arc y se usa el color de relleno apropiado.

Función makeShip

Esta función se invoca desde canvasSpaceGame. Al usar una serie de

métodos beginPath, moveTo, bezierCurveTo, closePath, fillStyle y fill, se dibuja una nave espacial simple.

Page 4: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 4

2.- Mover la nave Se indica cómo mover la nave espacial en el campo de estrellas. El elemento Canvas usa el modo inmediato para

crear imágenes en movimiento. Se necesitan dos pasos para implementar esta función en el programa de juegos.

En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se

destruyó cuando se dibujó la nave espacial sobre él.

Esta muestra de código cubre las siguientes tareas que demuestran los principios básicos sobre el uso de Canvas

para mover un objeto por un fondo detallado:

Establecer un bucle de juego para procesar los eventos principales del juego

Capturar pulsaciones de teclas para determinar si la nave debe moverse a continuación

Guardar el fondo adonde se moverá la nave

Mover la nave a su nueva posición

Restablecer el fondo anterior que la nave estaba cubriendo

<!DOCTYPE html>

<html>

<head>

<script type="text/javascript">

// Global variables

var shipX = 0; // X position of ship

var shipY = 0; // Y position of ship

var canvas; // canvas

var ctx; // context

var back = new Image(); // storage for new background piece

var oldBack = new Image(); // storage for old background piece

var ship = new Image(); // ship

var shipX = 0; // current ship position X

var shipY = 0; // current ship position Y

var oldShipX = 0; // old ship position Y

var oldShipY = 0; // old ship position Y

// This function is called on page load.

function canvasSpaceGame() {

// Get the canvas element.

canvas = document.getElementById("myCanvas");

// Make sure you got it.

if (canvas.getContext)

// If you have it, create a canvas user inteface element.

{

// Specify 2d canvas type.

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

// Paint it black.

ctx.fillStyle = "black";

ctx.rect(0, 0, 300, 300);

ctx.fill();

// Save the initial background.

back = ctx.getImageData(0, 0, 30, 30);

// Paint the starfield.

stars();

Page 5: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 5

// Draw space ship.

makeShip();

}

// Play the game until the until the game is over.

gameLoop = setInterval(doGameLoop, 16);

// Add keyboard listener.

window.addEventListener('keydown', whatKey, true);

}

// Paint a random starfield.

function stars() {

// Draw 50 stars.

for (i = 0; i <= 50; i++) {

// Get random positions for stars.

var x = Math.floor(Math.random() * 299);

var y = Math.floor(Math.random() * 299);

// Make the stars white

ctx.fillStyle = "white";

// Give the ship some room by painting black stars.

if (x < 30 || y < 30) ctx.fillStyle = "black";

// Draw an individual star.

ctx.beginPath();

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

ctx.closePath();

ctx.fill();

// Save black background.

oldBack = ctx.getImageData(0, 0, 30, 30);

}

}

function makeShip() {

// Draw saucer bottom.

ctx.beginPath();

ctx.moveTo(28.4, 16.9);

ctx.bezierCurveTo(28.4, 19.7, 22.9, 22.0, 16.0, 22.0);

ctx.bezierCurveTo(9.1, 22.0, 3.6, 19.7, 3.6, 16.9);

ctx.bezierCurveTo(3.6, 14.1, 9.1, 11.8, 16.0, 11.8);

ctx.bezierCurveTo(22.9, 11.8, 28.4, 14.1, 28.4, 16.9);

ctx.closePath();

ctx.fillStyle = "rgb(222, 103, 0)";

ctx.fill();

// Draw saucer top.

ctx.beginPath();

ctx.moveTo(22.3, 12.0);

ctx.bezierCurveTo(22.3, 13.3, 19.4, 14.3, 15.9, 14.3);

Page 6: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 6

ctx.bezierCurveTo(12.4, 14.3, 9.6, 13.3, 9.6, 12.0);

ctx.bezierCurveTo(9.6, 10.8, 12.4, 9.7, 15.9, 9.7);

ctx.bezierCurveTo(19.4, 9.7, 22.3, 10.8, 22.3, 12.0);

ctx.closePath();

ctx.fillStyle = "rgb(51, 190, 0)";

ctx.fill();

// Save ship data.

ship = ctx.getImageData(0, 0, 30, 30);

// Erase it for now.

ctx.putImageData(oldBack, 0, 0);

}

function doGameLoop() {

// Put old background down to erase shipe.

ctx.putImageData(oldBack, oldShipX, oldShipY);

// Put ship in new position.

ctx.putImageData(ship, shipX, shipY);

}

// Get key press.

function whatKey(evt) {

// Flag to put variables back if we hit an edge of the board.

var flag = 0;

// Get where the ship was before key process.

oldShipX = shipX;

oldShipY = shipY;

oldBack = back;

switch (evt.keyCode) {

// Left arrow.

case 37:

shipX = shipX - 30;

if (shipX < 0) {

// If at edge, reset ship position and set flag.

shipX = 0;

flag = 1;

}

break;

// Right arrow.

case 39:

shipX = shipX + 30;

if (shipX > 270) {

// If at edge, reset ship position and set flag.

shipX = 270;

flag = 1;

}

break;

Page 7: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 7

// Down arrow

case 40:

shipY = shipY + 30;

if (shipY > 270) {

// If at edge, reset ship position and set flag.

shipY = 270;

flag = 1;

}

break;

// Up arrow

case 38:

shipY = shipY - 30;

if (shipY < 0) {

// If at edge, reset ship position and set flag.

shipY = 0;

flag = 1;

}

break;

}

// If flag is set, the ship did not move.

// Put everything back the way it was.

if (flag) {

shipX = oldShipX;

shipY = oldShipY;

back = oldBack;

} else {

// Otherwise, get background where the ship will go

// So you can redraw background when the ship

// moves again.

back = ctx.getImageData(shipX, shipY, 30, 30);

}

}

</script>

</head>

<body onload="canvasSpaceGame()">

<h1>

Canvas Space Game

</h1>

<canvas id="myCanvas" width="300" height="300">

</canvas>

</body>

</html>

Código del cuerpo

El código del cuerpo es el mismo que el código del contenido de la primera tarea de este escenario: "Dibujar el

fondo y tu vehículo".

Page 8: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 8

Código de script

Se invocan variables globales cuando se carga la página. Se invoca la función canvasSpaceGame desde el

atributo onload de la etiqueta del contenido. Se llama al resto de las funciones desde la

función canvasSpaceGame.

Variables globales

Este programa usa una variable global para los datos a los que se obtendrá acceso desde diferentes funciones. Las

variables las incluyen en la siguiente lista:

canvas y context: es posible que desees que estas variables sean globales para la mayoría de los

programas de Canvas, ya que obtendrás acceso a ellas desde muchas funciones.

back, oldBack: imágenes que almacenan las instantáneas de 30 x 30 píxeles del fondo anterior y nuevo.

ship: imagen que almacena los píxeles para la nave espacial.

shipX, shipY: las coordenadas x e y para la nave espacial.

oldShipX, oldShipY: las coordenadas x e y de la última posición de la nave espacial.

Función canvasSpaceGame

Esta función se basa en la misma función de la primera tarea de este escenario: "Dibujar el fondo y tu vehículo". Se

realizaron las siguientes modificaciones:

Se creó una instantánea de 30 x 30 píxeles usando el método getImageData y guardándolo en la

variable back. Esta variable se usa más tarde cuando se mueve la nave.

Una llamada a setInterval, que ejecuta la función doGameLoop cada 16 milisegundos. Este intervalo se

cancelará al final del juego usando gameLoop.

Se establece un controlador de eventos usando addEventListener. Esto llama a la función whatKey cada

vez que se produce el evento keydown.

Función stars

Esta función es la misma que la función stars de la primera tarea: "Dibujar el fondo y tu vehículo". La única

diferencia es que se guarda una instantánea de 30 x 30 píxeles del fondo en la imagen de la variable oldBack con

el fin de usarla más adelante.

Función makeShip

Esta función es la misma que la función makeShip de la primera tarea de este escenario: "Dibujar el fondo y tu

vehículo". La única diferencia es que se guarda una instantánea de 30 x 30 píxeles de la nave en la imagen

del ship con el fin de usarla más adelante.

Función doGameLoop

El temporizador gameLoop invoca esta función cada 16 milisegundos. Los bucles de juegos son muy comunes en

los juegos porque realizan tareas básicas de animación a intervalos regulares.

El bucle de juego invoca dos tareas de animación:

Erasing the ship : si la nave se mueve y deja la marca de la nave en el fondo, debes restaurar la imagen

anterior del fondo. Esto usa el método putImageData. Si no realizas esta acción, cada vez que muevas la

nave, quedará la imagen anterior de la nave. Debes saber qué había debajo de la nave antes de que se

moviera y copiar la imagen para borrar la imagen de la nave anterior y reemplazarla por la imagen del fondo

que estaba allí anteriormente.

Moving the ship: debes copiar la imagen de la nave en su nueva posición. Dado que esto destruirá

cualquier imagen que había allí anteriormente, debes guardar el fondo antes de destruirlo.

Page 9: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 9

Función whatKey

Se invoca esta función cada vez que se presiona una tecla. Determina a dónde desea el jugador que se mueva la

nave. Es importante tener en cuenta que la nave no se mueve realmente en esta función. El movimiento se calcula,

pero la acción de dibujar la nueva nave se realiza en la función doGameLoop.

La función whatKey contiene las siguientes acciones:

Se usará una marca para determinar qué sucede si la nave llega al borde de la pantalla.

Antes de que se mueva, debes guardar las posiciones de x e y de la nave, y guardar el fondo que se

encuentra debajo de la nave. Esto es necesario porque el modo inmediato no guarda automáticamente

ningún píxel en la pantalla.

A continuación, una instrucción switch procesa el evento y busca el código de tecla del evento. Los códigos

de tecla corresponden a las teclas izquierda, derecha, arriba y abajo del teclado.

Para cada caso relevante de código de tecla, se calculan las nuevas posiciones de x e y. Si la nueva

posición de la nave la movería fuera del lienzo, se cancela y se marca como establecida.

Si la marca está establecida, las variables de la nave y el fondo vuelven a su estado original.

En caso contrario, se usa el método getImageData para guardar la instantánea de fondo actual.

Animación de Canvas

Canvas tiene dos maneras para crear animaciones. La primera es la forma de animación más común, en la que la

pantalla se vuelve a dibujar completamente para obtener cada movimiento. Esto funciona mejor si tienes una

pequeña superficie de dibujo de lienzo y un equipo rápido. Sin embargo, no se recomienda para animaciones más

grandes o más complejas. La segunda manera en que Canvas crea animaciones se indica en la muestra de código

incluida en este tema. Este método se recomienda para los casos en que hay animaciones de Canvas más grandes

y más complejas. Este estilo de animación es más avanzado. Si bien requiere un código más grande para

establecerlo, se ejecuta mucho más rápido que el estilo de animación más común. Se ejecuta más rápido porque

solo se cambian unos pocos píxeles individuales en cada movimiento, no toda la pantalla de píxeles. El estilo de

animación más rápido que se muestra aquí usa los siguientes pasos. Estos pasos se repiten de forma cíclica para

cada movimiento.

Borra la nave al dibujar arriba de ella una instantánea de 30 x 30 píxeles con la imagen del fondo anterior.

Obtén una nueva instantánea del fondo que se cubrirá cuando se mueva la nave.

Dibuja la nave en su nueva posición.

Dado que este bucle circular sucede cada 16 milisegundos, el ojo humano no ve que la nave se borra; solo ve que

la nave se mueve. Esto disminuye el riesgo de que la pantalla parpadee entre cada movimiento, dado que solo se

dibuja una pequeña parte de la pantalla en cada ocasión.

Puedes cargar el juego y con las flechas del teclado puedes mover la nave.

Page 10: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 10

3.- Detectar colisiones

Se explica detectar si la nave espacial colisiona contra un asteroide rojo o contra la base central azul. Esta muestra

indica cómo usar Canvas para hacer un seguimiento de cada píxel en la pantalla. Debido a que usa el modo

inmediato, Canvas cuenta con la capacidad para definir la posición y el valor de color de cada píxel. Debido a que

Canvas te permite leer y escribir cada píxel, puedes crear animaciones detalladas que se ejecutan de forma rápida y

eficiente. Esta muestra de código te indica cómo asignar valores específicos de color a los píxeles para crear

asteroides rojos y una base central azul. Podrás detectar colisiones al tomar instantáneas de la pantalla para

examinar objetos en color que la nave espacial debe sortear.

Esta muestra de código cubre las siguientes tareas que demuestran los principios básicos sobre el uso de Canvas

para detectar el color de diferentes objetos.

Dibujar asteroides y una base central con colores específicos para su detección posterior.

Tomar instantáneas de lo que la nave espacial tiene enfrente.

Examinar instantáneas para detectar objetos en color y mostrar mensajes.

<!DOCTYPE html>

<html>

<head>

<script type="text/javascript">

// Global variables

var shipX = 0; // X position of ship

var shipY = 0; // Y position of ship

var canvas; // canvas

var ctx; // context

var back = new Image(); // storage for new background piece

var oldBack = new Image(); // storage for old background piece

var ship = new Image(); // ship

var shipX = 0; // current ship position X

var shipY = 0; // current ship position Y

var oldShipX = 0; // old ship position Y

var oldShipY = 0; // old ship position Y

// This function is called on page load.

function canvasSpaceGame() {

// Get the canvas element.

canvas = document.getElementById("myCanvas");

// Make sure you got it.

if (canvas.getContext)

// If you have it, create a canvas user inteface element.

{

// Specify 2d canvas type.

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

// Paint it black.

ctx.fillStyle = "black";

ctx.rect(0, 0, 300, 300);

ctx.fill();

// Save the initial background.

back = ctx.getImageData(0, 0, 30, 30);

Page 11: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 11

// Paint the starfield.

stars();

// Draw space ship.

makeShip();

// Draw asteroids.

drawAsteroids();

}

// Play the game until the until the game is over.

gameLoop = setInterval(doGameLoop, 16);

// Add keyboard listener.

window.addEventListener('keydown', whatKey, true);

}

// Paint a random starfield.

function stars() {

// Draw 50 stars.

for (i = 0; i <= 50; i++) {

// Get random positions for stars.

var x = Math.floor(Math.random() * 299);

var y = Math.floor(Math.random() * 299);

// Make the stars white

ctx.fillStyle = "#EEEEEE";

// Paint the star but not if too close to ship.

if (x > 40 && y > 40) {

// Draw an individual star.

ctx.beginPath();

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

ctx.closePath();

ctx.fill();

} else--i;

}

// Save black background.

oldBack = ctx.getImageData(0, 0, 30, 30);

}

function makeShip() {

// Draw saucer bottom.

ctx.beginPath();

ctx.moveTo(28.4, 16.9);

ctx.bezierCurveTo(28.4, 19.7, 22.9, 22.0, 16.0, 22.0);

ctx.bezierCurveTo(9.1, 22.0, 3.6, 19.7, 3.6, 16.9);

ctx.bezierCurveTo(3.6, 14.1, 9.1, 11.8, 16.0, 11.8);

ctx.bezierCurveTo(22.9, 11.8, 28.4, 14.1, 28.4, 16.9);

ctx.closePath();

ctx.fillStyle = "rgb(222, 103, 0)";

Page 12: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 12

ctx.fill();

// Draw saucer top.

ctx.beginPath();

ctx.moveTo(22.3, 12.0);

ctx.bezierCurveTo(22.3, 13.3, 19.4, 14.3, 15.9, 14.3);

ctx.bezierCurveTo(12.4, 14.3, 9.6, 13.3, 9.6, 12.0);

ctx.bezierCurveTo(9.6, 10.8, 12.4, 9.7, 15.9, 9.7);

ctx.bezierCurveTo(19.4, 9.7, 22.3, 10.8, 22.3, 12.0);

ctx.closePath();

ctx.fillStyle = "rgb(51, 190, 0)";

ctx.fill();

// Save ship data.

ship = ctx.getImageData(0, 0, 30, 30);

// Erase it for now.

ctx.putImageData(oldBack, 0, 0);

}

function doGameLoop() {

// Put old background down to erase shipe.

ctx.putImageData(oldBack, oldShipX, oldShipY);

// Put ship in new position.

ctx.putImageData(ship, shipX, shipY);

}

// Get key press.

function whatKey(evt) {

// Flag to put variables back if we hit an edge of the board.

var flag = 0;

// Get where the ship was before key process.

oldShipX = shipX;

oldShipY = shipY;

oldBack = back;

switch (evt.keyCode) {

// Left arrow.

case 37:

shipX = shipX - 30;

if (shipX < 0) {

// If at edge, reset ship position and set flag.

shipX = 0;

flag = 1;

}

break;

// Right arrow.

case 39:

shipX = shipX + 30;

if (shipX > 270) {

Page 13: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 13

// If at edge, reset ship position and set flag.

shipX = 270;

flag = 1;

}

break;

// Down arrow

case 40:

shipY = shipY + 30;

if (shipY > 270) {

// If at edge, reset ship position and set flag.

shipY = 270;

flag = 1;

}

break;

// Up arrow

case 38:

shipY = shipY - 30;

if (shipY < 0) {

// If at edge, reset ship position and set flag.

shipY = 0;

flag = 1;

}

break;

default:

flag = 1;

alert("Please only use the arrow keys.");

}

// If flag is set, the ship did not move.

// Put everything back the way it was.

if (flag) {

shipX = oldShipX;

shipY = oldShipY;

back = oldBack;

} else {

// Otherwise, get background where the ship will go

// So you can redraw background when the ship

// moves again.

back = ctx.getImageData(shipX, shipY, 30, 30);

}

collideTest();

}

function collideTest() {

// Collision detection. Get a clip from the screen.

var clipWidth = 20;

var clipDepth = 20;

var clipLength = clipWidth * clipDepth;

// alert(clipLength);

var clipOffset = 5;

Page 14: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 14

var whatColor = ctx.getImageData(shipX + clipOffset, shipY + clipOffset, clipWidth,

clipDepth);

// Loop through the clip and see if you find red or blue.

for (var i = 0; i < clipLength * 4; i += 4) {

if (whatColor.data[i] == 255) {

alert("red");

break;

}

// Second element is green but we don't care.

if (whatColor.data[i + 2] == 255) {

alert("blue");

break;

}

// Fourth element is alpha and we don't care.

}

}

function drawAsteroids() {

// Draw asteroids.

for (i = 0; i <= 20; i++) {

// Get random positions for asteroids.

var a = Math.floor(Math.random() * 299);

var b = Math.floor(Math.random() * 299);

// Make the asteroids red

ctx.fillStyle = "#FF0000";

// Keep the asteroids far enough away from

// the beginning or end.

if (a > 40 && b > 40 && a < 270 && b < 270) {

// Draw an individual asteroid.

ctx.beginPath();

ctx.arc(a, b, 10, 0, Math.PI * 2, true);

ctx.closePath();

ctx.fill();

} else--i;

}

// Draw blue base.

ctx.fillStyle = "#0000FF";

ctx.beginPath();

ctx.rect(270, 270, 30, 30);

ctx.closePath();

ctx.fill();

}

</script>

</head>

<body onload="canvasSpaceGame()">

<h1>

Canvas Space Game

</h1>

Page 15: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 15

<canvas id="myCanvas" width="300" height="300">

</canvas>

</body>

</html>

Código del cuerpo

El código del cuerpo es igual al del tema “mover la nave”.

Código de script

Se invocan variables globales cuando se carga la página. Se llama a la función canvasSpaceGame desde el

atributo onload de la etiqueta del contenido. Se llama al resto de las funciones desde la

función canvasSpaceGame.

Función canvasSpaceGame

Esta función es muy similar a la que aparece en la segunda tarea de este escenario: "Cómo mover el vehículo". La

única modificación consiste en agregar una llamada a la función drawAsteroids, que dibuja los asteroides y la base

central en la pantalla.

Función stars

Esta función es muy similar a la función stars en la segunda tarea de este escenario: "Cómo mover el vehículo".

La única diferencia es que el color de la estrella (star) recibe un valor de color diferente. En la función stars de la

segunda tarea de este escenario: "Mover la nave", el color de la estrella era "blanco". (El valor de cuatro bytes es

100% rojo, azul, verde y alfa, o “#FFFFFF”.) Pero en esta tarea, las estrellas reciben el valor de color de

“#EEEEEE”, que es casi blanco (los valores de cuatro bytes son 94% rojo, verde, azul y alfa). El valor parece blanco

porque muestra solamente un indicio de color. Es necesario mostrar un indicio de color cuando se examina la

pantalla para detectar colisiones, ya que el uso del blanco puro causa problemas. Cuando examinas la pantalla en

búsqueda de colisiones y buscas un objeto que sea 100% rojo, es posible que obtengas un falso positivo para una

estrella blanca, porque una estrella "blanca" es 100% roja en su interior.

Si trabajas con porcentajes precisos de rojo, verde, azul y alfa, podrás realizar detecciones de colisiones muy

precisas y sutiles. Esto es de suma importancia, ya que casi todos los juegos Arcade requieren la detección de

colisiones en el juego. Otro beneficio que se obtiene al usar los colores precisos es que se puede mantener el

tamaño pequeño de la instantánea y llevar a cabo exámenes rápidos de los valores de color, lo que hace que la

detección de colisiones sea aún más rápida.

Función makeShip

Esta función es similar a la función makeShip en la segunda tarea de este escenario: "Cómo mover el vehículo". La

única diferencia es que se guarda una instantánea de 30 x 30 píxeles del barco en la imagen del barco con el fin de

usarla más adelante.

Función whatKey

Esta función tiene un código muy similar al de la función whatKey en la segunda tarea de este escenario: "Cómo

mover el vehículo". La única diferencia es que se agrega una llamada a la función collideTest después de que se

procesan los eventos clave. Esto sucede porque cada vez que se presiona una tecla, se puede originar una colisión.

Por lo tanto, debes ver lo que sucedió. Hasta que el barco se mueva, no es necesario que desperdicies ciclos para

detectar colisiones, ya que, en este juego, no se mueve nada más.

Función collideTest

Esta nueva función determina si la nave ha colapsado contra un asteroide o contra la base central. Esta acción se

lleva a cabo en dos pasos. El primer paso consiste en tomar una instantánea de la pantalla en el punto donde el

barco se está por mover. La función whatKey ya ha calculado esta ubicación. Los datos de la instantánea

constituyen una matriz simple y lineal de valores de color de cuatro bytes, que comienza en la esquina izquierda

superior y continúa de izquierda a derecha en filas y después continúa por cada fila hasta la esquina derecha

Page 16: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 16

inferior. El tamaño de la matriz es 4 veces (por el valor de color de 4 bytes) el tamaño de la longitud y el ancho. Para

una instantánea de 20 x 20, el tamaño sería 4 x 20 x 20 o 1600.

El segundo paso consiste en examinar los datos de la instantánea, cuatro bytes a la vez. Intenta ver si un valor

100% rojo (255) está en el primer byte. Si es así, hay un asteroide. Asimismo, intenta ver si un valor 100% azul

(255) está en el tercer byte. Si es así, has aterrizado en la base central. El segundo y el tercer byte no son

importantes en este ejemplo, ya que no buscas un valor verde o alfa. Si un valor 100% rojo está en el primer byte,

se muestra un cuadro de alerta que te informa que has encontrado "rojo". De manera similar, si un valor 100% azul

está en el tercer byte, un cuadro de alerta te informa que has encontrado "azul". En la próxima tarea de este

escenario, aprenderás cómo encontrar el valor rojo o azul finaliza el juego, pero en esta tarea del escenario, puedes

continuar después de cerrar el cuadro de alerta.

Esta simple tarea de tomar una instantánea y examinar los datos para bytes específicos de color puede resultar

efectiva para detectar colisiones. Es posible que las instantáneas grandes no sean eficientes. No obstante, un

diseño cuidadoso de su arte te permitirá detectar los objetos en pantalla de forma rápida y efectiva. Es muy rápido el

examen de una matriz de 1600 bytes cada vez que presionas la tecla.

Colores de los píxeles del lienzo

Para leer o escribir píxeles de color en la pantalla, debes asignar un valor de color a cada píxel. Este valor está

compuesto por cuatro partes: rojo, verde, azul y alfa. Por ejemplo, un píxel blanco está formado por 100% rojo,

100% verde, 100% azul y 100% alfa. (Alfa se refiere a la cantidad de transparencia que muestra un color). Cada

valor de color de píxel del lienzo se almacena como una matriz de cuatro bytes. Los cuatro bytes corresponden al

porcentaje de rojo, verde, azul y alfa en cada píxel. (Los bytes van de 0 a 255 para los números decimales y de #0 a

#FF para los números hexadecimales). Para obtener más información acerca de los nombres y valores numéricos

de colores específicos, consulta http://msdn.microsoft.com/en-us/library/ms531197(VS.85).aspx.

Los diseñadores web normalmente usan los nombres de los colores ("rojo") o los valores hexadecimales

(“#FF0000”) para definir los colores. Canvas usa esos sistemas de notación, pero también usa la función rgb para

indicar los primeros tres bytes de color, o la función rgbasi necesitas definir el valor alfa. Si el valor alfa no se define,

se asume que es 100%. Por ejemplo, rojo sería rgb (255,0,0). Ten en cuenta que la función rgb se usó para definir

colores cuando dibujaste el barco original, que aparece anteriormente en este tema, con la funciónmakeShip.

El código en esta muestra detalla cómo Canvas usa el modo inmediato para leer los colores de píxeles para

detectar colisiones entre los objetos. Canvas hace esto al leer un bloque de píxeles en la pantalla y determinar qué

partes del bloque contienen un valor de color particular. Por ejemplo, si deseas que tu programa de juegos

reconozca si el asteroide rojo está cerca de tu barco, puedes tomar una instantánea de la pantalla y examinarla para

determinar si contiene rojo. Si es así, tu programa reconoce que hay un asteroide. Como consecuencia, el programa

ya está preparado para reaccionar ante la acción del jugador. Si el jugador bombardea al asteroide, este estalla. Si

el jugador se estrella contra un asteroide, la nave espacial del jugador estalla.

Función drawAsteroids

Esta función es nueva. Es muy similar a la función stars en la segunda tarea de este escenario: "Mover la nave".

La función drawAsteroids emplea la misma lógica que la función stars, pero hace que el tamaño de cada asteroide

sea más grande en el método arc de Canvas y hace fillStyle “#FF0000”, que es rojo puro. Definir el color asegura

que la rutina de detección de colisiones, cuando buscas 255 en el primer byte del valor de color en la

función collideTest, encuentre siempre "rojo". El bucle del dibujo se asegura de que el asteroide no esté demasiado

cerca de la ubicación inicial del barco o de la base central. Si los asteroides se dibujan demasiado cerca o el bucle

no dibuja un asteroide, el recuento aumenta y el bucle circula una vez más.

La función drawAsteroids también dibuja la base azul. Usa el valor de color de “#0000FF”, que es "azul" puro. La

base es un simple rectángulo.

Page 17: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 17

4.- Quitar obstáculos y realizar el seguimiento de las puntuaciones

Se explica cómo crear estas rápidas acciones animadas al cambiar los píxeles individuales directamente en la

pantalla. Esta técnica se puede usar de forma eficaz para mover o modificar objetos durante el juego. Esta muestra

de código indica cómo modificar píxeles para lanzar bombas verdes desde la nave espacial para destruir los

asteroides rojos. Cuando las bombas golpean a los asteroides, los asteroides se rompen y la nave espacial puede

volar de forma segura para llegar a la base central.

Esta muestra de código cubre las siguientes tareas que demuestran los principios básicos sobre el uso de Canvas

para quitar obstáculos y llevar la puntuación:

Capturar pulsaciones de tecla para lanzar bombas

Modificar píxeles para mover objetos y simular explosiones

Crear una segunda pantalla de lienzo para mostrar la puntuación

Realizar un seguimiento de las acciones para calcular las puntuaciones

<!DOCTYPE html>

<html>

<head>

<script type="text/javascript">

// Global variables

var shipX = 0; // X position of ship

var shipY = 0; // Y position of ship

var canvas; // canvas

var ctx; // context

var back = new Image(); // storage for new background piece

var oldBack = new Image(); // storage for old background piece

var ship = new Image(); // ship

var bomb = new Image(); // neutralizer ray field

var shipX = 0; // current ship position X

var shipY = 0; // current ship position Y

var oldShipX = 0; // old ship position Y

var oldShipY = 0; // old ship position Y

var direction = "R"; // direction of ship movement

var score = 0; // score

// This function is called on page load.

function canvasSpaceGame() {

// Get the main canvas element.

canvas = document.getElementById("myCanvas");

// Get the score canvas element.

canvas2 = document.getElementById("myScore");

// Initialize the score element.

if (canvas2.getContext)

// If you have it, create score element.

{

// Specify score 2d canvas type.

ctx2 = canvas2.getContext("2d");

}

// Initialize main element.

if (canvas.getContext)

Page 18: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 18

// If you have it, create a canvas user inteface element.

{

// Specify main 2d canvas type.

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

// Paint it black.

ctx.fillStyle = "black";

ctx.rect(0, 0, 300, 300);

ctx.fill();

// Save the initial background.

back = ctx.getImageData(0, 0, 30, 30);

// Paint the starfield.

stars();

// Draw space ship.

makeShip();

// Draw asteroids.

drawAsteroids();

}

// Play the game until the until the game is over.

gameLoop = setInterval(doGameLoop, 16);

// Add keyboard listener.

window.addEventListener('keydown', whatKey, true);

}

// Paint a random star field.

function stars() {

// Draw 50 stars.

for (i = 0; i <= 50; i++) {

// Get random positions for stars.

var x = Math.floor(Math.random() * 299);

var y = Math.floor(Math.random() * 299);

// Make the stars white

ctx.fillStyle = "#EEEEEE";

// Paint the star but not if too close to ship.

if (x > 40 && y > 40) {

// Draw an individual star.

ctx.beginPath();

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

ctx.closePath();

ctx.fill();

} else--i;

}

// Save black background.

oldBack = ctx.getImageData(0, 0, 30, 30);

}

Page 19: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 19

function makeShip() {

// Draw saucer bottom.

ctx.beginPath();

ctx.moveTo(28.4, 16.9);

ctx.bezierCurveTo(28.4, 19.7, 22.9, 22.0, 16.0, 22.0);

ctx.bezierCurveTo(9.1, 22.0, 3.6, 19.7, 3.6, 16.9);

ctx.bezierCurveTo(3.6, 14.1, 9.1, 11.8, 16.0, 11.8);

ctx.bezierCurveTo(22.9, 11.8, 28.4, 14.1, 28.4, 16.9);

ctx.closePath();

ctx.fillStyle = "rgb(222, 103, 0)";

ctx.fill();

// Draw saucer top.

ctx.beginPath();

ctx.moveTo(22.3, 12.0);

ctx.bezierCurveTo(22.3, 13.3, 19.4, 14.3, 15.9, 14.3);

ctx.bezierCurveTo(12.4, 14.3, 9.6, 13.3, 9.6, 12.0);

ctx.bezierCurveTo(9.6, 10.8, 12.4, 9.7, 15.9, 9.7);

ctx.bezierCurveTo(19.4, 9.7, 22.3, 10.8, 22.3, 12.0);

ctx.closePath();

ctx.fillStyle = "rgb(51, 190, 0)";

ctx.fill();

// Save ship data.

ship = ctx.getImageData(0, 0, 30, 30);

// Erase it for now.

ctx.putImageData(oldBack, 0, 0);

}

function doGameLoop() {

// Put old background down to erase shipe.

ctx.putImageData(oldBack, oldShipX, oldShipY);

// Put ship in new position.

ctx.putImageData(ship, shipX, shipY);

}

// Get key press.

function whatKey(evt) {

// Flag to put variables back if we hit an edge of the board.

var flag = 0;

// Get where the ship was before key process.

oldShipX = shipX;

oldShipY = shipY;

oldBack = back;

switch (evt.keyCode) {

// Left arrow.

case 37:

shipX = shipX - 30;

Page 20: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 20

if (shipX < 0) {

// If at edge, reset ship position and set flag.

shipX = 0;

flag = 1;

}

direction = "L";

break;

// Right arrow.

case 39:

shipX = shipX + 30;

if (shipX > 270) {

// If at edge, reset ship position and set flag.

shipX = 270;

flag = 1;

}

direction = "R";

break;

// Down arrow

case 40:

shipY = shipY + 30;

if (shipY > 270) {

// If at edge, reset ship position and set flag.

shipY = 270;

flag = 1;

}

direction = "D";

break;

// Up arrow

case 38:

shipY = shipY - 30;

if (shipY < 0) {

// If at edge, reset ship position and set flag.

shipY = 0;

flag = 1;

}

direction = "U";

break;

// A key for drawing neutralizer field

case 65:

// Using this increases your score.

score = score + 20;

// The ship isn't moving.

flag = 1;

// Draw the neutralizing ray which will let you pass.

neutralize();

break;

// If any other keys were presssed

default:

Page 21: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 21

flag = 1; // Don't move the ship.

alert("Please only use the arrow keys.");

}

// If flag is set, the ship did not move.

// Put everything back the way it was.

// Reduce score since the ship did not move.

if (flag) {

shipX = oldShipX;

shipY = oldShipY;

back = oldBack;

score = score - 1;

} else {

// Otherwise, get background where the ship will go

// So you can redraw background when the ship

// moves again.

back = ctx.getImageData(shipX, shipY, 30, 30);

}

// Increase score.

score = score + 1;

// Draw score on scoreboard.

ctx2.clearRect(0, 0, 300, 300);

ctx2.font = "20 point Ariel";

ctx2.fillText("Score", 20, 15);

ctx2.fillText(score, 100, 15);

// Did we collide?

collideTest();

}

function collideTest() {

// Collision detection. Get a clip from the screen.

// See what the ship would move over.

var clipWidth = 20;

var clipDepth = 20;

var clipLength = clipWidth * clipDepth;

var clipOffset = 5;

var whatColor = ctx.getImageData(shipX + clipOffset, shipY + clipOffset, clipWidth,

clipDepth);

// Loop through the clip and see if you find red or blue.

for (var i = 0; i < clipLength * 4; i += 4) {

if (whatColor.data[i] == 255) {

direction = "P";

break;

}

// Second element is green but we don't care.

if (whatColor.data[i + 2] == 255) {

direction = "B";

break;

Page 22: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 22

}

// Fourth element is alpha and we don't care.

}

// Did we hit something?

if (direction == "P") bang();

if (direction == "B") youWin();

}

function bang() {

// You lose.

alert("Game over! You hit an asteroid.");

// Stop game.

clearTimeout(gameLoop);

window.removeEventListener('keydown', whatKey, true);

}

function youWin() {

// You win.

alert("Game over! You made it to home base.");

// Stop game.

clearTimeout(gameLoop);

window.removeEventListener('keydown', whatKey, true);

}

function drawAsteroids() {

// Draw asteroids.

for (i = 0; i <= 20; i++) {

// Get random positions for asteroids.

var a = Math.floor(Math.random() * 299);

var b = Math.floor(Math.random() * 299);

// Make the asteroids red

ctx.fillStyle = "#FF0000";

// Keep the asteroids far enough away from

// the beginning or end.

// Draw an individual asteroid.

ctx.beginPath();

ctx.arc(a, b, 10, 0, Math.PI * 2, true);

ctx.closePath();

ctx.fill();

}

// Draw green for neutralizer.

ctx.fillStyle = "#00FF00";

ctx.beginPath();

ctx.rect(270, 270, 30, 30);

ctx.closePath();

ctx.fill();

// Save it for later.

bomb = ctx.getImageData(270, 270, 30, 30);

Page 23: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 23

// Draw blue base.

ctx.fillStyle = "#0000FF";

ctx.beginPath();

ctx.rect(270, 270, 30, 30);

ctx.closePath();

ctx.fill();

// Make some room at beginning.

ctx.putImageData(back, 0, 30);

ctx.putImageData(back, 30, 0);

ctx.putImageData(back, 30, 30);

// Make some room at end.

ctx.putImageData(back, 240, 240);

ctx.putImageData(back, 270, 240);

ctx.putImageData(back, 240, 270);

}

// Create neutralizer field.

function neutralize() {

// Which way was the ship going?

// Put down a neuralizer field that way.

switch (direction) {

case "D":

ctx.putImageData(bomb, shipX, shipY + 30);

break;

case "U":

ctx.putImageData(bomb, shipX, shipY - 30);

break;

case "L":

ctx.putImageData(bomb, shipX - 30, shipY);

break;

case "R":

ctx.putImageData(bomb, shipX + 30, shipY);

break;

default:

}

}

</script>

</head>

<body onload="canvasSpaceGame()">

<h1>

Canvas Space Game

</h1>

<canvas id="myCanvas" width="300" height="300">

</canvas>

Page 24: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 24

<canvas id="myScore" width="300" height="300">

</canvas>

</body>

</html>

Código del cuerpo

La mayor parte del código del cuerpo es el mismo que el código del cuerpo del tema Detección de colisiones. Sin

embargo, se incorpora una segunda etiqueta de Canvas que se usará para crear un segundo elemento de lienzo

para mostrar el puntaje.

Código de script

El código de script comienza con el mismo código de script que el tema Detección de colisiones. Sin embargo,

modifica casi todos los bloques y agrega varios códigos nuevos. El código de script de esta muestra consta de los

siguientes elementos:

Variables globales

Función canvasSpaceGame

Función makeShip

Función whatKey

Función collideTest

Función drawAsteroids

Función bang

Función youWIn

Función neutralize

Se invocan variables globales cuando se carga la página. Se invoca la función canvasSpaceGame desde el

atributo "onload" de la etiqueta del contenido. Se llama al resto de las funciones desde la

función canvasSpaceGame.

Variables globales

Se agregan dos nuevas variables globales:

Direction hace un seguimiento de la dirección en que se está moviendo la nave. Cuando la nave choca con

un objeto, esta variable también se usa para determinar cómo finaliza el juego.

Score hace un seguimiento del puntaje. Cada vez que se mueve la nave, el puntaje aumenta un punto. Si

usas una bomba para destruir un asteroide, se suman 20 puntos al puntaje. El objetivo del juego es volar

por el campo de asteroides para llegar a la base central con el menor puntaje posible. Esto se puede lograr

al tomar decisiones cuidadosas acerca de si se desea moverse alrededor de los asteroides o si se desea

lanzarles bombas.

Función canvasSpaceGame

Esta función es casi la misma que la función canvasSpaceGame de la tercera tarea de este escenario, "Detección

de colisiones". Se agrega un segundo lienzo a esta función para que puedas mostrar la puntuación sin modificar el

primer lienzo. Además, se realiza una llamada a la función drawAsteroids para dibujar los asteroides en la pantalla

y crear la base central.

Función whatKey

Esta función comienza con el mismo código que la función whatKey de la tercera tarea de este escenario:

"Detección de colisiones", pero se agregan varios elementos nuevos para facilitar el cálculo del puntaje y el

lanzamiento de bombas.

Si se presionan las teclas arriba, abajo, izquierda o derecha para mover la nave espacial, se guarda la dirección de

la nave para que se la pueda usar para determinar dónde aterrizará la bomba. Si se presiona la tecla "A", esto

Page 25: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 25

activa la bomba y suma 20 puntos al puntaje. Se coloca la bandera para indicar que la nave no se movió y se invoca

la función "neutralize" para dibujar la bomba en la pantalla.

La función whatKey también se encarga del puntaje. Si la nave se mueve, se suma un punto. El puntaje se muestra

en la segunda pantalla de lienzo. Para esto, primero se borra la pantalla, después se establece la fuente, se dibuja

la palabra "Puntuación" y después se muestra un puntaje numérico. Si la nave no se movió, no se suma ningún

punto al puntaje.

Función collideTest

Se modificó esta función desde la función collideTest de la tercera tarea de este escenario, "Detección de

colisiones", para determinar qué hacer si ocurre una colisión. Si la nave colisiona con un asteroide, se cambia la

variable direction a "P" y se la procesa más adelante. Este otro uso de la variable direction no causará problemas

porque la nave ya no puede moverse y, por lo tanto, no tiene una dirección.

Si la nave colisiona con la base central, cambia la variable direction a "B" y se la procesa más adelante. Después de

haber procesado la instantánea, se realiza una prueba para ver si hubo una colisión. Se invoca la función bang si la

nave chocó con un asteroide. Se invoca la función youWin si la nave se acopló a la base central.

Función bang

Se invoca esta función cuando la nave choca con un asteroide. Se muestra una alerta para indicar que se destruyó

la nave y que finalizó el juego. Debes realizar dos acciones adicionales para lograr que el código deje de ejecutarse:

Detener el bucle de juego al invocar la función clearTimeout con la variable original gameLoop que creaste

cuando estableciste el bucle de juego. De lo contrario, este continuará ejecutándose.

También debes detener el agente de escucha de eventos llamando a removeEventListener. Si no realizas

esta acción, se continuarán procesando las teclas y se continuarán realizando las acciones.

Función youWin

Se invoca esta función si la nave se acopla a la base central. Una alerta avisa al jugador que ha ganado el juego.

También debes detener el bucle de juego y el agente de escucha de eventos del teclado de la misma manera en

que lo hace la función "bang".

Función drawAsteroids

Esta constituye una pequeña modificación de la función drawAsteroid en la tercera tarea de este escenario,

"Detección de colisiones". Un cambio es dibujar un rectángulo verde (que representa los restos de la bomba) antes

de dibujar la base central y guardarla para usarla más adelante. El otro cambio es dibujar imágenes negras

alrededor de la ubicación inicial de la nave y la base central, mediante el uso de la variable de imagen back. Esto

hará que el juego sea un poco más sencillo, ya que no habrá tantos asteroides agolpados en la ubicación de inicio o

en la base central.

Función neutralize

Esta nueva función simplemente toma el valor de dirección y usa la instrucción switch para decidir dónde dibujar la

imagen de la bomba. La variable direction determina la ubicación de la bomba. Dado que la imagen de la bomba

verde no tiene color rojo ni azul, la nave podrá moverse a través de los restos de la bomba sin que haya una

colisión. Esto muestra qué tan fácil es usar Canvas para modificar el comportamiento del juego al manipular los

colores de los píxeles de los objetos de la pantalla.

Depuración visual

Al usar el elemento Canvas para detectar colisiones, puede ser útil ver una instantánea del objeto con el que estás

colisionando. No puedes ver el objeto con el que estás colisionando porque la nave espacial lo está tapando.

Puedes ver la instantánea de la detección de colisión al agregar esta línea a la función collideTest justo después de

calcular la imagen whatColor.

ctx2.putImageData(whatColor,50,100);

Page 26: 1.- Dibujar el fondo y la nave...En primer lugar, volver a dibujar la imagen cada vez que se la mueve. En segundo lugar, restaurar el fondo que se En segundo lugar, restaurar el fondo

Juego de nave espacial HTML5 - Canvas

Código tomado de: https://msdn.microsoft.com/es-es/library/gg589490(v=vs.85).aspx 26

Puedes mostrar la imagen instantánea en un elemento de lienzo separado (ctx2) para que no interfiera con el

elemento de lienzo principal donde se está desarrollando el juego. Esta es una técnica valiosa para cuando se está

trabajando con juegos de Canvas porque se puede ver qué imágenes se crearon o se están usando. Además,

también podrías usar una segunda pantalla de lienzo para escribir datos de variables numéricas a fin de poder

hacer fácilmente un seguimiento de los valores intermedios para depuración.

Empezar a jugar

Para comenzar a jugar, presiona una de las cuatro teclas de flecha del teclado. La nave se mueve en esa dirección.

Si conduces la nave hacia un asteroide rojo, la nave se destruye, el juego termina y pierdes. Si un asteroide se

encuentra en tu camino y deseas eliminarlo, presiona la tecla "A" para lanzar una bomba verde. La bomba hará

explotar el asteroide y podrás volar a través del polvo verde hasta un lugar seguro. La dirección en que se lanza la

bomba se basa en tu último movimiento; por ejemplo, si se mueve hacia la izquierda, la bomba se lanzará un

espacio a la izquierda de tu nave. Si intentas mover tu nave fuera de la pantalla, el juego no te lo permitirá.

Puntuación

Durante el juego, el puntaje se muestra continuamente en un elemento de lienzo separado ubicado a la derecha del

elemento de lienzo del juego. El puntaje dependerá de la cantidad de veces que muevas la nave y de la cantidad de

bombas que lances. Cada movimiento de la nave suma un punto y cada lanzamiento de bomba suma veinte puntos.

Tu objetivo es lograr el menor puntaje posible antes de llegar a la base central. Usa las bombas con moderación y

elige tu ruta con inteligencia.

Finalización del juego

Cuando finaliza el juego, puedes apagarlo simplemente cerrando el explorador. Si deseas jugar de nuevo, actualiza

la página del explorador para iniciar un juego nuevo. Cada vez que juegues, los asteroides y las estrellas

aparecerán en nuevas posiciones aleatorias que te presentarán un nuevo desafío.