Advertisement
  1. Code
  2. Coding Fundamentals
  3. Game Development

Crea un juego de reventar globos en Flash

Scroll to top
Read Time: 13 min

() translation by (you can also view the original English article)

Uno de los juegos Flash más populares de todos los tiempos es Bloons, en el que juegas un mono lanzando dardos a globos. Ha generado numerosas secuelas, incluso extendiéndose a otros géneros como la defensa de la torre. Este tutorial le mostrará cómo crear su propio juego de reventar globos con el motor QuickBox2D.


Vista previa del resultado final

Echemos un vistazo al resultado final en el que trabajaremos:

Haga clic y mantenga presionado para determinar el ángulo de la toma. ¡Intenta hacer estallar todos los globos!


Paso 1: Breve descripción

En este tutorial usaremos una serie de clases de ActionScript para crear un juego inspirado en Bloons. El objetivo del juego es disparar a los globos para hacerlos explotar a todos.


Paso 2: Configuración del documento Flash

Abra Flash y cree un documento de 480 píxeles de ancho y 320 píxeles de alto. Establecer la velocidad de fotogramas a 24 fps.


Paso 3: Interfaz

Se utilizará una interfaz colorida y sencilla, con varias formas, botones y clips de película. En los próximos pasos construiremos esta GUI. Los gráficos de ardilla y bellota son de openclipart.org.


Paso 4: Antecedentes

Este fondo fue creado en Flash usando rectángulos simples y formas ovaladas. La barra marrón en la parte inferior servirá como barra de información.


Paso 5: Título y Globos

Para crear el título, seleccione la herramienta Texto (T) y cambie el color a #EEEEEE; escribe el texto de tu título (he usado la fuente GoodDog) y agrega una sombra simple. Para el globo, seleccione la herramienta Ovalo (O) y cree un óvalo de 20x30 px #FFCE47. Usa la herramienta Poly Star para el pequeño triángulo debajo de él.


Paso 6: Botones

Utilice nuevamente la Herramienta texto para crear dos botones como se muestra en la imagen de arriba. Conviértalos en botones y déles nombres de instancia descriptivos para que podamos usarlos más adelante en el código. Convierta los gráficos en el escenario en un único clip MovieClip y asígnele el nombre TitleView. Recuerde marcar la casilla Exportar para ActionScript.


Paso 7: Pantalla de juego

Esta es la pantalla del juego, que contiene todos los elementos dinámicos e interactivos del juego. Se generarán más de ellos en tiempo de ejecución utilizando ActionScript. Puedes leer los nombres de instancia en la imagen de arriba.


Paso 8: Pantalla de Créditos

La pantalla de Créditos aparecerá frente a la pantalla de Título; Usa los gráficos y fuentes de antes para crearlo. Asígnele el nombre CreditsView y recuerde marcar la casilla Exportar para ActionScript.


Paso 9: Alerta

Se mostrará una alerta cuando se hayan reventado todos los globos; se mostrará un juego sobre el mensaje y la puntuación. Use la herramienta Rectángulo para crearlo y establecer su nombre de instancia en AlertView. Una vez más, marque la casilla Exportar para ActionScript.


Paso 10: Sonidos

Usaremos efectos de sonido para mejorar la sensación del juego; Puede encontrar el sonido utilizado en este ejemplo en Soungle.com usando la palabra clave pop.


Paso 11: TweenNano

Usaremos un motor de interpolación diferente del predeterminado incluido en Flash, esto aumentará el rendimiento y será más fácil de usar.

Puedes descargar TweenNano desde su sitio web oficial.


Paso 12: QuickBox 2D

Usaremos la útil biblioteca de física QuickBox2D para crear este juego. Si no está familiarizado con él, puede seguir la Serie de Introducción de Activetuts+.

Puede descargar QuickBox2D desde su sitio web oficial.


Paso 13: Establecer clase de documento


Haremos que nuestra aplicación sea interactiva utilizando una clase externa. Agregue su nombre al campo Clase en la sección Publicar del panel Propiedades para asociar la FLA con la clase de documento principal.


