Usa Citrus para construir un simple juego de plataformas flash

¿Alguna vez has querido crear un juego de plataformas, pero no te gusta escribir todo el código desde cero? Citrus Engine no elimina el código por completo, pero lo hace mucho más simple, con muchas funciones útiles de juego 2D integradas. En este tutorial, lo usaremos para construir un juego de plataforma simple.


Paso 1: Breve descripción

En este tutorial usaremos un popular motor de juegos Flash, llamado Citrus, y una serie de clases de ActionScript para crear un juego de plataformas..


Paso 2: Configuración del documento Flash

Abre Flash y crea un documento de 420x280px. Establecer la velocidad de fotogramas a 30 fps.


Paso 3: Interfaz

Usaremos estos grandes gráficos de píxeles de Guillaume Moreau. Puedes descargarlos desde opengameart.org.


Paso 4: Antecedentes

Para el fondo, cambie el color del escenario a # 99D9EA, o use la herramienta Rectángulo (R) para dibujar un rectángulo de ese color.


Paso 5: Alerta

Se mostrará una alerta cuando el jugador complete el nivel o muera; se mostrará un juego sobre el mensaje y la puntuación. Utilizar el Herramienta rectangular para crearlo y establecer su nombre de instancia en AlertView. marca el Exportar para ActionScript caja y darle el mismo nombre de clase.

Hay muchos otros objetos en el juego (por ejemplo: una pantalla de título, los distintos símbolos para cada sprite, el terreno). En lugar de explicar cómo crearlos aquí, le sugiero que descargue los archivos de origen y observe qué objetos hay en la Biblioteca de la FLA. Puedes usar los mismos símbolos en tu propio juego o crear otros nuevos!


Paso 6: Incrustar Fuente

Usaremos una fuente de mapa de bits en el juego; Como vamos a utilizar la fuente dinámicamente, necesitaremos incrustarla en la aplicación. Estoy usando las fuentes 04b11 y Arcade Classic.

Seleccione un campo de texto dinámico con la fuente de su preferencia y haga clic en Empotrar… botón en el Panel de propiedades.

Seleccione / agregue todos los caracteres necesarios y haga clic en DE ACUERDO.


Paso 7: Sonidos

Usaremos efectos de sonido para mejorar la sensación del juego. Los sonidos utilizados en este ejemplo se generaron utilizando as3sfxr y se incluyen en los archivos de origen.


Paso 8: 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 9: Motor Citrus

Usaremos el Motor Citrus para potenciar nuestro juego..

¿Qué es el motor cítrico? Aprenda más de su sitio web:

The Citrus Engine es un motor de juegos Flash escalable de nivel profesional creado para juegos de calidad industrial. Se basa en las prácticas modernas de programación de Flash, lo que le permite centrarse en hacer que su juego sea increíble. Viene incorporado con un kit de inicio para "juegos de plataformas", que puede usar para hacer juegos de desplazamiento lateral en 2D increíbles..


Paso 10: Configurar el motor de cítricos

Vaya a la página de descarga y obtenga los archivos necesarios. Abre Preferencias de Flash, selecciona ActionScript De la lista de la izquierda y haga clic en Configuraciones de ActionScript 3.0 ... , a continuación, agregue la ruta a las fuentes como se muestra en la imagen de arriba.


Paso 11: Establecer clase de documento

Haremos que nuestra aplicación sea interactiva utilizando una clase externa. Añada su nombre (Principal) al Clase campo en el Publicar sección de la Propiedades Panel para asociar la FLA con la clase de documento principal..


Paso 12: Crear una nueva clase de ActionScript

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


Paso 13: Estructura de la clase

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

 package public class Main public function Main (): void // código de constructor

Paso 14: Main.as

los Principal La clase preparará el Motor Citrus para manejar el primer nivel..

 package import com.citrusengine.core.CitrusEngine; La clase final pública Principal extiende CitrusEngine función final pública Principal (): void super (); estado = nuevo nivel (); 

Esta clase extiende la clase CitrusEngine y establece el "estado" del juego en Nivel, que es el nombre de la clase que contendrá todo el comportamiento de nuestro juego.


Paso 15: Nivel.as

La clase estatal es una de las clases principales de Citrus Engine, y debes extender esta clase para crear la lógica del juego de tus niveles o estados. En este ejemplo el Nivel clase se extiende Estado para crear el primer nivel del juego.

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


Paso 16: Clases Requeridas

