Advertisement
  1. Code
  2. Games

Creando "Flux": un juego flash simple con un mecanismo de gravedad

Scroll to top
Read Time: 22 min

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

En este tutorial, explicaré los principales pasos y el flujo de trabajo para crear un juego simple de supervivencia espacial, basado en la mecánica de gravedad explicada en un tutorial anterior. Este juego está escrito en AS3 usando FlashDevelop.


Juega el Juego

Use las teclas de flecha izquierda y derecha para maniobrar su nave, las teclas de flecha hacia arriba y hacia abajo para aumentar o reducir el tamaño del campo magnético que produce, y la barra espaciadora para invertir la polaridad. Recoge los cristales blancos para aumentar el suministro de combustible, pero evita los rojos, porque lo usan. No golpees una roca, ¡o se acabó el juego!

En este tutorial, no vamos a crear el juego completo que se muestra arriba; comenzaremos con esto, haciendo una versión muy simple con gráficos primitivos y solo un tipo de objeto. Sin embargo, al final, ¡debería haber aprendido lo suficiente para poder agregar las otras características usted mismo!

El juego en sí mismo es muy simple en su estado actual. ¡Mire esta crítica para obtener consejos sobre cómo puede llevarlo de una simple demostración a un juego completo!


¡Empecemos!

Configure un nuevo proyecto AS3 en FlashDevelop y establezca sus dimensiones en 550x600px.

1
 package 
2
{
3
  [SWF(width = "550", height = "600")]
4
	
5
	public class Main extends Sprite
6
	{
7
	
8
	}
9
}

Paso 1: identificando los objetos del juego

Hay seis objetos en partículas que puedes identificar al jugar el juego de arriba:

  • Suministro de energía: representado por un objeto de forma ovalada blanca
  • Asteroide: representado por un objeto parecido a una roca
  • Consumidor de energía: representado por una estrella roja delimitada por una luz verde.
  • Estrellas - el fondo
  • Indicador de rango: representado por un círculo blanco
  • Nave - objeto jugador

Por supuesto, puede agregar cualquier otro objeto para hacer el juego más interactivo o agregar una nueva función. Para este tutorial, solo haremos


Paso 2: la clase de energía

De los objetos que identificamos, cuatro de ellos realmente funcionan exactamente de la misma manera: cayendo de arriba a abajo.

Son:

  • Estrellas
  • Suministro de energía
  • Consumidor de energía
  • Asteroide

En este tutorial, solo vamos a hacer los objetos de "suministro de energía", de los cuatro anteriores. Comencemos creando estos objetos y haciendo que caigan, con una posición y velocidad de desove aleatorias.

Comience creando una clase de Energía:

1
	package  
2
	{
3
		import flash.display.MovieClip;
4
		import flash.events.Event;
5
6
		public class Energy extends MovieClip
7
		{
8
			private var rSpeed:Number = 0;
9
			
10
			public function Energy(speed:Number)
11
			{		
12
				graphics.beginFill(0x321312);
13
				graphics.drawCircle(0, 0 , 8);
14
				
15
				rSpeed = speed;
16
			}
17
			
18
			// we will call this every frame

19
			public function move():void
20
			{
21
				this.y += rSpeed;
22
				//rotation speed is linked to moving speed

23
				this.rotation += rSpeed / 8;
24
			}
25
		}
26
	}

Paso 3: la clase GameScreen

Esta clase eventualmente controlará la mayoría de los aspectos de nuestro juego, incluyendo el movimiento del jugador y el bucle del juego.

Crea la clase:

1
package  
2
{
3
	
4
	public class GameScreen extends MovieClip
5
	{
6
7
		public function GameScreen()
8
		{
9
		
10
		}
11
	}
12
}

Eso es todo lo que necesitamos por ahora.


Paso 4: Actualiza la clase principal

Ahora crearemos una instancia de GameScreen dentro de Main:

