Aprende CreateJS construyendo un juego de HTML5 Pong

La web se mueve rápido, ¡tan rápido que nuestro tutorial original de EaselJS ya está desactualizado! En este tutorial, aprenderá a usar la nueva suite CreateJS creando un sencillo clon de Pong.


Vista previa del resultado final

Echemos un vistazo al resultado final en el que trabajaremos:

Dele "click" para jugar

Este tutorial se basa en el juego Create a Pong de Carlos Yanez en HTML5 con EaselJS, que a su vez se basa en su guía Getting Started With EaselJS. Los gráficos y los efectos de sonido están tomados del tutorial anterior..


Paso 1: Crear index.html

Este será nuestro principal. index.html expediente:

    Apestar             

Como puede ver, es bastante corto y consiste principalmente en cargar las bibliotecas CreateJS.

Desde el lanzamiento de CreateJS (que básicamente agrupa todas las bibliotecas separadas EaselJS) ya no tenemos que descargar los archivos JS ni alojarlos en nuestro sitio web; los archivos ahora se colocan en un CDN (Content Delivery Network) que nos permite cargar estos archivos de manera remota lo más rápido posible.

Repasemos el código:

 

Esta línea elimina el resaltado móvil que puede aparecer cuando intentas jugar el juego en el móvil. (El resaltado móvil hace que el objeto del lienzo se resalte y, por lo tanto, ignore los movimientos de sus dedos).

A continuación, tenemos la carga de las bibliotecas CreateJS:>

     

Este código carga los archivos JS desde el CDN de CreateJS y básicamente nos permite utilizar cualquiera de las funciones de CreateJS en nuestro código.

A continuación, cargaremos el complemento SoundJS Flash, que proporciona soporte de sonido para los navegadores que no admiten el audio HTML5. Esto se hace usando un SWF (un objeto Flash) para cargar los sonidos.

 

En este caso no utilizaremos el CDN; en su lugar, descargaremos la biblioteca SoundJS de http://createjs.com/#!/SoundJS/download y colocaremos soundjs.flashplugin-0.2.0.min.js y FlashAudioPlugin.swf archivos en una carpeta local llamada bienes.

Último entre los archivos JS, cargaremos el Main.js Archivo que contendrá todo el código de nuestro juego:

 

Finalmente, coloquemos un objeto Canvas en nuestro escenario..

   

Ahora podemos empezar a trabajar en el código del juego..


Paso 2: Las variables

Nuestro código de juego estará dentro de un archivo llamado Main.js, así que crea y guarda esto ahora.

En primer lugar, vamos a definir variables para todos los objetos gráficos en el juego:

 lienzo var; // Se vinculará al lienzo en nuestro index.html page var stage; // Es el equivalente de etapa en AS3; le agregaremos "hijos" // Gráficos // [Fondo] var bg; // El gráfico de fondo // [Vista de título] var main; // El fondo principal var startB; // El botón de inicio en el menú principal var creditsB; // El botón de créditos en el menú principal // [Créditos] var credits; // La pantalla de Créditos // [Game View] var player; // El jugador paddle gráfico var ball; // El gráfico de la bola var cpu; // La CPU paleta var win; // La popup ganadora var perder; // El popup perdedor

He agregado un comentario para cada variable para que sepa qué cargaremos en esa variable.

A continuación, las puntuaciones:

 // [Score] var playerScore; // La puntuación del jugador principal var cpuScore; // La puntuación de CPU var cpuSpeed ​​= 6; // La velocidad de la paleta de la CPU; Cuanto más rápido es más difícil es el juego

Necesitaremos variables para la velocidad de la pelota:

 // Variables var xSpeed ​​= 5; var ySpeed ​​= 5;

Puedes cambiar estos valores a lo que quieras, si quieres que el juego sea más fácil o más difícil.

Si eres un desarrollador de Flash, sabes que Flash onEnterFrame es muy útil al crear juegos, ya que hay cosas que deben suceder en cada fotograma dado. (Si no está familiarizado con esta idea, consulte este artículo en Game Loop).

