Aprenda CreateJS construyendo un juego de Pong HTML5
Spanish (Español) translation by Juan Pablo Diaz Cuartas (you can also view the original English article)
La web se mueve rápido, ¡tan rápido que nuestro tutorial original de EaselJS ya está desactualizado! En este tutorial, aprenderá a usar el nuevo conjunto de aplicaciones CreateJS creando un clon de Pong simple.
Vista previa del resultado final
Echemos un vistazo al resultado final para el que trabajaremos:
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 efectos de sonido están tomados del tutorial anterior.
Paso 1: Crea index.html
Este será nuestro archivo index.html principal:
1 |
<!DOCTYPE html> |
2 |
<html> |
3 |
<head> |
4 |
<title>Pong</title> |
5 |
|
6 |
<style>/* Removes Mobile Highlight */ *{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}</style> |
7 |
|
8 |
<script src="http://code.createjs.com/easeljs-0.4.2.min.js"></script> |
9 |
<script src="http://code.createjs.com/tweenjs-0.2.0.min.js"></script> |
10 |
<script src="http://code.createjs.com/soundjs-0.2.0.min.js"></script> |
11 |
<script src="http://code.createjs.com/preloadjs-0.1.0.min.js"></script> |
12 |
<script src="http://code.createjs.com/movieclip-0.4.1.min.js"></script> |
13 |
<script src="assets/soundjs.flashplugin-0.2.0.min.js"></script> |
14 |
<script src="Main.js"></script> |
15 |
|
16 |
</head> |
17 |
<body onload="Main();"> |
18 |
<canvas id="PongStage" width="480" height="320"></canvas> |
19 |
</body> |
20 |
</html> |
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 EaselJS separadas) ya no tenemos que descargar los archivos JS y 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:
1 |
<style>/* Removes Mobile Highlight */ *{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}</style> |
Esta línea elimina el resaltado móvil que puede aparecer cuando intenta jugar el juego en un dispositivo móvil. (El resaltado móvil hace que el objeto lienzo quede resaltado y, por lo tanto, ignora los movimientos de los dedos).
A continuación, tenemos la carga de las bibliotecas CreateJS:>
1 |
<script src="http://code.createjs.com/easeljs-0.4.2.min.js"></script> |
2 |
<script src="http://code.createjs.com/tweenjs-0.2.0.min.js"></script> |
3 |
<script src="http://code.createjs.com/soundjs-0.2.0.min.js"></script> |
4 |
<script src="http://code.createjs.com/preloadjs-0.1.0.min.js"></script> |
5 |
<script src="http://code.createjs.com/movieclip-0.4.1.min.js"></script> |
Este código carga los archivos JS desde CreateJS CDN y básicamente nos permite usar cualquiera de las funciones CreateJS en nuestro código
A continuación, cargaremos el complemento SoundJS Flash, que proporciona soporte de sonido para los navegadores que no son compatibles con el audio HTML5. Esto se hace usando un SWF (un objeto Flash) para cargar los sonidos.
1 |
<script src="assets/soundjs.flashplugin-0.2.0.min.js"></script> |
En este caso, no usaremos el CDN; en su lugar, descargaremos la biblioteca SoundJS desde http://createjs.com/#!/SoundJS/download y colocaremos los archivos soundjs.flashplugin-0.2.0.min.js y FlashAudioPlugin.swf en una carpeta local llamada assets.
Último entre los archivos JS, cargaremos el archivo Main.js que contendrá todo el código de nuestro juego:
1 |
<script src="Main.js"></script> |
Finalmente, pongamos un objeto Canvas en nuestro escenario.
1 |
<body onload="Main();"> |
2 |
<canvas id="PongStage" width="480" height="320"></canvas> |
3 |
</body> |
Ahora podemos comenzar 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 cree y guarde esto ahora.
Antes que nada, definamos variables para todos los objetos gráficos en el juego:
1 |
var canvas; //Will be linked to the canvas in our index.html page |
2 |
var stage; //Is the equivalent of stage in AS3; we'll add "children" to it |
3 |
|
4 |
// Graphics
|
5 |
//[Background]
|
6 |
|
7 |
var bg; //The background graphic |
8 |
|
9 |
//[Title View]
|
10 |
|
11 |
|
12 |
var main; //The Main Background |
13 |
var startB; //The Start button in the main menu |
14 |
var creditsB; //The credits button in the main menu |
15 |
|
16 |
//[Credits]
|
17 |
|
18 |
|
19 |
var credits; //The Credits screen |
20 |
|
21 |
//[Game View]
|
22 |
|
23 |
|
24 |
var player; //The player paddle graphic |
25 |
var ball; //The ball graphic |
26 |
var cpu; //The CPU paddle |
27 |
var win; //The winning popup |
28 |
var lose; //The losing popup |
He agregado un comentario para cada variable para que sepas lo que vamos a cargar en esa variable
A continuación, los puntajes:
1 |
//[Score]
|
2 |
|
3 |
var playerScore; //The main player score |
4 |
var cpuScore; //The CPU score |
5 |
var cpuSpeed=6; //The speed of the CPU paddle; the faster it is the harder the game is |
Vamos a necesitar variables para la velocidad de la pelota:
1 |
// Variables
|
2 |
|
3 |
var xSpeed = 5; |
4 |
var ySpeed = 5; |
Puede cambiar estos valores a lo que desee, si desea que el juego sea más fácil o más difícil.
Si eres desarrollador de Flash, sabes que Flash onEnterFrame es muy útil cuando creas juegos, ya que hay cosas que deben suceder en cada cuadro. (Si no está familiarizado con esta idea, consulte este artículo en Game Loop).
Tenemos un equivalente para onEnterFrame en CreateJS, y ese es el objeto ticker, que puede ejecutar código cada fracción de segundo. Vamos a crear la variable que se vinculará a ella:
1 |
var tkr = new Object; |
A continuación tenemos el preloader, que usará los nuevos métodos PreloadJS.
1 |
//preloader
|
2 |
var preloader; |
3 |
var manifest; |
4 |
var totalLoaded = 0; |
-
preloader- contendrá el objeto PreloadJS. -
manifest-contendrá la lista de archivos que necesitamos cargar. -
totalLoaded- esta variable contendrá la cantidad de archivos ya cargados.
Por último, pero no por ello menos importante, en nuestra lista de variables, tenemos TitleView, que guardará varios gráficos para mostrarlos juntos (como Flash DisplayObjectContainer).
1 |
var TitleView = new Container(); |
Pasemos 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 cargar todos los archivos JS de index.html. Pero, ¿cómo se llama a esta función?
Bueno, ¿recuerdas esta línea del archivo index.html?
1 |
<body onload="Main();"> |
Este fragmento de código indica que una vez que se carguen las bibliotecas HTML (y JS), se debe ejecutar la función Principal.
Repasemoslo:
1 |
function Main() |
2 |
{
|
3 |
/* Link Canvas */
|
4 |
|
5 |
canvas = document.getElementById('PongStage'); |
6 |
stage = new Stage(canvas); |
7 |
|
8 |
stage.mouseEventsEnabled = true; |
9 |
|
10 |
|
11 |
/* Set The Flash Plugin for browsers that don't support SoundJS */
|
12 |
SoundJS.FlashPlugin.BASE_PATH = "assets/"; |
13 |
if (!SoundJS.checkPlugin(true)) { |
14 |
alert("Error!"); |
15 |
return; |
16 |
}
|
17 |
|
18 |
manifest = [ |
19 |
{src:"bg.png", id:"bg"}, |
20 |
{src:"main.png", id:"main"}, |
21 |
{src:"startB.png", id:"startB"}, |
22 |
{src:"creditsB.png", id:"creditsB"}, |
23 |
{src:"credits.png", id:"credits"}, |
24 |
{src:"paddle.png", id:"cpu"}, |
25 |
{src:"paddle.png", id:"player"}, |
26 |
{src:"ball.png", id:"ball"}, |
27 |
{src:"win.png", id:"win"}, |
28 |
{src:"lose.png", id:"lose"}, |
29 |
{src:"playerScore.mp3|playerScore.ogg", id:"playerScore"}, |
30 |
{src:"enemyScore.mp3|enemyScore.ogg", id:"enemyScore"}, |
31 |
{src:"hit.mp3|hit.ogg", id:"hit"}, |
32 |
{src:"wall.mp3|wall.ogg", id:"wall"} |
33 |
];
|
34 |
|
35 |
|
36 |
|
37 |
preloader = new PreloadJS(); |
38 |
preloader.installPlugin(SoundJS); |
39 |
preloader.onProgress = handleProgress; |
40 |
preloader.onComplete = handleComplete; |
41 |
preloader.onFileLoad = handleFileLoad; |
42 |
preloader.loadManifest(manifest); |
43 |
|
44 |
/* Ticker */
|
45 |
|
46 |
Ticker.setFPS(30); |
47 |
Ticker.addListener(stage); |
48 |
}
|
Analicemos cada parte:
1 |
canvas = document.getElementById('PongStage'); |
2 |
stage = new Stage(canvas); |
3 |
|
4 |
stage.mouseEventsEnabled = true; |
Aquí vinculamos el objeto PongStage Canvas del archivo index.html a la variable canvas y luego creamos un objeto Stage desde ese lienzo. (El escenario nos permitirá colocar objetos en él).
mouseEventsEnabled nos permite usar eventos de mouse, por lo que podemos detectar movimientos y clics del mouse.
1 |
/* Set The Flash Plugin for browsers that don't support SoundJS */
|
2 |
SoundJS.FlashPlugin.BASE_PATH = "assets/"; |
3 |
if (!SoundJS.checkPlugin(true)) { |
4 |
alert("Error!"); |
5 |
return; |
6 |
}
|
Aquí configuramos dónde reside el complemento de sonido de Flash para aquellos navegadores en los que no se admite el audio HTML5
1 |
manifest = [ |
2 |
{src:"bg.png", id:"bg"}, |
3 |
{src:"main.png", id:"main"}, |
4 |
{src:"startB.png", id:"startB"}, |
5 |
{src:"creditsB.png", id:"creditsB"}, |
6 |
{src:"credits.png", id:"credits"}, |
7 |
{src:"paddle.png", id:"cpu"}, |
8 |
{src:"paddle.png", id:"player"}, |
9 |
{src:"ball.png", id:"ball"}, |
10 |
{src:"win.png", id:"win"}, |
11 |
{src:"lose.png", id:"lose"}, |
12 |
{src:"playerScore.mp3|playerScore.ogg", id:"playerScore"}, |
13 |
{src:"enemyScore.mp3|enemyScore.ogg", id:"enemyScore"}, |
14 |
{src:"hit.mp3|hit.ogg", id:"hit"}, |
15 |
{src:"wall.mp3|wall.ogg", id:"wall"} |
16 |
];
|
En la variable de manifiesto, colocamos una matriz de archivos que queremos cargar (y proporcionamos una identificación única para cada uno). Cada sonido tiene dos formatos: MP3 y OGG, porque diferentes navegadores son (en) compatibles con diferentes formatos.
1 |
preloader = new PreloadJS(); |
2 |
preloader.installPlugin(SoundJS); |
3 |
preloader.onProgress = handleProgress; |
4 |
preloader.onComplete = handleComplete; |
5 |
preloader.onFileLoad = handleFileLoad; |
6 |
preloader.loadManifest(manifest); |
Aquí configuramos el objeto preloader usando PreloadJS. PreloadJS es una nueva adición a las bibliotecas CreateJS y bastante útil.
Creamos un nuevo objeto PreloadJS y lo colocamos en la variable preloader, luego asignamos un método a cada evento (onProgress, onComplete, onFileLoad). Finalmente usamos el preloader para cargar el manifiesto que creamos anteriormente.
1 |
Ticker.setFPS(30); |
2 |
Ticker.addListener(stage); |
Aquí agregamos el objeto Ticker a la etapa y establecemos la frecuencia de cuadro a 30 FPS; lo usaremos más adelante en el juego para la funcionalidad enterFrame.
Paso 4: Creando las Funciones del Preloader
1 |
function handleProgress(event) |
2 |
{
|
3 |
//use event.loaded to get the percentage of the loading
|
4 |
}
|
5 |
|
6 |
function handleComplete(event) { |
7 |
//triggered when all loading is complete
|
8 |
}
|
9 |
|
10 |
function handleFileLoad(event) { |
11 |
//triggered when an individual file completes loading
|
12 |
|
13 |
switch(event.type) |
14 |
{
|
15 |
case PreloadJS.IMAGE: |
16 |
//image loaded
|
17 |
var img = new Image(); |
18 |
img.src = event.src; |
19 |
img.onload = handleLoadComplete; |
20 |
window[event.id] = new Bitmap(img); |
21 |
break; |
22 |
|
23 |
case PreloadJS.SOUND: |
24 |
//sound loaded
|
25 |
handleLoadComplete(); |
26 |
break; |
27 |
}
|
28 |
}
|
Repasemos las funciones:
-
handleProgress- en esta función, podrá seguir el porcentaje del progreso de carga utilizando este parámetro:event.loaded. Puede usar esto para crear, por ejemplo, una barra de progreso. -
handleComplete- se llama a esta función una vez que se han cargado todos los archivos (en caso de que desee colocar algo allí). -
handleFileLoad- como cargamos dos tipos de archivos (imágenes y sonidos), tenemos esta función que manejará cada uno por separado. Si se trata de 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 a la funciónhandleLoadComplete(que escribiremos a continuación); si es un sonido, simplemente llamamos inmediatamente ahandleLoadComplete.
Ahora veamos la función handleLoadComplete que acabo de mencionar:
1 |
function handleLoadComplete(event) |
2 |
{
|
3 |
|
4 |
totalLoaded++; |
5 |
|
6 |
if(manifest.length==totalLoaded) |
7 |
{
|
8 |
addTitleView(); |
9 |
}
|
10 |
}
|
Es una función bastante sencilla; aumentamos la variable total cargada (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


1 |
function addTitleView() |
2 |
{
|
3 |
//console.log("Add Title View");
|
4 |
startB.x = 240 - 31.5; |
5 |
startB.y = 160; |
6 |
startB.name = 'startB'; |
7 |
|
8 |
creditsB.x = 241 - 42; |
9 |
creditsB.y = 200; |
10 |
|
11 |
TitleView.addChild(main, startB, creditsB); |
12 |
stage.addChild(bg, TitleView); |
13 |
stage.update(); |
14 |
|
15 |
// Button Listeners
|
16 |
|
17 |
startB.onPress = tweenTitleView; |
18 |
creditsB.onPress = showCredits; |
Nada especial aquí. Colocamos las imágenes del botón Fondo, botón de inicio y créditos en el escenario y vinculamos los manejadores de eventos onPress a los botones de Inicio y Créditos.
Aquí están las funciones que muestran y eliminan la pantalla de créditos y el tweenTitleView que inicia el juego:
1 |
function showCredits() |
2 |
{
|
3 |
// Show Credits
|
4 |
|
5 |
credits.x = 480; |
6 |
|
7 |
stage.addChild(credits); |
8 |
stage.update(); |
9 |
Tween.get(credits).to({x:0}, 300); |
10 |
credits.onPress = hideCredits; |
11 |
}
|
12 |
|
13 |
// Hide Credits
|
14 |
|
15 |
function hideCredits(e) |
16 |
{
|
17 |
Tween.get(credits).to({x:480}, 300).call(rmvCredits); |
18 |
}
|
19 |
|
20 |
// Remove Credits
|
21 |
|
22 |
function rmvCredits() |
23 |
{
|
24 |
stage.removeChild(credits); |
25 |
}
|
26 |
|
27 |
// Tween Title View
|
28 |
|
29 |
function tweenTitleView() |
30 |
{
|
31 |
// Start Game
|
32 |
|
33 |
Tween.get(TitleView).to({y:-320}, 300).call(addGameView); |
34 |
}
|
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 requeridos a la etapa, por lo que hacemos eso en la función addGameView:
1 |
function addGameView() |
2 |
{
|
3 |
// Destroy Menu & Credits screen
|
4 |
|
5 |
stage.removeChild(TitleView); |
6 |
TitleView = null; |
7 |
credits = null; |
8 |
|
9 |
// Add Game View
|
10 |
|
11 |
player.x = 2; |
12 |
player.y = 160 - 37.5; |
13 |
cpu.x = 480 - 25; |
14 |
cpu.y = 160 - 37.5; |
15 |
ball.x = 240 - 15; |
16 |
ball.y = 160 - 15; |
17 |
|
18 |
// Score
|
19 |
|
20 |
playerScore = new Text('0', 'bold 20px Arial', '#A3FF24'); |
21 |
playerScore.x = 211; |
22 |
playerScore.y = 20; |
23 |
|
24 |
cpuScore = new Text('0', 'bold 20px Arial', '#A3FF24'); |
25 |
cpuScore.x = 262; |
26 |
cpuScore.y = 20; |
27 |
|
28 |
stage.addChild(playerScore, cpuScore, player, cpu, ball); |
29 |
stage.update(); |
30 |
|
31 |
// Start Listener
|
32 |
|
33 |
bg.onPress = startGame; |
34 |
}
|
De nuevo, una función bastante sencilla que coloca los objetos en la pantalla y agrega un mouseEvent a la imagen de fondo, de modo que cuando el usuario haga clic en el juego se iniciará (llamaremos a la función startGame).
Repasemos la función startGame:
1 |
function startGame(e) |
2 |
{
|
3 |
bg.onPress = null; |
4 |
stage.onMouseMove = movePaddle; |
5 |
|
6 |
Ticker.addListener(tkr, false); |
7 |
tkr.tick = update; |
8 |
}
|
Aquí, como puede ver, además de agregar un evento onMouseMove que moverá nuestra paleta. Agregamos el evento tick, que llamará a la función de actualización en cada cuadro.
Repasemos las funciones movePaddle y reset:
1 |
function movePaddle(e) |
2 |
{
|
3 |
// Mouse Movement
|
4 |
player.y = e.stageY; |
5 |
}
|
6 |
|
7 |
/* Reset */
|
8 |
|
9 |
function reset() |
10 |
{
|
11 |
ball.x = 240 - 15; |
12 |
ball.y = 160 - 15; |
13 |
player.y = 160 - 37.5; |
14 |
cpu.y = 160 - 37.5; |
15 |
|
16 |
stage.onMouseMove = null; |
17 |
Ticker.removeListener(tkr); |
18 |
bg.onPress = startGame; |
19 |
}
|
En movePaddle, básicamente colocamos la paleta del usuario en la coordenada y del mouse.
En el reinicio, hacemos algo similar a agregarGameView, excepto que aquí no agregamos ningún elemento gráfico porque ya están en la pantalla.
Usando la función de alerta, mostraremos la ventana emergente ganadora y perdedora:
1 |
function alert(e) |
2 |
{
|
3 |
Ticker.removeListener(tkr); |
4 |
stage.onMouseMove = null; |
5 |
bg.onPress = null |
6 |
|
7 |
if(e == 'win') |
8 |
{
|
9 |
win.x = 140; |
10 |
win.y = -90; |
11 |
|
12 |
stage.addChild(win); |
13 |
Tween.get(win).to({y: 115}, 300); |
14 |
}
|
15 |
else
|
16 |
{
|
17 |
lose.x = 140; |
18 |
lose.y = -90; |
19 |
|
20 |
stage.addChild(lose); |
21 |
Tween.get(lose).to({y: 115}, 300); |
22 |
}
|
23 |
}
|
Paso 7: The Game Loop
Ahora, para la última parte de nuestro tutorial, trabajaremos en la función de actualización (que ocurre en cada fotograma del juego, similar a la función onEnterFrame de Flash):
1 |
function update() |
2 |
{
|
3 |
// Ball Movement
|
4 |
|
5 |
ball.x = ball.x + xSpeed; |
6 |
ball.y = ball.y + ySpeed; |
7 |
|
8 |
// Cpu Movement
|
9 |
|
10 |
if(cpu.y < ball.y) { |
11 |
cpu.y = cpu.y + 4; |
12 |
}
|
13 |
else if(cpu.y > ball.y) { |
14 |
cpu.y = cpu.y - 4; |
15 |
}
|
16 |
|
17 |
// Wall Collision
|
18 |
|
19 |
if((ball.y) < 0) { ySpeed = -ySpeed; SoundJS.play('wall'); };//Up |
20 |
if((ball.y + (30)) > 320) { ySpeed = -ySpeed; SoundJS.play('wall');};//down |
21 |
|
22 |
/* CPU Score */
|
23 |
|
24 |
if((ball.x) < 0) |
25 |
{
|
26 |
xSpeed = -xSpeed; |
27 |
cpuScore.text = parseInt(cpuScore.text + 1); |
28 |
reset(); |
29 |
SoundJS.play('enemyScore'); |
30 |
}
|
31 |
|
32 |
/* Player Score */
|
33 |
|
34 |
if((ball.x + (30)) > 480) |
35 |
{
|
36 |
xSpeed = -xSpeed; |
37 |
playerScore.text = parseInt(playerScore.text + 1); |
38 |
reset(); |
39 |
SoundJS.play('playerScore'); |
40 |
}
|
41 |
|
42 |
/* Cpu collision */
|
43 |
|
44 |
if(ball.x + 30 > cpu.x && ball.x + 30 < cpu.x + 22 && ball.y >= cpu.y && ball.y < cpu.y + 75) |
45 |
{
|
46 |
xSpeed *= -1; |
47 |
SoundJS.play('hit'); |
48 |
}
|
49 |
|
50 |
/* Player collision */
|
51 |
|
52 |
if(ball.x <= player.x + 22 && ball.x > player.x && ball.y >= player.y && ball.y < player.y + 75) |
53 |
{
|
54 |
xSpeed *= -1; |
55 |
SoundJS.play('hit'); |
56 |
}
|
57 |
|
58 |
/* Stop Paddle from going out of canvas */
|
59 |
|
60 |
if(player.y >= 249) |
61 |
{
|
62 |
player.y = 249; |
63 |
}
|
64 |
|
65 |
/* Check for Win */
|
66 |
|
67 |
if(playerScore.text == '10') |
68 |
{
|
69 |
alert('win'); |
70 |
}
|
71 |
|
72 |
/* Check for Game Over */
|
73 |
|
74 |
if(cpuScore.text == '10') |
75 |
{
|
76 |
alert('lose'); |
77 |
}
|
78 |
}
|
Parece aterrador, ¿no? No se preocupe, revisaremos cada parte y lo discutiremos.
1 |
// Ball Movement
|
2 |
|
3 |
ball.x = ball.x + xSpeed; |
4 |
ball.y = ball.y + ySpeed; |
En cada cuadro, la bola se moverá de acuerdo con sus valores de velocidad x , y
1 |
// Cpu Movement
|
2 |
|
3 |
if((cpu.y+32) < (ball.y-14)) { |
4 |
cpu.y = cpu.y + cpuSpeed; |
5 |
}
|
6 |
else if((cpu.y+32) > (ball.y+14)) { |
7 |
cpu.y = cpu.y - cpuSpeed; |
8 |
}
|
Aquí tenemos la IA básica de la computadora, en la que 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 Y de la CPU) 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.
1 |
if((ball.y) < 0) { //top |
2 |
ySpeed = -ySpeed; |
3 |
SoundJS.play('wall'); |
4 |
};
|
5 |
if((ball.y + (30)) > 320) { //bottom |
6 |
ySpeed = -ySpeed; |
7 |
SoundJS.play('wall'); |
8 |
};
|
Si la pelota golpea el borde superior o el borde inferior de la pantalla, la bola cambia de dirección y tocamos el sonido de golpe de pared.
1 |
/* CPU Score */
|
2 |
if((ball.x) < 0) |
3 |
{
|
4 |
xSpeed = -xSpeed; |
5 |
cpuScore.text = parseInt(cpuScore.text + 1); |
6 |
reset(); |
7 |
SoundJS.play('enemyScore'); |
8 |
}
|
9 |
/* Player Score */
|
10 |
if((ball.x + (30)) > 480) |
11 |
{
|
12 |
xSpeed = -xSpeed; |
13 |
playerScore.text = parseInt(playerScore.text + 1); |
14 |
reset(); |
15 |
SoundJS.play('playerScore'); |
16 |
}
|
El acceso al puntaje 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 usando la función de restablecimiento que hemos discutido anteriormente.
1 |
|
2 |
/* CPU collision */
|
3 |
if(ball.x + 30 > cpu.x && ball.x + 30 < cpu.x + 22 && ball.y >= cpu.y && ball.y < cpu.y + 75) |
4 |
{
|
5 |
xSpeed *= -1; |
6 |
SoundJS.play('hit'); |
7 |
}
|
8 |
/* Player collision */
|
9 |
if(ball.x <= player.x + 22 && ball.x > player.x && ball.y >= player.y && ball.y < player.y + 75) |
10 |
{
|
11 |
xSpeed *= -1; |
12 |
SoundJS.play('hit'); |
13 |
}
|
Aquí tratamos con colisiones de la pelota con las paletas; cada vez que la pelota golpea una de las paletas, la pelota cambia de dirección y se reproduce un sonido
1 |
if(player.y >= 249) |
2 |
{
|
3 |
player.y = 249; |
4 |
}
|
Si la paleta del jugador sale de los límites, la colocamos dentro de los límites.
1 |
/* Check for Win */
|
2 |
if(playerScore.text == '10') |
3 |
{
|
4 |
alert('win'); |
5 |
}
|
6 |
/* Check for Game Over */
|
7 |
if(cpuScore.text == '10') |
8 |
{
|
9 |
alert('lose'); |
10 |
}
|
En este fragmento, verificamos si el puntaje de alguno de los jugadores ha alcanzado los 10 puntos, y si es así mostramos la ventana emergente ganadora o perdedora al jugador (según su estado ganador).
Conclusión
Eso es todo, has creado un juego de pong completo usando CreateJS. Gracias por tomarse el tiempo para leer este tutorial.