1
package 
2
{
3
	import flash.display.Sprite;
4
	import flash.events.Event;
5
6
	[SWF(width = "550", height = "600")]
7
	 
8
	public class Main extends Sprite 
9
	{
10
		private var game:GameScreen;
11
		
12
		public function Main():void 
13
		{
14
			// don't display a yellow rectangle on the screen at startup

15
			stage.stageFocusRect = false;
16
			
17
			game = new GameScreen();
18
			addChild(game);
19
			
20
			// give keyboard focus to the game screen immediately

21
			stage.focus = game;
22
		}
23
	}
24
}

¿Por qué molestarse? Bueno, de esta manera, será más fácil agregar pantallas adicionales más tarde si queremos (como un preloader, una pantalla de título, un juego en la pantalla ...).


Paso 5: Presentación de una clase Manager

Para evitar que la clase GameScreen se convierta en un desastre, usaremos clases separadas para administrar cada objeto.

Cada clase de administrador contendrá todas las funciones que se relacionan e interactúan con un objeto en particular. Aquí está la clase EnergyManager:

1
package  
2
{
3
	import flash.display.MovieClip;
4
	
5
	public class EnergyManager
6
	{
7
		// this Vector will store all instances of the Energy class

8
		private var energyList:Vector.<Energy>	
9
		private var gameScreen:GameScreen;
10
		
11
		public function EnergyManager(gs:GameScreen) 
12
		{
13
			gameScreen = gs;
14
			energyList = new Vector.<Energy>;	
15
		}
16
	}
17
}

Tenga en cuenta que se requiere una referencia a GameScreen para pasar al constructor, y almacenamos esta referencia en una variable privada. También configuramos un Vector para almacenar referencias a todos los objetos de energía.

Hasta ahora, la clase no contiene otras funciones; los agregaremos más tarde.


Paso 6: Creando Energía

Agregue la siguiente función para crear energía, esta es solo una función; llamaremos a la función más tarde desde GameScreen Class:

1
	public function createEnergy(number:int):void	
2
	{
3
		var energy:Energy;
4
		for (var i:int = 0; i < number; i++) {		
5
6
			energy = new Energy(4);				
7
				
8
			gameScreen.addEnergyToScreen(energy);
9
				
10
			energyList.push(energy);				
11
	
12
			energy.x = Calculation.generateRandomValue(30, 520);		
13
			energy.y = Calculation.generateRandomValue( -150, -20); 
14
		}
15
	}

Creamos un nuevo suministro de energía con una velocidad de 4, lo agregamos a la lista de visualización (a través de GameScreen), lo agregamos al Vector de todos los objetos de energía que acabamos de crear y establece su posición a un punto aleatorio dentro de ciertos límites.