Tenemos un equivalente para onEnterFrame en CreateJS, y esa es la corazón Objeto, que puede ejecutar código cada fracción de segundo. Vamos a crear la variable que lo vinculará:

 var tkr = nuevo objeto;

A continuación tenemos el precargador, que utilizará los nuevos métodos PreloadJS.

 // preloader var preloader; var manifiesto var totalLoaded = 0;
  • precargador - contendrá el objeto PreloadJS.
  • manifiesto - mantendrá la lista de archivos que necesitamos cargar.
  • Total cargado - Esta variable mantendrá el número de archivos ya cargados..

Por último, pero no menos importante, en nuestra lista de variables, tenemos TitleView, que contendrá varios gráficos dentro para mostrarlos juntos (como un Flash DisplayObjectContainer).

 var TitleView = nuevo contenedor ();

Vamos a pasar a la función principal ...


Paso 3: La función principal ()

Esta función es la primera función que se ejecuta después de todos los archivos JS de la index.html se cargan Pero lo que se llama esta función?

Bueno, recuerda esta línea de la index.html expediente?

 

Este fragmento de código indica que una vez que se cargan el HTML (y las bibliotecas JS), el Principal la función debería ejecutarse.

Vamos a revisarlo:

 función Main () / * Link Canvas * / canvas = document.getElementById ('PongStage'); etapa = nueva etapa (lienzo); stage.mouseEventsEnabled = true; / * Establecer el complemento de Flash para los navegadores que no son compatibles con SoundJS * / SoundJS.FlashPlugin.BASE_PATH = "asset /"; if (! SoundJS.checkPlugin (true)) alert ("Error!"); regreso;  manifiesto = [src: "bg.png", id: "bg", src: "main.png", id: "main", src: "startB.png", id: "startB" , src: "creditsB.png", id: "creditsB", src: "credits.png", id: "credits", src: "paddle.png", id: "cpu", src: "paddle.png", id: "player", src: "ball.png", id: "ball", src: "win.png", id: "win", src : "lose.png", id: "lose", src: "playerScore.mp3 | playerScore.ogg", id: "playerScore", src: "enemyScore.mp3 | enemyScore.ogg", id: " enemyScore ", src:" hit.mp3 | hit.ogg ", id:" hit ", src:" wall.mp3 | wall.ogg ", id:" wall "]; preloader = new PreloadJS (); preloader.installPlugin (SoundJS); preloader.onProgress = handleProgress; preloader.onComplete = handleComplete; preloader.onFileLoad = handleFileLoad; preloader.loadManifest (manifiesto); / * Ticker * / Ticker.setFPS (30); Ticker.addListener (etapa); 

Vamos a desglosar cada parte:

 canvas = document.getElementById ('PongStage'); etapa = nueva etapa (lienzo); stage.mouseEventsEnabled = true;

Aquí enlazamos el PongStage Objeto de lona de la index.html archivo a la variable de lienzo y luego cree un objeto de escenario a partir de ese lienzo. (El escenario nos permitirá colocar objetos sobre él).

mouseEventsEnabled nos permite usar eventos del mouse, por lo que podemos detectar movimientos y clics del mouse.

 / * Establecer el complemento de Flash para los navegadores que no son compatibles con SoundJS * / SoundJS.FlashPlugin.BASE_PATH = "asset /"; if (! SoundJS.checkPlugin (true)) alert ("Error!"); regreso; 

Aquí configuramos el lugar donde se encuentra el complemento de sonido Flash para aquellos navegadores en los que HTML5 Audio no es compatible

 manifest = [src: "bg.png", id: "bg", src: "main.png", id: "main", src: "startB.png", id: "startB" , src: "creditsB.png", id: "creditsB", src: "credits.png", id: "credits", src: "paddle.png", id: "cpu",  src: "paddle.png", id: "player", src: "ball.png", id: "ball", src: "win.png", id: "win", src: "lose.png", id: "lose", src: "playerScore.mp3 | playerScore.ogg", id: "playerScore", src: "enemyScore.mp3 | enemyScore.ogg", id: "enemyScore ", src:" hit.mp3 | hit.ogg ", id:" hit ", src:" wall.mp3 | wall.ogg ", id:" wall "];