Paso 14: Crear una nueva clase de ActionScript


Cree una nueva clase de ActionScript 3.0 (Cmd + N) y guárdela como Main.as en su carpeta de clase.


Paso 15: Estructura de la clase

Crea tu estructura declase básica para comenzar a escribir tu código.

1
 
2
package  
3
{ 
4
  import flash.display.Sprite; 
5
	 
6
	public class Main extends Sprite 
7
	{ 
8
		public function Main():void 
9
		{ 
10
			// constructor code 

11
		} 
12
	} 
13
}

Paso 16: Clases Requeridas

Estas son las clases que necesitaremos importar para que nuestra clase funcione; La directiva de importación import hace que las clases y los paquetes definidos externamente estén disponibles para su código.

1
 
2
import flash.display.MovieClip; 
3
import com.actionsnippet.qbox.*; 
4
import com.greensock.TweenNano; 
5
import com.greensock.easing.Expo; 
6
import flash.events.MouseEvent; 
7
 
8
import Box2D.Common.Math.*; 
9
import flash.events.Event; 
10
import flash.net.navigateToURL; 
11
import flash.net.URLRequest;

Paso 17: Variables

Estas son las variables que usaremos. Lea los comentarios en el código para saber más sobre ellos; Algunos de sus nombres se explican por sí mismos, por lo que no habrá comentarios allí.

1
 
2
private var titleView:TitleView = new TitleView(); 
3
private var credits:CreditsView; 
4
private var world:QuickBox2D; 
5
private var acorn:QuickObject; 
6
private var acorns:Array = [];//stores the acorns thrown 

7
private var contacts:QuickContacts; //used to handle collisions in quickbox2d 

8
private var balloons:Array = []; //stores the balloons in stage 

9
private var yImpulse:Number = 0; //vertical strength to shoot the acorn 

10
private var xImpulse:int = 3; //default horizontal strength the acorn is thrown 

11
private var pop:Pop = new Pop(); //the sound in the library

Paso 18: Constructor

El constructor es una función que se ejecuta cuando un objeto se crea a partir de una clase, este código es el primero en ejecutarse cuando se crea una instancia de un objeto. El constructor de la clase de documento es un caso especial: se ejecuta al inicio del juego.

Usamos esto para llamar a las funciones necesarias para iniciar el juego. Verifique esas funciones en los siguientes pasos.

1
 
2
public final function Main():void 
3
{ 
4
	//Code 

5
}

Paso 19: Añadir vista de título

Comenzamos agregando el TitleView de la biblioteca al escenario.

1
 
2
addChild(titleView); 
3
startButtonListeners();

Paso 20: Iniciar los botones de escucha

Esto agregará los escuchas del mouse a los botones en la vista de título, que nos llevará a la pantalla del juego o créditos.

1
 
2
private final function startButtonListeners(action:String = 'add'):void 
3
{ 
4
	if(action == 'add') 
5
	{ 
6
		titleView.creditsBtn.addEventListener(MouseEvent.MOUSE_UP, showCredits); 
7
		titleView.playBtn.addEventListener(MouseEvent.MOUSE_UP, showGameView); 
8
	} 
9
	else 
10
	{ 
11
		titleView.creditsBtn.removeEventListener(MouseEvent.MOUSE_UP, showCredits); 
12
		titleView.playBtn.removeEventListener(MouseEvent.MOUSE_UP, showGameView); 
13
	} 
14
}

Paso 21: Mostrar créditos

La pantalla de Créditos se muestra cuando el usuario hace clic en el botón Créditos. Se agrega un detector de mouse al MovieClip completo para eliminarlo.

1
 
2
private final function showCredits(e:MouseEvent):void 
3
{ 
4
	titleView.creditsBtn.visible = false; 
5
	titleView.playBtn.visible = false; 
6
	credits = new CreditsView(); 
7
	addChild(credits); 
8
	TweenNano.from(credits, 0.3, {x:-credits.width, onComplete:function():void{credits.addEventListener(MouseEvent.MOUSE_UP, hideCredits);}}); 
9
}

Paso 22: Ocultar Créditos