El Calculation.generateRandomValue (#, #) es una función estática que aún no hemos escrito, así que hagámoslo ahora. Crea una nueva clase llamada Cálculo y agrega esta función:

1
	public static function generateRandomValue(min:Number, max:Number):Number
2
	{
3
		var randomValue:Number = min + (Math.random() * (max - min));
4
			
5
		return randomValue;
6
	}

Esta función generará un número aleatorio entre los dos valores pasados a él. Para obtener más información sobre cómo funciona, consulte esta sugerencia rápida. Como esta es una función estática, no necesitamos crear una instancia de Cálculo para llamarlo.

Ahora, ¿qué es esa función addEnergyToScreen ()? Todavía no hemos definido eso, así que hagámoslo ahora. Agregue esto a GameScreen:

1
		public function addEnergyToScreen(energy:Energy):void
2
		{
3
			addChild(energy);
4
		}

Simplemente agrega la instancia de energía pasada a la lista de visualización. Hagamos también una función correspondiente para eliminar un objeto de energía dado de la pantalla:

1
		public function removeEnergyFromScreen(energy:Energy):void
2
		{
3
			if (energy.parent == this)
4
			{
5
				removeChild(energy);
6
			}
7
		}

Paso 7: Generando energía

Establezcamos un temporizador que defina el intervalo para cada desove. Este código va en la función de constructor de GameScreen:

1
energyM = new EnergyManager(this);	//remember to pass a reference to the game screen

2
								
3
var spawnTimer:Timer = new Timer(3000, 0);
4
spawnTimer.addEventListener(TimerEvent.TIMER, spawnEnergy);
5
spawnTimer.start();

Entonces, cada tres segundos, el temporizador llamará a spawnEnergy (). Vamos a escribir esa función ahora:

1
	private function spawnEnergy(e:TimerEvent):void
2
	{
3
		energyM.createEnergy(4);    // create 4 energies

4
	}

Paso 8: Creando jugador

Usemos otro círculo más grande para representar al jugador. No dude en importar una imagen para usar en su lugar:

1
public function Player() 
2
		{
3
			graphics.beginFill(0x7ebff1);
4
			graphics.drawCircle(0, 0, 20);

Agregue este código a GameScreen para agregar el reproductor a la pantalla:

1
// in the variable definitions

2
public var player:Player;
1
// in the constructor function

2
player = new Player;
3
addChild(player);
4
player.x = 275;
5
player.y = 450;

Hasta ahora deberíamos tener algunos suministros de energía cayendo unos segundos, y el jugador aparece en el medio de la pantalla:

playerandenergy.playerandenergy.playerandenergy.

Paso 9: moviendo el reproductor

Básicamente hay dos formas de aplicar el movimiento:

  1. Usar valores booleanos (verdadero / falso) - verdadero = mover, falso = no mover. Cuando se presiona la tecla de la flecha hacia la derecha, el valor para "mover a la derecha" cambiará a verdadero. En cada actualización de cuadro, "mover hacia la derecha" es verdadero, aumentamos el valor de x del objeto.
  2. Usar la actualización directa de cada cuadro: cuando se presiona la tecla de la flecha hacia la derecha, se le indica a un objeto que se mueva hacia la derecha inmediatamente, al aumentar su valor de x.

El segundo método no conduce a un movimiento suave cuando la tecla se presiona continuamente, pero el primer método lo hace, por lo que utilizaremos el primer método.

Hay tres pasos simples para hacer esto:

  1. Crea dos variables booleanas, una para mover hacia la derecha y otra para mover hacia la izquierda.
    1
    	private var moveRight:Boolean = false;
    
    2
    	private var moveLeft:Boolean = false;
    
  2. Alternar el booleano cuando se presionan o liberan las teclas:
    1
    		addEventListener(Event.ENTER_FRAME, update);
    
    2
    		addEventListener(KeyboardEvent.KEY_DOWN, KeyDownHandler);
    
    3
    		addEventListener(KeyboardEvent.KEY_UP, KeyUpHandler);
    
    4
    	}
    
    5
    		
    
    6
    	private function KeyDownHandler(e:KeyboardEvent):void
    
    7
    	{
    
    8
    		if (e.keyCode == Keyboard.RIGHT) {
    
    9
    			moveRight = true;
    
    10
    		}
    
    11
    		if (e.keyCode == Keyboard.LEFT) {
    
    12
    			moveLeft = true;
    
    13
    		}
    
    14
    		if (e.keyCode == Keyboard.SPACE) {
    
    15
    			if (isGravityPushing == true) {
    
    16
    				isGravityPushing = false;
    
    17
    			} else  {
    
    18
    				isGravityPushing = true;
    
    19
    			}
    
    20
    		}
    
    21
    	}
    
    22
    		
    
    23
    	private function KeyUpHandler(e:KeyboardEvent):void
    
    24
    	{
    
    25
    		if (e.keyCode == Keyboard.RIGHT) {
    
    26
    			moveRight = false;
    
    27
    		}
    
    28
    		if (e.keyCode == Keyboard.LEFT) {
    
    29
    			moveLeft = false;
    
    30
    		}
    
    31
    	}
    
  3. Con base en estos Booleanos, mueva al jugador en cada cuadro:

    No te olvides de crear primero una función de escuchar desde el evento enter frame, "actualización":

    1
    //call this function every frame
    
    
    2
    private function update(e:Event):void
    
    3
    	if (moveRight == true) {
    
    4
    		player.x += 6;
    
    5
    	}
    
    6
    	if (moveLeft == true) {
    
    7
    		player.x -= 6;
    
    8
    	}
    

    Mantenga al jugador dentro de los límites de la pantalla:

    1
    	if (player.x >= 525) {
    
    2
    		moveRight = false;
    
    3
    	}
    
    4
    	if (player.x <= 20) {
    
    5
    		moveLeft = false;
    
    6
    	}
    

Así es como todo eso se ve, en su lugar:

1
package
2
{
3
    import flash.display.MovieClip;
4
    import flash.events.Event;
5
    import flash.events.TimerEvent;
6
    import flash.ui.Keyboard;
7
    import flash.utils.Timer;
8
    import flash.events.KeyboardEvent;
9
 
10
    public class GameScreen
11
    {
12
        public var player:Player;
13
 
14
        private var energyM:EnergyManager;
15
 
16
        private var moveRight:Boolean = false;
17
        private var moveLeft:Boolean = false;
18
        private var isGravityPushing:Boolean = true;
19
 
20
        private var returnedPower:int = 0;
21
 
22
        private var scoreText:Text;
23
        private var totalScore:int=0;
24
        private var score:Text;
25
 
26
        public function GameScreen()
27
        {
28
            scoreText = new Text("Score :");
29
            addChild(scoreText);
30
 
31
            energyM = new EnergyManager;
32
 
33
            var spawnTimer:Timer = new Timer(3000, 0);
34
            spawnTimer.addEventListener(TimerEvent.TIMER, spawnEnergy);
35
            spawnTimer.start();
36
 
37
            player = new Player;
38
            addChild(player);
39
            player.x = 275;
40
            player.y = 450;
41
 
42
            addEventListener(Event.ENTER_FRAME, update);
43
            addEventListener(KeyboardEvent.KEY_DOWN, KeyDownHandler);
44
            addEventListener(KeyboardEvent.KEY_UP, KeyUpHandler);
45
        }
46
47
	private function KeyDownHandler(e:KeyboardEvent):void
48
	{
49
		if (e.keyCode == Keyboard.RIGHT) {
50
			moveRight = true;
51
		}
52
		if (e.keyCode == Keyboard.LEFT) {
53
			moveLeft = true;
54
		}
55
		if (e.keyCode == Keyboard.SPACE) {
56
			if (isGravityPushing == true) {
57
				isGravityPushing = false;
58
			}else if (isGravityPushing == false) {
59
				isGravityPushing = true;
60
			}
61
		}
62
	}
63
		
64
	private function KeyUpHandler(e:KeyboardEvent):void
65
	{
66
		if (e.keyCode == Keyboard.RIGHT) {
67
			moveRight = false;
68
		}
69
		if (e.keyCode == Keyboard.LEFT) {
70
			moveLeft = false;
71
		}
72
	}
73
74
	private function update(e:Event):void
75
	{
76
		if (player.x >= 525) {
77
			moveRight = false;
78
		}
79
		if (player.x <= 20) {
80
			moveLeft = false;
81
		}
82
		if (moveRight == true) {
83
			player.x += 6;
84
		}
85
		if (moveLeft == true) {
86
			player.x -= 6;
87
		}
88
	}
89
    }
90
}

Paso 10: Mueva los suministros de energía

Por el momento, los suministros de energía están generando pero no se están moviendo. Usaremos la función GameScreen.update () para hacer que se muevan, ya que ejecuta cada cuadro.

Agregue este código a GameScreen.update ():

1
			energyM.moveAll();  // will make every energy object move

Ahora, por supuesto, necesitamos hacer la función EnergyManager.moveAll (), así que agréguela a EnergyManager.as:

1
		public function moveAll():void
2
		{
3
			for (var i:int = 0; i < energyList.length; i++) {
4
				var energyS:Energy = energyList[i];
5
				energyS.move();
6
			}
7
		}

Paso 10: detección de colisión

Tendremos que verificar las colisiones entre cada objeto de energía y el jugador. (Si desarrolla el juego aún más, tendrá que comprobar si hay asteroides y consumidores de energía, pero no estrellas).

El mejor lugar para manejar estos controles es dentro del EnergyManager, que GameScreen activa cada cuadro.

Una cosa a tener en cuenta: las comprobaciones de colisión se realizarán entre dos círculos, por lo que hitTestObject () no es ideal. En cambio, usaremos el método explicado en este tutorial.

Podemos escribir la función de la siguiente manera:

1
	public function checkCollision(p:Player):int
2
	{
3
		// energy transferred due to collision

4
		var energyTransfer:int = 0;
5
		
6
		for (var i:int = 0; i < energyList.length; i++) {
7
			var energyS:Energy = energyList[i];
8
			
9
			var newX:Number = p.x - energyS.x;
10
			var newY:Number = p.y - energyS.y;
11
				
12
			var distance:Number = Math.sqrt(newX * newX + newY * newY);
13
				
14
			if (distance <= 28) {
15
				gameScreen.removeEnergyFromScreen(energyS);
16
				energyList.splice(i, 1);
17
				// for this simple game, we'll always transfer 1 unit

18
				// but you could alter this based on speed of collision

19
				// or any other factor

20
				energyTransfer = 1;
21
			}
22
		}
23
		return energyTransfer;
24
	}
  • Línea 32: ten en cuenta que pasamos una referencia al jugador, para que podamos acceder a su posición.
  • Línea 38: EnergyS es la abreviatura de Energy Supply.
  • Línea 40 y 41: encontrar la diferencia en las coordenadas x e y entre el jugador y el suministro de energía que estamos comprobando actualmente.
  • Línea 43: calcular la distancia entre los objetos a través de Pitágoras.
  • Línea 45: verificar colisión; 28 es la suma de los radios de los dos objetos (el radio del jugador es 20, el radio de energía es 8).
  • Línea 46 y 47: elimine el suministro de energía de la pantalla y de Vector.
  • Línea 51: agregue un máximo de una unidad de energía por cuadro.

Puedes alterar la Línea 51 para energyTransfer + = 1, para permitir que el jugador absorba más de un objeto de energía a la vez. Depende de usted, pruébelo y vea cómo afecta el juego.


Paso 11: Rutina de llamado de Detección de Colisiones

Necesitamos verificar las colisiones en cada cuadro, por lo que deberíamos llamar a la función que acabamos de escribir desde GameScreen.update ().

Primero, necesitamos crear una variable entera para almacenar el valor de transferencia de energía de la función de detección de colisión. Usaremos este valor para aumentar la energía de la nave y aumentar la puntuación del jugador.

1
private var returnedPower:int = 0;
1
returnedPower = energyM.checkCollision(player);

Paso 12: Ley de Gravitación de Newton

Antes de entrar en la creación de la mecánica del juego para la función 'Empujar' y 'tirar' de la nave, me gustaría introducir el concepto de física en el que se basa la mecánica.

La idea es atraer el objeto hacia el jugador por medio de una fuerza. La Ley de la Gravedad Universal de Newton nos da una gran (y simple) fórmula matemática que podemos usar para esto, donde la fuerza es, por supuesto, la fuerza gravitacional:

G es solo un número, y podemos configurarlo para lo que queramos. Del mismo modo, podemos establecer las masas de cada objeto en el juego a cualquier valor que nos guste. La gravedad ocurre a través de infinitas distancias, pero en nuestro juego, tendremos un punto de corte (indicado por el círculo blanco en la demostración desde el comienzo del tutorial).

Las dos cosas más importantes a tener en cuenta acerca de esta fórmula son:

  • La fuerza de la fuerza depende del cuadrado de la distancia entre los dos objetos (por lo que si los objetos están dos veces más lejos, la fuerza es un cuarto tan fuerte).
  • La dirección de la fuerza es a lo largo de la línea directa que conecta los dos objetos a través del espacio.

Paso 13: Revisar los conceptos matemáticos

Antes de comenzar a codificar la mecánica del juego para la función "Empujar" y "Tirar", seamos claros en lo que queremos que haga:

frameWorkframeWorkframeWork

Esencialmente, queremos que A (el jugador) ejerza una cierta fuerza sobre B (un cristal), y mueva B hacia A en función de esa fuerza.

Deberíamos revisar algunos conceptos:

  • El flash funciona en radianes en lugar de grados.
  • El sistema de coordenadas de Flash tiene su eje y invertido: bajar significa un aumento en y.
  • Podemos obtener el ángulo de la línea que conecta A a B usando Math.atan2 (B.y - A.y, B.x - A.x).
  • Podemos usar la trigonometría para calcular cuánto necesitamos mover B a lo largo de cada eje, en función de este ángulo y la fuerza:
    • B.x += (Fuerza*Math.cos(ángulo));
    • B.y += (Fuerza*Math.sin(ángulo));
  • Podemos usar el teorema de Pitágoras para calcular la distancia entre los dos objetos:

Para obtener más información, consulte los tutoriales Gravedad en acción y Trigonometría para desarrolladores de juegos Flash.


Paso 14: Implementando Push and Pull

Según la explicación anterior, podemos obtener un esquema para nuestro código que atrae a cada cristal del barco:

  1. Encuentra la diferencia en xey entre el barco y un cristal dado.
  2. Encuentra el ángulo entre ellos, en radianes.
  3. Encuentra la distancia entre ellos, usando Pitágoras.
  4. Verifica si el objeto está dentro del campo gravitacional del barco.
  5. Si es así, calcule la fuerza gravitatoria y ...
  6. ... aplicar la fuerza, cambiando los valores x e y del cristal.

Código de muestra:

1
	public function gravityPull(p:Player): void
2
	{
3
		for (var i:int = 0; i < energyList.length; i++) {
4
			var energyS:Energy = energyList[i];
5
				
6
			var nX:Number = (p.x - energyS.x);
7
			var nY:Number = (p.y - energyS.y);
8
			
9
			var angle:Number = Math.atan2(nY, nX);
10
				
11
			var r:Number =  Math.sqrt(nX * nX + nY * nY);
12
				
13
			if (r <= 250) {
14
				var f:Number = (4 * 50 * 10) / (r * r); 				
15
				energyS.x += f * Math.cos(angle);
16
				energyS.y += f * Math.sin(angle);
17
			}
18
		}
19
	}
  • Línea 53: obtener una referencia al jugador.
  • Línea 55: recorremos cada objeto de energía.
  • Línea 61: encuentra el ángulo entre el barco y la energía.
  • Línea 63: encuentra la distancia entre ellos, también.
  • Línea 65: verifica si la energía está dentro del campo de fuerza del barco.
  • Línea 67: usa la fórmula:
    • 4 = G, la "constante gravitacional" que he elegido.
    • 50 = m1, la masa del jugador de la nave.
    • 10 = m2, la masa del objeto de energía.
  • Línea 69: aplicar movimiento.

Aquí hay un lapso de tiempo que muestra cómo se ve esto:

Tenga en cuenta que la energía se mueve más rápido cuanto más se acerca a la nave, gracias al término r-cuadrado.

Podemos implementar la función de empuje simplemente haciendo que la fuerza sea negativa:

1
	public function gravityPull(p:Player): void
2
	{
3
		for (var i:int = 0; i < energyList.length; i++) {
4
			var energyS:Energy = energyList[i];
5
				
6
			var nX:Number = (p.x - energyS.x);
7
			var nY:Number = (p.y - energyS.y);
8
			
9
			var angle:Number = Math.atan2(nY, nX);
10
				
11
			var r:Number =  Math.sqrt(nX * nX + nY * nY);
12
				
13
			if (r <= 250) {
14
				var f:Number = (4 * 50 * 10) / (r * r); 				
15
				energyS.x -= f * Math.cos(angle);
16
				energyS.y -= f * Math.sin(angle);
17
			}
18
		}
19
	}

Aquí el objeto se mueve más lentamente a medida que se aleja del jugador, ya que la fuerza se debilita.


Paso 15: aplicar el mecánico

Por supuesto que necesitará esta función para ejecutar cada cuadro por GameScreen, pero antes de eso, necesitaremos usar una función booleana para alternar entre las dos funciones:

1
private var isGravityPushing:Boolean = true;  // hitting space toggles it

Usaremos true para 'Push' y falso para 'Pull'.

Dentro de KeyDownHandler ():

1
	if (e.keyCode == Keyboard.SPACE) {
2
		if (isGravityPushing == true) {
3
			isGravityPushing = false;
4
		} else if (isGravityPushing == false) {
5
			isGravityPushing = true;
6
		}
7
	}

Luego, deberá verificar el booleano de cada cuadro. Agregar esto a la update ():

1
	if (isGravityPushing == true) {
2
		energyM.gravityPull(player);
3
	}
4
	if (isGravityPushing == false) {
5
		energyM.gravityPush(player);
6
	}

Paso 16: modificación

Es posible que el movimiento no se vea tan bien. Esto podría deberse a que la fuerza no es del todo ideal, o debido al término r-cuadrado.

Me gustaría modificar la fórmula así:

1
var f:Number = (0.8 * 50 * 10) / r;

Como puede ver, he reducido el valor de "G" a 0.8, y he cambiado la fuerza para que dependa simplemente de la distancia entre los objetos, en lugar de la distancia al cuadrado.

Pruébelo y vea si disfruta el cambio. Siempre puedes modificarlo como quieras.


Paso 17: la clase de texto

Tendremos que mostrar un texto en la pantalla para mostrar el puntaje y la potencia restante del barco.

Para este propósito, crearemos una nueva clase, Text:

1
package  
2
{
3
	import flash.display.MovieClip;
4
	import flash.text.TextField;
5
	import flash.events.Event;
6
	import flash.text.TextFormat;
7
8
	import flash.text.TextFormatAlign;
9
10
	public class Text extends MovieClip
11
	{
12
		public var _scoreText:TextField= new TextField();
13
		
14
		public function Text(string:String)
15
		{	
16
			var myScoreFormat:TextFormat = new TextFormat(); //Format changeable

17
			myScoreFormat.size = 24;		
18
			
19
			myScoreFormat.align = TextFormatAlign.LEFT;
20
			myScoreFormat.color = (0x131313);
21
			
22
			_scoreText.defaultTextFormat = myScoreFormat;
23
			
24
			_scoreText.text = string;
25
			
26
			addChild(_scoreText);
27
		}
28
29
		public function updateText(string:String)
30
		{
31
			_scoreText.text = string;
32
		}
33
	}
34
}

Es muy sencillo; es básicamente un MovieClip con un campo de texto dentro.


Paso 18: agregar potencia al reproductor

Para darle un poco de desafío al juego, haremos que la potencia del barco se consuma lentamente, de modo que el jugador tenga que recolectar objetos de energía para recargarse.

Para que la potencia del barco aparezca en el barco, simplemente podemos agregar una instancia de Text a la lista de visualización del objeto del barco.

Declare estas variables dentro de la clase Ship:

1
public var totalPower:Number = 100;  // ship starts with this much power

2
private var powerText:Text;

Tendremos que mantener la cantidad de energía (tanto almacenada como mostrada) actualizada en cada cuadro, así que agregue esta nueva función al Player:

Primero, en el constructor:

1
			// add a new text object if it doesn't already exist

2
			if (!powerText) {
3
				powerText = new Text(String(int(totalPower))); 
4
				addChild(powerText);	
5
				powerText.x -= 20;			//Adjust position

6
				powerText.y -= 16;
7
			}

Y entonces...

1
	public function updatePower():void
2
		{
3
			// fps = 24, so this makes power decrease by 1/sec

4
			totalPower -= 1 / 24;		
5
			powerText.updateText(String(int(totalPower)));
6
		}

La potencia disminuirá cada fotograma en 1/24 de una unidad, lo que significa que disminuirá en una unidad completa por segundo.

Necesitamos hacer que esto se ejecute en cada cuadro, así que agrega esta línea a GameScreen.update ():

1
player.updatePower();

Paso 19: hacer que la energía aumente la potencia

Cuando la nave colisiona con un objeto de energía, queremos que aumente su poder.

En GameScreen.update (), agregue la línea resaltada:

1
returnedPower = energyM.checkCollision(player);
2
player.totalPower += returnedPower;

Recuerde que puede modificar la cantidad de energía que se devuelve en la función EnergyManager.checkCollision ().


Paso 20: Configurando el puntaje

De nuevo, necesitaremos la clase de texto. Esta vez, mostraremos "Puntuación" y luego el valor.

Aquí, necesitaremos tres variables más:

  • El texto "Puntuación".
  • El texto del valor del puntaje
  • Una variable para almacenar el puntaje real.

Declare estos en la clase GameScreen:

1
private var scoreText:Text;
2
private var totalScore:int = 0;
3
private var score:Text;

En el constructor, agrega este código:

1
scoreText = new Text("Score :");
2
addChild(scoreText);
3
4
score = new Text(String(totalScore));
5
addChild(score);
6
score.x = scoreText.x + 100;   //Positioning it beside the "Score : " Text.

7
score.y += 2;

Ahora, en la función update () , agregue esto:

1
score.updateText(String(totalScore));

Eso es todo - ¡hemos creado una versión básica del juego anterior!

Eche un vistazo (puede que necesite volver a cargar la página):


Características adicionales y pulido

Fondo Espacial

Tal vez también te gustaría un fondo con una imagen incrustada y estrellas. Agregue esto a su clase Main:

1
[Embed(source = "/../lib/SpaceBackground.jpg")]	//embed

2
		private var backgroundImage:Class; //This line must come immediately after the embed

3
4
		private var bgImage:Bitmap = new backgroundImage();		
5
		private var numOfStars:int = 70;

Ahora crea la clase Star:

1
package assets 
2
{
3
	import flash.display.MovieClip;
4
	import flash.events.Event;
5
6
	public class Star extends MovieClip
7
	{
8
		private var speed:Number;
9
		
10
		public function Star(alpha:Number, size:Number, speed1:Number) 
11
		{
12
			graphics.beginFill(0xCCCCCC);
13
			graphics.drawCircle(0, 0, size);
14
			
15
			speed = speed1;
16
		}
17
		
18
		// make sure you call this every frame

19
		private function moveDown():void
20
		{
21
			this.y += speed;
22
			
23
			if (this.y >= 600) {
24
				this.y = 0;
25
			}
26
		}
27
	}
28
}

En el constructor Main (), agregue esto para crear las estrellas:

1
2
for (var i:int = 0; i < numOfStars; i++) {
3
		createStars();
4
}

Aquí está la función real de createStars ():

1
2
private function createStars():void
3
{
4
	var star:Star = new Star(
5
		Math.random(), 
6
		Calculations.getRandomValue(1, 2), 
7
		Calculations.getRandomValue(2, 5)
8
	);  //random alpha, size and speed

9
			
10
	addChild(star);
11
			
12
	star.x = Calculations.getRandomValue(0, 550);
13
	star.y = Calculations.getRandomValue(0, 600);
14
}

Con alfa, tamaño, posición y velocidad aleatorios, se puede generar un fondo pseudo-3D.

Indicador de rango

Se puede crear un círculo indicador de rango simplemente creando otro círculo y agregándolo a la lista de visualización de la nave, al igual que la forma en que agregó el texto del indicador de potencia. Asegúrese de que el círculo esté centrado en la nave y tenga un radio igual al rango de empuje / tracción de la nave.

Agregue transparencia (valor alfa) al círculo con el siguiente código:

1
			graphics.beginFill(0xCCCCCC, 0.1);

Intente agregar controles adicionales que hacen que el rango aumente o disminuya cuando se presionan las teclas de flecha hacia arriba y hacia abajo.


Conclusión

¡Espero que disfrutes este tutorial! Por favor, deja tus comentarios.

Siguiente: ¡Lee esta crítica para obtener una guía para llevar Flux de una simple demostración a un juego completo!

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.