Estas son las clases que necesitaremos importar para nuestra Nivel clase para trabajar los importar La directiva hace que las clases y los paquetes definidos externamente estén disponibles para su código..

 importar flash.display.MovieClip; importar flash.display.Sprite; import flash.events.MouseEvent; import com.citrusengine.core.CitrusEngine; importar com.citrusengine.core.State; import com.citrusengine.physics.Box2D; import com.citrusengine.objects.platformer. *; import com.citrusengine.objects. *; import com.citrusengine.math.MathVector; import flash.events.Event; import flash.geom.Rectangle; importar flash.ui.Keyboard; import flash.events.KeyboardEvent; importar flash.text.TextField; importar flash.text.TextFormat; import com.greensock.TweenNano; import com.greensock.easing.Expo; importar flash.net.navigateToURL; importar flash.net.URLRequest; importar flash.filters.GlowFilter; importar flash.filters.BitmapFilter;

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 hay comentarios).

 private var levelView: LevelView = new LevelView (); // sprite de la biblioteca private var hero: Hero; corazones privados var: vector. = nuevo vector.(); private var tf: TextFormat = new TextFormat ('ArcadeClassic', 17, 0xFFFFFF, null, null, null, null, null, 'right'); private var scoreTF: TextField = new TextField (); private var gemSnd: GemSnd = new GemSnd (); // Snd = Sonido privado var goalSnd: GoalSnd = new GoalSnd (); private var hitSnd: HitSnd = new HitSnd (); private var jumpSnd: JumpSnd = new JumpSnd (); private var loseSnd: LoseSnd = new LoseSnd (); private var baddySnd: BaddySnd = new BaddySnd ();

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, se carga una vez que el juego comienza si parte de la clase de documento.

Se llama a las funciones necesarias para iniciar el juego. Comprueba esas funciones en los siguientes pasos..

 Función final pública Nivel (): nula // Código

Paso 19: Pausa el juego

Comenzaremos haciendo una pausa en el juego; esto evitará que el motor agregue los gráficos mientras el sprite de vista de nivel está en el escenario.

 Función final pública Nivel (): void super (); // código de configuración predeterminado CitrusEngine.getInstance (). playing = false; // realmente pausa el juego

Paso 20: Añadir vista de nivel

Esto agregará el sprite de Vista de Nivel al escenario, así como un detector de ratón para eliminarlo.

 anular la función pública initialize (): void / * Level Start View * / addChild (levelView); levelView.addEventListener (MouseEvent.MOUSE_UP, startLevel); 

Paso 21: Nivel de Inicio

La siguiente función se ejecuta cuando se hace clic en la Vista de nivel, y manejará la lógica para iniciar el juego.

 función final privada startLevel (e: MouseEvent): void 

Paso 22: Eliminar la vista de nivel

Este código destruye la instancia de Level View.

 levelView.removeEventListener (MouseEvent.MOUSE_UP, startLevel); removeChild (levelView); levelView = nulo;

Paso 23: Iniciar GameState (No pausa)

Ahora desatamos el juego e iniciamos el nivel..

 super.initialize (); CitrusEngine.getInstance (). Playing = true;

Paso 24: Iniciar Box2D

El siguiente código inicia el motor Box2D que maneja la física de Citrus Engine.

 var box2D: Box2D = nuevo Box2D ('Box2d'); añadir (box2D); //box2D.visible = true; // descomentar para ver los gráficos de depuración de Box2D

Paso 25: Añadir objetos gráficos

Estas líneas crearán todo el nivel, lea el código para comprender el sistema de creación de instancias de Citrus Engine (¡que es realmente fácil!).