Cuando se hace clic en la pantalla Créditos, se interpone y se elimina del escenario.

1
 
2
private final function hideCredits(e:MouseEvent):void 
3
{ 
4
    TweenNano.to(credits, 0.3, { 
5
        x: -credits.width, 
6
        onComplete: function (): void { 
7
            titleView.creditsBtn.visible = true; 
8
            titleView.playBtn.visible = true; 
9
            credits.removeEventListener(MouseEvent.MOUSE_UP, hideCredits); 
10
            removeChild(credits); 
11
            credits = null; 
12
        } 
13
    }); 
14
}

Paso 23: Mostrar vista de juego

Las siguientes líneas eliminan la pantalla de título y dejan la pantalla de juego visible. Aquí también llamamos a las funciones necesarias para iniciar el juego; Estas funciones se explican en los siguientes pasos.

1
 
2
private final function showGameView(e:MouseEvent):void 
3
{ 
4
    TweenNano.to(titleView, 0.3, { 
5
        y: -titleView.height, 
6
        onComplete: function (): void { 
7
            startButtonListeners('rmv'); 
8
            removeChild(titleView); 
9
            titleView = null; 
10
            startGame(); 
11
        } 
12
    }); 
13
}

Paremos aquí para hacer una prueba rápida y asegurarnos de que nuestro código de juego funciona:

Tenga en cuenta que algunas líneas se han comentado, ya que algunas funciones aún no se han creado.

Recuerde que los hitos están incluidos en los archivos de origen, por lo que si por alguna razón su archivo no imita este, mire la fuente para ver qué está causando eso.


Paso 24: Oyentes del juego

Esta función agrega los dispositivos de escucha del mouse necesarios para realizar el disparo de bellota.

1
 
2
private final function gameListeners(action:String = 'add'):void 
3
{ 
4
	if(action == 'add') 
5
	{ 
6
		bg.addEventListener(MouseEvent.MOUSE_DOWN, startCharge); 
7
		bg.addEventListener(MouseEvent.MOUSE_UP, shot); 
8
		restartBtn.addEventListener(MouseEvent.MOUSE_UP, restartLvl); 
9
		stage.addEventListener(Event.ENTER_FRAME, update); 
10
	} 
11
	else 
12
	{ 
13
		bg.removeEventListener(MouseEvent.MOUSE_DOWN, startCharge); 
14
		bg.removeEventListener(MouseEvent.MOUSE_UP, shot); 
15
		restartBtn.removeEventListener(MouseEvent.MOUSE_UP, restartLvl); 
16
		stage.removeEventListener(Event.ENTER_FRAME, update); 
17
	} 
18
}

Paso 25: Comience el juego

Aquí comenzamos el juego creando el mundo de Box2D y llamando a las funciones que crearán los globos y manejarán los eventos del mouse.

1
 
2
private final function startGame():void 
3
{ 
4
	/* Hide gCircle */ 
5
	 
6
	gCircle.visible = false; 
7
	 
8
	/* New B2D world */ 
9
	 
10
	world = new QuickBox2D(this, {debug:0}); 
11
	contacts = world.addContactListener(); 
12
	contacts.addEventListener(QuickContacts.ADD, onAdd); 
13
	 
14
	/* Create balloon function */ 
15
	 
16
	gameListeners(); 
17
	createBalloons(); 
18
}

Paso 26: Crear Globos

Anidados bucles for se utilizan para colocar los globos en el escenario. Esta función utilizará el método AddBox de QuickBox2D para crear un nuevo objeto Box2D que se configurará como un sensor; esto significa que no habrá una reacción física a la colisión (es decir, la bellota no rebotará), pero aún así una colisión sera detectada. Usando este método podemos destruir el globo pero dejar que la bellota continúe su camino como si nada hubiera pasado.

El globo se agrega a una matriz; Esto nos dará acceso a todos los globos fuera de esta función.

1
 