En la variable manifiesta colocamos una matriz de archivos que queremos cargar (y proporcionamos una ID única para cada uno). Cada sonido tiene dos formatos, MP3 y OGG, porque diferentes navegadores son (in) compatibles con diferentes formatos.

 preloader = new PreloadJS (); preloader.installPlugin (SoundJS); preloader.onProgress = handleProgress; preloader.onComplete = handleComplete; preloader.onFileLoad = handleFileLoad; preloader.loadManifest (manifiesto);

Aquí configuramos el objeto precargador utilizando PreloadJS. PreloadJS es una nueva adición a las bibliotecas de CreateJS y es bastante útil.

Creamos un nuevo objeto PreloadJS y lo colocamos en el precargador variable, luego asigne un método a cada evento (en progreso, onComplete, onFileLoad). Finalmente usamos el precargador para cargar el manifiesto que creamos anteriormente.

 Ticker.setFPS (30); Ticker.addListener (etapa);

Aquí agregamos el objeto Ticker al escenario y configuramos la velocidad de cuadros a 30 FPS; Lo usaremos más tarde en el juego para el enterFrame funcionalidad.


Paso 4: Creando las Funciones de Preloader

 function handleProgress (event) // use event.loaded para obtener el porcentaje de la carga function handleComplete (event) // se desencadena cuando toda la carga está completa function handleFileLoad (event) // se desencadena cuando un archivo individual completa la carga switch (event.type) case PreloadJS.IMAGE: // image loaded var img = new Image (); img.src = event.src; img.onload = handleLoadComplete; ventana [event.id] = nuevo Bitmap (img); descanso; case PreloadJS.SOUND: // sound loaded handleLoadComplete (); descanso; 

Repasemos las funciones:

  • manejar el progreso - En esta función podrás seguir el porcentaje del progreso de carga usando este parámetro: evento.loaded. Puedes usar esto para crear, por ejemplo, una barra de progreso..
  • manejarCompleto - Se llama a esta función una vez que se han cargado todos los archivos (en caso de que desee colocar algo allí).
  • manejarFileLoad - Dado que cargamos dos tipos de archivos: imágenes y sonidos, tenemos esta función que manejará cada uno por separado. Si es una imagen, creamos una imagen de mapa de bits y la colocamos en una variable (cuyo nombre es el mismo que el ID de la imagen cargada) y luego llamamos al handleLoadComplete función (que escribiremos a continuación); si es un sonido entonces simplemente llamamos al handleLoadComplete inmediatamente.

Ahora vamos a discutir el handleLoadComplete función que acabo de mencionar:

 función handleLoadComplete (evento) totalLoaded ++; if (manifest.length == totalLoaded) addTitleView (); 

Es una función bastante sencilla; aumentamos el Total cargado variable (que contiene el número de activos cargados hasta el momento) y luego verificamos si el número de elementos en nuestro manifiesto es el mismo que el número de activos cargados, y si es así, vaya a la pantalla del Menú principal.


Paso 5: Creando el Menú Principal

 function addTitleView () //console.log("Add Title View "); inicioB.x = 240 - 31.5; startB.y = 160; startB.name = 'startB'; créditosB.x = 241 - 42; creditsB.y = 200; TitleView.addChild (main, startB, creditsB); stage.addChild (bg, TitleView); stage.update (); // Oyentes de botón startB.onPress = tweenTitleView; creditsB.onPress = showCredits;

Nada especial aquí. Colocamos las imágenes de fondo, botón de inicio y botón de créditos en el escenario y el enlace. onPress controladores de eventos a los botones de inicio y créditos.

Aquí están las funciones que muestran y eliminan la pantalla de créditos y la tweenTitleView que comienza el juego:

 función showCredits () // Show Credits credits.x = 480; stage.addChild (créditos); stage.update (); Tween.get (créditos) .to (x: 0, 300); credits.onPress = hideCredits;  // Función de ocultar créditos hideCredits (e) Tween.get (credits) .to (x: 480, 300) .call (rmvCredits);  // Función para eliminar créditos rmvCredits () stage.removeChild (credits);  // TweenTitleView () // Iniciar juego Tween.get (TitleView) .to (y: -320, 300) .call (addGameView); 