(Todos ver Las propiedades son los nombres de clase de los símbolos de la biblioteca FLA: Bg, TerrainPart1, WaterX3, etc.)

 var leftWall: Platform = new Platform ('LeftWall', width: 1, height: 280, x: 0, y: 110); agregar (leftWall); var rightWall: Platform = new Platform ('RightWall', width: 1, height: 280, x: 726, y: 100); añadir (rightWall); var bg: CitrusSprite = nuevo CitrusSprite ('Bg', vista: Bg, x: 0, y: 20); añadir (bg); var terrain1: Platform = new Platform ('Terrain1', width: 422, height: 32, x: 211, y: 264, view: TerrainPart1); añadir (terreno1); var oneWay1: Platform = new Platform ('OneWay1', width: 92, height: 32, x: 184, y: 232, oneWay: true, view: OneWay1); agregar (oneWay1); var gema: Moneda = moneda nueva ('Gema', ancho: 11, altura: 10, x: 186, y: 136, vista: gema); añadir (gema); var agua: Sensor = nuevo Sensor ('Agua', ancho: 92, altura: 32, x: 468, y: 264, vista: WaterX3); añadir (agua); var terrain2: Platform = new Platform ('Terrain2', width: 214, height: 32, x: 621, y: 264, view: TerrainPart2); añadir (terreno2); var baddy: Baddy = new Baddy ('Baddy', x: 300, y: 200, leftBound: 250, rightBound: 350, view: Enemy); añadir (baddy); var movingPlatform: MovingPlatform = new MovingPlatform ('MP', width: 32, height: 8, x: 436, y: 232, startX: 436, startY: 232, endX: 500, endY: 232, view: PlatformClip, speed : 0.9); añadir (movingPlatform); var oneWay2: Platform = new Platform ('OneWay2', width: 127, height: 32, x: 663, y: 232, oneWay: true, view: OneWay2); agregar (oneWay2); var oneWay3: Platform = new Platform ('OneWay3', width: 64, height: 32, x: 695, y: 200, oneWay: true, view: OneWay3); agregar (oneWay3); var puerta: Sensor = nuevo Sensor ('Puerta', ancho: 20, altura: 28, x: 695, y: 202, vista: Puerta); añadir (puerta); hero = new Hero ('Hero', x: 30, y: 234, ancho: 19, altura: 26, vista: HeroClip, salto Altura: 9, maxVelocity: 2, hurtVelocityX: 2); añadir (héroe);

Como puede ver, en cada caso, crea una instancia del tipo de objeto que desea y utiliza los parámetros para especificar su posición, tamaño, gráfico o aspecto (esta es la ver parámetro) y otros elementos útiles. Luego lo agregamos a la etapa Citrus usando el añadir() método.

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

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é puede estar causando eso. (Y tenga en cuenta que algunas líneas se deben comentar, ya que algunas funciones aún no se han creado).


Paso 26: Añadir señales

Citrus Engine usa señales para manejar la interacción de tipo de evento. Puedes aprender más sobre las señales en este tutorial de Activetuts +.

 gem.onBeginContact.addOnce (función (e: *) gemSnd.play (); scoreTF.text = String (int (scoreTF.text) + 50);); door.onBeginContact.addOnce (levelComplete); hero.onTakeDamage.add (hurtHero); hero.onGiveDamage.addOnce (killBaddy); hero.onJump.add (function () jumpSnd.play ()); hero.onGiveDamage.addOnce (function () baddySnd.play ());

Paso 27: Stop Hero Animation

Nuestro Hero MovieClip se reproducirá de forma predeterminada a menos que lo impidamos. Este código se encarga de eso, y también aprenderá cómo acceder al MovieClip que sirve como arte para su objeto Citrus.

 this.view.getArt (hero) .content.stop (); //State(Level).SpriteView.SpriteArt.MovieClip.stop gameListeners (); addIndicators ();

Paso 28: Oyentes del juego

Este código agrega a los oyentes EnterFrame y al teclado que se utilizarán en nuestro juego. Puedes leer acerca de las funciones de controlador correspondientes en los siguientes pasos.

 función final privada gameListeners (action: String = 'add'): void if (action == 'add') stage.addEventListener (Event.ENTER_FRAME, gameLogic); stage.addEventListener (KeyboardEvent.KEY_DOWN, animateWalk); stage.addEventListener (KeyboardEvent.KEY_UP, stopWalk);  else stage.removeEventListener (Event.ENTER_FRAME, gameLogic); stage.removeEventListener (KeyboardEvent.KEY_DOWN, animateWalk); stage.removeEventListener (KeyboardEvent.KEY_UP, stopWalk); 

Paso 29: Añadir Corazones

Los corazones representarán la salud de nuestro héroe. El siguiente código agrega tres corazones al escenario y los almacena en un Vector para usarlos más adelante fuera de esta función.

 función final privada addIndicators (): void / * Hearts * / for (var i: int = 0; i < 3; i++)  var heart:Heart = new Heart(); heart.y = 5; heart.x = 5 + (i * heart.width); addChild(heart); hearts.push(heart); 

Paso 30: Añadir puntuación