2
private final function createBalloons(h:int = 5, v:int = 3):void 
3
{ 
4
	for(var i:int = 0; i < h; i++) 
5
	{ 
6
		for(var j:int = 0; j < v; j++) 
7
		{ 
8
			var balloon:QuickObject = world.addBox({x:10 + (i * 0.66), y:4 + (j * 1), width: 0.66, height: 1, skin:Balloon, fixedRotation:true, draggable:false, density:0}); 
9
			balloon.shape.m_isSensor = true; 
10
			balloons.push(balloon); 
11
		} 
12
	} 
13
	 
14
	/* Set balloon counter */ 
15
	 
16
	targetTF.text = String(balloons.length); 
17
	 
18
	/* Start Physics */ 
19
	 
20
	world.start(); 
21
}

Por supuesto, no tiene que usar anidados bucles for para colocar los globos; Esta es la forma más fácil de colocarlos en una cuadrícula, pero puede colocarlos manualmente si lo prefiere.


Paso 27: Detección de colisiones

Esta función maneja la colisión mencionada en el Paso 26. Lo primero que debe hacer es ir a través de la matriz de globos, verificando cada uno para ver si está chocando con la bellota.

1
 
2
private final function onAdd(e:Event):void 
3
{ 
4
	for(var i:int = 0; i < balloons.length; i++) 
5
	{ 
6
		if(contacts.isCurrentContact(balloons[i], acorn)) 
7
		{

Paso 28: Destruye Globo

Si la colisión es verdadera, llamamos al método destroy() del globo QuickObject y eliminamos el elemento de la matriz.

1
 
2
balloons[i].destroy(); 
3
balloons.splice(i, 1);

Paso 29: Reproducir sonido

Luego reproducimos un sonido que indica el golpe, lo que mejora la sensación de juego.

1
 
2
pop.play();

Paso 30: Actualizar puntaje y contadores de objetivos

Los contadores de puntaje y de objetivo se actualizan de acuerdo con los globos que se abrieron y los globos que quedaron.

1
 
2
scoreTF.text = String(int(scoreTF.text) + 50); 
3
targetTF.text = String(balloons.length);

Paso 31: Revisa el nivel completado

Se llama una alerta cuando se hacen estallar todos los globos; Veremos esta función más adelante en el tutorial.

1
 
2
if(targetTF.text == '0') 
3
{ 
4
	alert(); 
5
}

Paso 32: Iniciar carga

Este código revelará el indicador de dirección de la bellota, restablecerá la variable de impulso y de la bellota y agregará un detector de enterframe que manejará el objetivo.

1
 
2
private final function startCharge(e:MouseEvent):void 
3
{ 
4
	yImpulse = 0; 
5
	gCircle.visible = true; 
6
	gCircle.addEventListener(Event.ENTER_FRAME, charge); 
7
}

Paso 33: Carga

El indicador de objetivo gira para mostrar la dirección en la que se disparará la bellota y ajusta la variable de impulso y en consecuencia. La dirección del disparo se ve afectada por dos variables, xImpulse y yImpulse, que se combinan para formar un vector impulse más adelante. xImpulse permanece constante, y se modifica yImpulse a medida que el usuario mantiene presionado el botón del mouse.

1
 
2
private final function charge(e:Event):void 
3
{ 
4
	gCircle.rotation -= 3; 
5
	yImpulse -= 0.2; 
6
 
7
	/* Prevent over-rotation */ 
8
	if(gCircle.rotation < -80) 
9
	{ 
10
		yImpulse = -5.4; 
11
		gCircle.rotation = -80; 
12
	} 
13
}

Paso 34: Disparo

Las siguientes acciones ocurren cuando el botón del mouse está arriba.

1
 
2
private final function shot(e:MouseEvent):void 
3
{ 
4
	/* Hide gCircle */ 
5
	 
6
	gCircle.removeEventListener(Event.ENTER_FRAME, charge); 
7
	gCircle.visible = false; 
8
	gCircle.rotation = 0; 
9
	 
10
	/* Create new Acorn */ 
11
	 
12
	acorn = world.addBox({x:2.76, y:7.33, width: 0.66, height: 0.53, skin:Acorn, fixedRotation:true, draggable:false, density:1}); 
13
	acorns.push(acorn); 
14
	 
15
	/* Shoot acorn */ 
16
	 
17
	var impulse:b2Vec2 = new b2Vec2(xImpulse, yImpulse); 
18
	acorn.body.ApplyImpulse(impulse, acorn.body.GetWorldCenter()); 
19
	 
20
	/* Update Acorn counter */ 
21
	 
22
	acornsTF.text = String(int(acornsTF.text) -1); 
23
}

Paremos aquí para hacer una prueba rápida y asegurarnos de que nuestro código de juego funciona:

Tenga en cuenta que algunas líneas se han comentado ya que esas funciones aún no se han creado.


Paso 35: La función Update

La función de actualización realizará una serie de operaciones EnterFrame. Veamos esas acciones en los siguientes pasos.

1
 
2
private final function update(e:Event):void 
3
{

Paso 36: Eliminar las bellotas fuera del escenario

Las siguientes líneas eliminarán cada bellota que salga del escenario.

1
 
2
/* Remove offstage acorns */ 
3
	 
4
	for(var i:int = 0; i < acorns.length; i++) 
5
	{ 
6
		if(acorns[i].y > 10.66) 
7
		{ 
8
			acorns[i].destroy(); 
9
			acorns.splice(i, 1);

Paso 37: Compruebe si el nivel falló

El juego termina cuando el jugador se queda sin bellotas (o destruye todos los globos como se mencionó anteriormente).

1
 
2
/* Check for level failed */ 
3
	 
4
			if(int(acornsTF.text) &lt;= 0) 
5
			{ 
6
				alert('lose'); 
7
			} 
8
		} 
9
	} 
10
}

Paso 38: Reiniciar Nivel

Este código se ejecuta cuando se hace clic en el botón Reiniciar. Se restablecerán las variables necesarias y los oyentes para reiniciar el nivel.

1
 
2
private final function restartLvl(e:MouseEvent):void 
3
{ 
4
	/* Remove Listeners */ 
5
	 
6
	gameListeners('rmv'); 
7
	 
8
	/* Destroy World */ 
9
	 
10
	world = null; 
11
	 
12
	/* Destroy Balloons, reset score and acorns */ 
13
	 
14
	for(var i:int = 0; i < balloons.length; i++) 
15
	{ 
16
		balloons[i].destroy(); 
17
		scoreTF.text = '0'; 
18
		acornsTF.text = '5'; 
19
	} 
20
	 
21
	balloons = [];//clear balloons array 

22
	 
23
	startGame(); 
24
}

Paso 39: Alerta

Esta función detendrá el juego y mostrará el mensaje Game Over. También agrega un detector de ratón para restablecer el juego cuando se hace clic.

1
 
2
private final function alert(gameState:String = 'win'):void 
3
{ 
4
	gameListeners('rmv'); 
5
	world.stop(); 
6
	 
7
	var alert:AlertView = new AlertView(); 
8
	 
9
	alert.x = stage.stageWidth * 0.5; 
10
	alert.y = stage.stageHeight * 0.5; 
11
	alert.scoreTF.text = scoreTF.text; 
12
	alert.addEventListener(MouseEvent.MOUSE_UP, restart); 
13
	 
14
	if(gameState == 'lose') 
15
	{ 
16
		alert.titleTF.text = 'Level Failed!'; 
17
	} 
18
	 
19
	addChild(alert); 
20
	TweenNano.from(alert, 0.6, {scaleX: 0.2, scaleY: 0.2, ease:Expo.easeOut}); 
21
}

Paso 40: Reiniciar

Este código volverá a cargar el SWF, restaurando cualquier valor y regresando a la pantalla inicial.

1
 
2
private final function restart(e:MouseEvent):void 
3
{ 
4
	navigateToURL(new URLRequest(stage.loaderInfo.url), '_level0'); 
5
}

Conclusión

Haz tus propios ajustes al juego y disfruta creandolo. Quizás podría cambiar el diseño de los globos, o agregar nuevos niveles, o alterar los gráficos.

Espero que te haya gustado este tutorial, ¡gracias por leer!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.