Paso 6: El código del juego

Hemos llegado a la parte principal de este tutorial, que es el código del juego en sí..

En primer lugar, debemos agregar todos los activos necesarios al escenario, por lo que hacemos eso en el addGameView función:

 function addGameView () // Destroy Menu & Credits screen stage.removeChild (TitleView); TitleView = null; créditos = nulo; // Agregar Game View player.x = 2; jugador.y = 160 - 37.5; cpu.x = 480 - 25; cpu.y = 160 - 37.5; ball.x = 240 - 15; ball.y = 160 - 15; // Score playerScore = nuevo texto ('0', 'bold 20px Arial', '# A3FF24'); playerScore.x = 211; playerScore.y = 20; cpuScore = nuevo texto ('0', 'bold 20px Arial', '# A3FF24'); cpuScore.x = 262; cpuScore.y = 20; stage.addChild (playerScore, cpuScore, player, cpu, ball); stage.update (); // Start Listener bg.onPress = startGame; 

Nuevamente, una función bastante sencilla que coloca los objetos en la pantalla y agrega un Evento del ratón a la imagen de fondo, de modo que cuando el usuario haga clic en él, el juego comenzará (llamaremos al empezar juego función).

Revisemos el empezar juego función:

 function startGame (e) bg.onPress = null; stage.onMouseMove = movePaddle; Ticker.addListener (tkr, false); tkr.tick = actualizar; 

Aquí, como puedes ver, además de agregar un onMouseMove Evento que moverá nuestra paleta. Añadimos el garrapata evento, que llamará al actualizar funcion en cada cuadro.

Revisemos el MovePaddle y Reiniciar funciones:

 function movePaddle (e) // Mouse Movement player.y = e.stageY;  / * Reset * / function reset () ball.x = 240 - 15; ball.y = 160 - 15; jugador.y = 160 - 37.5; cpu.y = 160 - 37.5; stage.onMouseMove = null; Ticker.removeListener (tkr); bg.onPress = startGame; 

En MovePaddle, Básicamente colocamos la paleta del usuario en la coordenada Y del ratón..

En Reiniciar, hacemos algo similar a addGameView, excepto aquí no agregamos ningún elemento gráfico ya que ya están en la pantalla.

Utilizando la alerta función mostraremos la ventana emergente ganadora y perdedora:

 función de alerta (e) Ticker.removeListener (tkr); stage.onMouseMove = null; bg.onPress = null if (e == 'win') win.x = 140; win.y = -90; stage.addChild (ganar); Tween.get (ganar) .to (y: 115, 300);  else lose.x = 140; perder.y = -90; stage.addChild (perder); Tween.get (perder) .to (y: 115, 300); 

Paso 7: The Game Loop

Ahora, para la última parte de nuestro tutorial trabajaremos en el actualizar Función (que se produce en cada cuadro del juego, similar a la de Flash onEnterFrame):

 función de actualización () // Ball Movement ball.x = ball.x + xSpeed; ball.y = ball.y + ySpeed; // Movimiento de la CPU si (cpu.y < ball.y)  cpu.y = cpu.y + 4;  else if(cpu.y > ball.y) cpu.y = cpu.y - 4;  // Wall Collision if ((ball.y) < 0)  ySpeed = -ySpeed; SoundJS.play('wall'); ;//Up if((ball.y + (30)) > 320) ySpeed ​​= -ySpeed; SoundJS.play ('wall');; // down / * CPU Score * / if ((ball.x) < 0)  xSpeed = -xSpeed; cpuScore.text = parseInt(cpuScore.text + 1); reset(); SoundJS.play('enemyScore');  /* Player Score */ if((ball.x + (30)) > 480) xSpeed ​​= -xSpeed; playerScore.text = parseInt (playerScore.text + 1); Reiniciar(); SoundJS.play ('playerScore');  / * Colisión de la CPU * / if (ball.x + 30> cpu.x && ball.x + 30 < cpu.x + 22 && ball.y >= cpu.y && ball.y < cpu.y + 75)  xSpeed *= -1; SoundJS.play('hit');  /* Player collision */ if(ball.x <= player.x + 22 && ball.x > player.x && ball.y> = player.y && ball.y < player.y + 75)  xSpeed *= -1; SoundJS.play('hit');  /* Stop Paddle from going out of canvas */ if(player.y >= 249) player.y = 249;  / * Compruebe si hay Win * / if (playerScore.text == '10') alert ('win');  / * Revisa Game Over * / if (cpuScore.text == '10') alerta ('perder'); 