El ScoreFieldField es creado por este código. Usamos filtros para agregar el trazo negro alrededor de las letras..

 / * Puntuación * / puntuaciónTF.x = 320; scoreTF.defaultTextFormat = tf; scoreTF.text = '0'; filtro var: BitmapFilter = nuevo GlowFilter (0, 1, 2, 2); var filter2: BitmapFilter = nuevo GlowFilter (0, 1, 1, 1); scoreTF.filters = [filter, filter2]; addChild (scoreTF); 

Paso 31: Manejar la cámara

Aquí configuramos la cámara, que seguirá a nuestro héroe si su posición está más allá del centro X del escenario..

 función final privada gameLogic (e: Event): void / * Handle Camera * / if (hero.x> = stage.stageWidth * 0.5) view.setupCamera (hero, new MathVector (stage.stageWidth * 0.5, 234), nuevo Rectángulo (0, 0, 726, 228), nulo); 

Paso 32: comprobar el otoño

Este código verifica si nuestro héroe ha caído al agua, y si es así, reproduce el sonido de pérdida y emite una alerta.

 / * Comprueba si el héroe cayó * / if (hero.y> stage.stageHeight) loseSnd.play (); alerta ('perder'); 

Paso 33: Animate Hero Walk

Nuestra animación de caminar héroe comienza cuando se presionan las teclas de flecha izquierda o derecha.

 función final privada animateWalk (e: KeyboardEvent): void if (e.keyCode == 37 || e.keyCode == 39) this.view.getArt (hero) .content.play (); 

Paso 34: Animación Stop Walk

Cuando se sueltan las teclas se detiene la animación..

 función final privada stopWalk (e: KeyboardEvent): void if (e.keyCode == 37 || e.keyCode == 39) this.view.getArt (hero) .content.gotoAndStop (1); 

Paremos aquí para hacer otra prueba y comprobar que nuestro código de juego funciona:

Recuerde nuevamente que algunas líneas se han comentado ya que no todas las funciones se han creado aún..

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 el origen para ver qué podría estar causando que.


Paso 35: Hurt Hero

El héroe debería recibir daño si el enemigo lo toca; Las siguientes líneas eliminan un corazón y reproducen el sonido herido. Se llama alerta cuando el héroe está fuera de salud..

 función final privada hurtHero (): void removeChild (hearts [hearts.length-1]); corazones.splice (corazones.longitud-1, 1); hitSnd.play (); if (hearts.length <= 0)  loseSnd.play(); alert('lose');  

Paso 36: Matar a Baddy

Puedes matar a un enemigo saltando sobre él. Cuando esto sucede, la puntuación aumenta..

 función final privada killBaddy (): void scoreTF.text = String (int (scoreTF.text) + 100); 

Paso 37: Nivel Completo

El nivel termina cuando el héroe llega a la puerta. Se reproducirá un sonido y se llamará una alerta; Puedes ver el código de alerta en el siguiente paso..

 nivel final de función privada Completa (e: *): void goalSnd.play (); alerta(); 

Paso 38: Alerta

Esta función detendrá el juego y mostrará el mensaje por encima del juego, y también agrega un detector de mouse para reiniciar el juego cuando se hace clic..

 alerta de la función final privada (gameState: String = 'win'): void gameListeners ('rmv'); CitrusEngine.getInstance (). Playing = false; this.view.getArt (hero) .content.gotoAndStop (1); alerta de var: AlertView = new AlertView (); alert.x = stage.stageWidth * 0.5; alert.y = stage.stageHeight * 0.5; alert.scoreTF.text = scoreTF.text; alert.addEventListener (MouseEvent.MOUSE_UP, reinicio); if (gameState == 'lose') alert.titleTF.text = 'Level Failed!';  addChild (alerta); TweenNano.from (alerta, 0.6, scaleX: 0.2, scaleY: 0.2, facilidad: Expo.easeOut); 

Paso 39: Reiniciar

Este código volverá a cargar el SWF cuando se haga clic en el mensaje sobre el juego, restaurando todos los valores iniciales y volviendo a la pantalla inicial.

 reinicio privado de la función final (e: MouseEvent): void navigationToURL (nueva URLRequest (stage.loaderInfo.url), '_level0'); 

Paso 40: Prueba Final

Ahora estamos listos para hacer una prueba final de nuestro juego y comprobar que todo funciona como se espera.


Conclusión

Experimenta con este potente motor de juego y crea tus propios juegos.!

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