Parece aterrador, ¿no es así? No te preocupes, revisaremos cada parte y lo discutiremos..

 // Movimiento de la bola ball.x = ball.x + xSpeed; ball.y = ball.y + ySpeed;

En cada cuadro, la bola se moverá de acuerdo con sus valores de velocidad x e y

 // Movimiento de la CPU si ((cpu.y + 32) < (ball.y-14))  cpu.y = cpu.y + cpuSpeed;  else if((cpu.y+32) > (ball.y + 14)) cpu.y = cpu.y - cpuSpeed; 

Aquí tenemos la IA básica de la computadora, en la cual la paleta de la computadora simplemente sigue la pelota sin ninguna lógica especial. Simplemente comparamos la ubicación del centro de la paleta (por lo que agregamos 32 píxeles al valor de la CPU Y) con la ubicación de la bola, con un pequeño desplazamiento, y movemos la paleta hacia arriba o hacia abajo según sea necesario.

 si ((ball.y) < 0)  //top ySpeed = -ySpeed; SoundJS.play('wall'); ; if((ball.y + (30)) > 320) // bottom ySpeed ​​= -ySpeed; SoundJS.play ('pared'); ;

Si la bola golpea el borde superior o el borde inferior de la pantalla, la bola cambia de dirección y reproducimos el sonido de golpe de pared.

 / * CPU Score * / if ((ball.x) < 0)  xSpeed = -xSpeed; cpuScore.text = parseInt(cpuScore.text + 1); reset(); SoundJS.play('enemyScore');  /* Player Score */ if((ball.x + (30)) > 480) xSpeed ​​= -xSpeed; playerScore.text = parseInt (playerScore.text + 1); Reiniciar(); SoundJS.play ('playerScore'); 

El inicio de sesión de la puntuación es simple: si la pelota pasa los bordes izquierdo o derecho, aumenta la puntuación del jugador o la CPU respectivamente, reproduce un sonido y restablece la ubicación de los objetos utilizando la Reiniciar función que hemos discutido anteriormente.

 / * CPU collision * / if (ball.x + 30> cpu.x && ball.x + 30 < cpu.x + 22 && ball.y >= cpu.y && ball.y < cpu.y + 75)  xSpeed *= -1; SoundJS.play('hit');  /* Player collision */ if(ball.x <= player.x + 22 && ball.x > player.x && ball.y> = player.y && ball.y < player.y + 75)  xSpeed *= -1; SoundJS.play('hit'); 

Aquí nos ocupamos de las colisiones de la pelota con las palas; Cada vez que la pelota golpea una de las paletas, la pelota cambia de dirección y se reproduce un sonido.

 if (player.y> = 249) player.y = 249; 

Si la paleta del jugador sale de los límites, la colocamos dentro de los límites..

 / * Compruebe si hay Win * / if (playerScore.text == '10') alert ('win');  / * Revisa Game Over * / if (cpuScore.text == '10') alerta ('perder'); 

En este fragmento, verificamos si el puntaje de alguno de los jugadores ha alcanzado los 10 puntos, y si es así, mostramos el elemento emergente ganador o perdedor al jugador (según su estado de ganador).


Conclusión

Eso es todo, has creado un juego de pong completo usando CreateJS. Gracias por tomarse el tiempo para leer este tutorial.