Peralta Rodrigo
8 de julio de 2014
ndice
1. Qu es y cmo se hace un videojuego?
1.1.
Qu es un videojuego? . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.
1.3.
Gneros y Clones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.3.1.
Gneros
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.3.2.
Clones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.4.
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.5.
Plataformas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
1.6.
1.7.
1.5.1.
Interfaz
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
1.5.2.
Recursos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
13
1.6.1.
Diseador
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
1.6.2.
Artista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
1.6.3.
Programador
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
1.6.4.
Msico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
1.6.5.
Sonidista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
1.6.6.
Guionista
14
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Herramientas disponibles . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
1.7.1.
Lenguaje de programacin . . . . . . . . . . . . . . . . . . . . . . .
15
1.7.2.
Libreras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
1.7.3.
Frameworks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
1.7.4.
Creadores de juegos . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
1.7.5.
Motores
16
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2. Aprendiendo Haxeixel
17
2.1.
. . . . . . . . . . . . . . . . . . .
2.2.
Qu es Haxe? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
2.3.
Instalacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
2.4.
Eligiendo un IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
17
19
Syntax Bsico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
3.1.1.
. . . . . . . . . . . . . . . . . . . . . . . . .
19
3.1.2.
19
3.1.3.
Bloques
19
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.
Declaracin de variables
3.3.
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
21
3.4.
21
3.5.
If . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
3.6.
Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
3.7.
While
22
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
3.8.
For . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
3.9.
Break y Continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
3.10. Return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
24
25
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
3.14. Tipado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
25
25
3.15. Herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
27
28
. . . . . . . . . . . . . .
29
29
. . . . . . . . . . . . . . . . .
29
. . . . . . . . . . . . . . . . . . .
30
4. Arquitectura de un videojuego
4.1.
Game Loop
31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.1.
. . . . . . . . . . . . . . . . . . . . . .
4.1.2.
31
32
. . . . . . . . . . . . . . . . . . . . .
34
4.2.
35
4.3.
Eventos
35
4.4.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1.
Event Dispatcher
4.3.2.
Event Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
4.3.3.
. . . . . . . . . . . . . . . . . . . .
36
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
Estados de Juego
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
39
5.1.
39
5.2.
39
. . . . . . . . . . . . . . . . . . . . . . . .
6. Proyectos en Haxeixel
41
7. BreakOut
7.1.
7.2.
7.3.
Main.hx . . .
La clase Playstate.hx
La clase
42
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
7.2.1.
Atributos
7.2.2.
Mtodo Create
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
7.2.3.
Mtodo Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
7.2.4.
Funciones Callback . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
Tarea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
8. Imgenes y Animaciones
48
8.1.
. . . . . . . . . . . . . . . . . . . . . . . . . .
48
8.2.
Animaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
8.2.1.
50
Comportamientos . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Loading
9.1.1.
9.2.
51
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La clase: FlxAsyncLoop
. . . . . . . . . . . . . . . . . . . . . . . .
51
52
52
9.2.1.
La Clase Main.hx . . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
9.2.2.
La clase MenuState . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
9.3.
. . . . . . . . . . . . . . . . . . . . . .
55
9.4.
Prctico: FlxInvaders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
9.4.1.
Diagrama de clases . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
9.4.2.
La clase Main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
9.4.3.
La clase PlayState
. . . . . . . . . . . . . . . . . . . . . . . . . . .
57
9.4.4.
La clase Alien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
9.4.5.
La clase PlayerShip . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
9.5.
Tarea: FlxInvaders
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.Sonidos y Msica
63
64
64
65
65
66
. . . . . . . . . . . . . . . . . . . . . . .
66
67
. . . . . . . . . . . . . . . . . . . . . . .
11.Guardando Datos
11.1. La clase: FlxSave
68
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68
69
70
. . . . . . . . . . . . . . . . . . . . . . . . . .
12.Cmaras y ScaleModes
71
12.1. Qu es la cmara? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
71
72
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
72
73
74
. . . . . . . . . . . . . . . . . .
13.Funcionalidad Avanzada
13.1. Pixel Perfect Collision
75
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
. . . . . . . . . . . . . . . . . . . . . . . . .
75
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
13.2.2. TweenOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
13.2.3. FlxGlitchSprite
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
13.2.4. FlxWaveSprite
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
13.2.5. FlxSpriteFilters . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
14.Tiles
83
. . . . . . . . . . . . . . . . . . . . . . . .
84
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
. . . . . . . . . . . . . . . . . . . . . . . . . . .
86
15.Comunidad
15.1. Comercializacin
84
88
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
15.1.1. Publicidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
15.1.2. Sponsors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
90
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
90
16.Game Jams
91
91
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
91
91
92
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
92
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
93
A los Lectores
Agradezco al analista en computacin Rodrigo Peralta, quien merece los crditos por
este trabajo. Estuvo a mi cargo la redaccin e indizacin del curso Videojuegos en 2D,
dictado por la Fundasoft en Fa.M.A.F, con el n de sistematizar lo expuesto por este gran
maestro.
Para entender la totalidad del apunte, es necesario tener algn conocimiento previo de
Programacin Orientada a Objetos (POO).
Los usuarios seguramente pueden encontrar online una mejor y ms completa gua
para empezar a programar videojuegos con Haxeixel, pero este apunte incluir no slo
desarrollo tcnico de la herramienta/framework sino una gran cantidad de referencias
y conocimientos de gente que ya estuvo desarrollando videojuegos, (de ac en adelante
simplemente juegos).
Lo que realmente aprecio del apunte es que est escrito con la misma losofa del
curso, a su vez voy a dar mi mejor esfuerzo para la elaboracin de tutoriales detallados,
didcticos, con ejemplos y referencias.
Espero que realmente disfruten leyendo este apunte tanto como yo lo hice asistiendo
al curso y no tengan dudas en contactarse conmigo al mail:
illbelemaxi@gmail.com por
El desarrollo de videojuegos combina muchos campos diferentes como ser edicin grca, composicin musical, guionistas y desarrolladores de software. Es un campo con
mucho potencial y desde sus inicios involucra una fuerte interaccin entre personas de
distintos mbitos, es decir, es un trabajo con una fuerte
e intentando hacer todo, dando el paso inicial con el desarrollo de juegos, hacia el difcil
camino del
trabajo en equipo1 .
Este curso trata de explicar cmo desarrollar videojuegos, as que para empezar vamos
a hablar de qu es un videojuego.
1.1. Qu es un videojuego?
Denir precisamente el concepto videojuego requiere hablar dentro de un marco terico
complejo, el cual no es el prposito de este curso, pero s intentar llegar a resumir una
nocin simple que nos sirva como desarrolladores.
Los videojuegos
son arte ya que permiten a sus creadores expresar sus ideas o puntos
Angry Birds por ejemplo es un juego muy exitoso que se trata de tirar pjaros
para derrumbar estructuras con chanchos, no hay un mensaje muy claro ah.
Pero, tambin tenemos juegos como
de un empleado de aduana que tiene que juntar suciente plata cada da para que su
pblicos
videojuegos son la vista, el tacto y el odio , pero eso se debe solamente a limitaciones
tecnolgicas. Algn da quizs existan aparatos que nos simulen olores, sabores y
sensaciones en la piel. Imagnense los juegos de terror que se podrn hacer con esa
tecnologa. Slenderman un poroto al lado de eso. Mapas, niveles, menes, msica de
fondo, animaciones, todo se reduce a imgenes y sonidos. El texto puede ser visto
3 Error chistoso!
4 R.P: podramos discutir si es as pero no lo vamos a hacer.
Para hacer eso usamos de imgenes que vamos intercambiando a cierta frecuencia
creando frames consecutivos y vamos cambiando de posicin el dibujo para simular
que nuestro personaje camina.
5 http://www.kongregate.com/games/icylime/multitask
Parecen pocas cosas, pero las posibilidades de juegos son innitas. El nico
lmite es nuestra imaginacin. Actualmente las maneras de utilizar la interfaz son
muchsimas, y con el tiempo a medida que emerjan nuevas tecnologas existirn an
10
Dos juegos pertenecen al mismo gnero cuando, independiente de sus interfaces o recursos, tienen reglas de interaccin similares. Si cambiamos las reglas
de interaccin drsticamente es probable que los juegos pertenezcan a gneros distintos.
Ejemplos de gneros:
Juegos de plataforma: Mario, Sonic y Castlevania.
Beat them up: Streets of Rage, Golden Axe y Cadillacs and Dinosaurs.
Simuladores: Sim City, Sims y Transport Tycoon.
Recuerdan cuando dijimos antes que los distintos tipos de videojuegos que existen
son innitos. Por esa misma razn la cantidad de
innitos. A medida que se crean juegos nuevos van apareciendo gneros que los denen.
Un ejemplo de un gnero nuevo que recin surgi este ao es el Procedural Death
Games, sus referentes son: Binding of Isacc, Spelunky y Rogues Legacy.
1.3.2. Clones
Un juego es un clon de otro juego cuando tiene prcticamente las mismas
reglas de interaccin pero usa recursos distintos.
Es muy comn que cuando un juego se hace popular, en pocos das aparecen una
gran cantidad de clones que tratan de llevarse un poco de ese xito y sacarle ganancia
monetaria. Igual, no es siempre el caso, a veces alguien hace un clon para honrar un juego,
como sera el caso de SuperTux que es un clon de Mario totalmente gratuito y open source.
11
ser simplemente nuevas versiones de otro juego o que se basen en sus reglas de interaccin
con una sutil diferencia. Un gran ejemplo de esto es 2048 que est basado en Threes pero
tiene algunos cambios , como desplazar hasta la la o columna mxima posible mientras
que Thress, lo hace en una sola la o columna por vez.
1.5. Plataformas
Una plataforma es el dispositivo electrnico sobre el cual corre el juego. Ejemplos de
plataformas incluyen PC, Xbox, PlayStation, Gameboy, etc.
1.5.1. Interfaz
Cada plataforma tiene uno o ms perifricos de entrada asociados a ella. La PC tiene
teclado y mouse. Las consolas tienen joysticks distintos entre s. Los celulares inteligentes
tienen una pantalla tctil.
Los perifricos de entrada asociados a una plataforma determinan qu interfaz puede tener nuestro juego. No podemos hacer un juego que use un mouse para
la Xbox.
Si recuerdan la interfaz es parte de lo que dene a un juego. Analizando Call of Duty,
observamos cmo cambia la jugabilidad mediante la utilizacin de distintas plataformas
1.5.2. Recursos
Cada plataforma tiene distintas especicaciones de hardware que afectan a los recursos
que podemos utilizar en nuestros juegos.
La memoria no voltil de una plataforma determina la cantidad de recursos totales
puede haber en nuestro juego.
La memoria voltil de una plataforma determina la cantidad de recursos que puede
haber en un instante dado del juego.
La velocidad de procesamiento de una plataforma determina a qu velocidad mxima
podemos realizar cambios sobre nuestros recursos (FPS).
Los juegos viejos tienen poca resolucin, podemos ver los pxeles. Los sonidos y la
msica eran de 8 bits. Mientras que los juegos modernos tienen resoluciones altsimas,
efectos impresionantes y en el caso de algunos juegos la msica fue hecha por una orquesta.
juegos que se pueden hacer usando cualquiera de estas tecnologas disponibles siguen
siendo prcticamente innitos.
6 R.P: Estos cambios hacen que 2048 sea un juego muchsimo mejor que Threes.
7 R.P: A mi me divierte jugar Call of Duty en PC pero odio jugarlo en consola.
12
1.6.1. Diseador
Es la persona encargada de describir ya sea en palabras o con algn tipo de modelo
el juego que se va a hacer. El diseador dene la interfaz, los recursos, y las reglas de
interaccin. En otras palabras, el diseador dene el juego. El diseo es considerada la
parte ms importante del juego ya que normalmente determina si un juego es entretenido
o no.
1.6.2. Artista
El artista se encarga dibujar todas las imgenes y animaciones que se van a usar en el
juego, es uno de los que se encarga de darle forma a los recursos del juego. Personajes,
fondos, mens, botones y hasta puede tener que crear la tipografa para el juego.
El arte inuye muchsimo en el juego, un juego de terror no puede tener zombies que
parezcan osos de peluche que hacen sonreir a un beb. Ni un juego para nios puede tener
monstruos con colmillos que derraman sangre de su boca.
13
1.6.3. Programador
El programador es el que se encarga de implementar las reglas de interaccin para que
acten de la manera en que el juego fue diseado. Es un rol con muchsima importancia,
si el trabajo del programador no est bien hecho el juego puede terminar con bugs que
pueden causar una reaccin muy negativa en el pblico. Imaginen estar jugando un juego
por dos horas y que tir un error se cierre y no haya guardado ningn dato y tengan que
empezar de vuelta .
Lamentablemente,
a sus ojos y odos. Un jugador puede apreciar el diseo de un juego, un jugador puede
apreciar el arte de un videojuego, puede apreciar la msica, pero una frase que nunca van
a escuchar es:
1.6.4. Msico
Es la persona que hace la msica, es uno de los que se encarga de darle forma a los
recursos del juego. Un juego sin msica puede volverse bastante aburrido. Al igual que
el arte, la msica es lo que le da la esencia del juego. Insisto un juego de horror tiene
que tener msica tenebrosa que te ponga los pelos de punta. No puede tener una cancin
cmica, salvo que sea un circo abandonado.
1.6.5. Sonidista
Es la persona que hace los sonidos que se utilizan en el juego, es uno de los que se
encarga de darle forma a los recursos del juego. Ruidos de botones, personaje corriendo,
montruos gruiendo, etc. A veces el sonidista y el msico son la misma persona, pero no
siempre. Al igual que el msico y el artista, los sonidos tienen que reejar la esencia del
juego. Sonidos graciosos en juegos graciosos, sonidos tenebrosos en juegos tenebrosos, etc.
1.6.6. Guionista
Es la persona que escribe la historia del juego, es uno de los que se encarga de darle
forma a los recursos del juego. Buenos juegos requieren buenas historias, ah es donde entra
el guionista. Si el diseo del juego es largo y montono, por ejemplo un tower defense,
la historia es la que hace que sea mucho ms entretenido. Al igual que los otros roles, la
historia tiene que integrar la esencia del juego.
8 I.M: estoy seguro que cualquiera de nosotros le dara una segunda oportunidad pero no
jueguen con nuestros lmites.
14
de contestar, por eso vamos a ver las distintas herramientas que hay disponibles para la
creacin de juegos.
1.7.2. Libreras
Las libreras nos proveen una interfaz a componentes de ms bajo nivel para simplicar el desarrollo del juego. Si quisiramos cargar una imagen en la placa de video de
nuestra computadora en C++, no sera una tarea nada simple. En vez de eso, SFML
(Simple Fast Media Library) nos permite cargar una imagen con una sola instruccin:
1.7.3. Frameworks
Un framework es una base sobre la cual uno construye su aplicacin. Tienen una serie
de libreras que proveen funcionamiento que si no usramos el framework tendramos que
implementar nosotros.
An con la librera queda mucho trabajo por hacer. Tenemos que disear una arquitectura para el juego y construir todas sus clases. El game loop, el sistema de estados,
los modos de escena, todas esto deber ser implementado en cada juego que hagamos.
1.7.5. Motores
Los motores se encuentran entre los frameworks y los creadores de juegos. En este
nivel todava hay programacin, la cantidad de cdigo que vemos depende del motor en
s. Algunos motores se parecen ms a un framework, algunos se parecen ms a un creador
de juegos. Tambin algunos motores suelen restringirte a crear ciertos gneros de juegos.
Ejemplos: Unity, UnrealEngine.
Al nal que herramienta me conviene? La que ms les guste.
En este curso vamos a usar el
esta eleccin. Pero recuerden que a su pblico, generalmente, no le interesa cmo fue
hecho su juego.
tratando de hacer cosas que ya estn hechas, y de una manera mejor. Cuando tienen que
usar un arreglo, nadie implementa el suyo, usa el de la librera estndar.
No digo que no est bueno meterse a veces ms profundo en el cdigo para ver cmo
funcionan ciertas cosas, eso est genial y a veces lo van a tener que hacer porque no queda
otra. Pero recuerden que nadie se va dar cuenta si su juego es un 1.5 % ms eciente en
memoria porque implementaron su propio algoritmo de bsqueda. Porque les puede pasar
que mientras ustedes estn peleando para cargar imgenes a la placa de video en C++
alguien puede estar vendiendo sus juegos hechos con Game Maker.
16
2. Aprendiendo Haxeixel
Si slo pudieras aprender un lenguaje de programacin, Haxe
sera ese lenguaje. Es universal. Es poderoso. Es fcil de usar.
haxe.org
Multiplataforma.
Con Haxeixel podemos hacer juegos para casi cualquier plataforma a veces sin tener
que cambiar una sola lnea de cdigo
2.
10 .
Open Source.
Unity y otros motores son multiplataforma, pero hay que pagar para usarlo pagos y
no son para nada open source. Unity Pro sale USD $1500. Game Maker Profesional
sale USD $ 800. Y sus versiones gratuitas son limitadas en algunos aspectos.
3.
4.
2.2. Qu es Haxe?
Haxe (pronunciado como Hex) es un lenguaje de programacin open source. Mientras
que otros lenguajes estn limitados a su propia plataforma (Java al JVM, C# a .Net,
ActionScript al Flash Player), Haxe es un lenguaje multiplataforma, a continuacin presentamos un listado de algunas plataformas a las que puedo compilar Haxe.
Javascript
Flash
NekoVM
PHP
C++
C#
Java
Android
Haxe es un lenguaje muy parecido a Javascript o ActionScript as que los que hayan
trabajado en esos lenguajes no van a tener muchos problemas adaptndose.
2.3. Instalacin
Hay un instalador automtico de Haxe para todos los sistemas operativos que se puede
descargar desde:
bajar y es, en mi opinin, excelente, open source y tambin sirve para OpenFL y Haxeixel.
Si estn en Linux o Mac, recomiendo que usen Sublime-Text. Para instalarlo recomiendo que lean lo siguiente:
http://haxeflixel.com/documentation/sublime-text/,
la
instalacin est en un repositorio GitHub, si se les complica mucho instalarlo y usan Lin-
12 .
11 R.P
12 R.P
18
Main
2 {
3
public
static
function main ( )
world " ) ;
7 }
true, false.
/[a-ZA-Z]+/.
Unknown<0>:
null.
&&, ||.
Bitwise: |, &, >>, <<, >>>.
Unarios: !, , ++, .
Operadores Booleanos:
Operadores
Operadores
3.1.3. Bloques
Los bloques son importantes en Haxe, herramienta til para simplicar algunas expresiones. Los bloques estn delimitados por llaves { }. Lo que los hace especial en Haxe es
19
Void.
static
function main ( )
Void
Void
2 {
3
var
s =
String ;
i f ( true ) {
else
trace ( s ) ;
10 }
static
function main ( )
2 {
3
var
i f ( true ) {
String ;
else
trace ( s ) ;
10 }
var.
una variable. Una es a nivel de clase, la otra es declarando variables locales en bloques de
cdigo.
1. A nivel de clase:
20
1 class
Main
2 {
3
public
var
5
6
static
function main ( )
myNumber
Int = 1 5 ;
7 }
Una variable puede ser declarada mltiples veces, en el mismo bloque o en bloques
distintos. La declaracin que se toma en cuenta es la ms cercana.
1 class
Main
2 {
3
public
static
function main ( )
var
myNumber = 2 ;
myNumber
Int = 1 5 ;
t r a c e ( myNumber ) ;
var
9
10
myNumber
// T r a c e s
Int = 1;
t r a c e ( myNumber ) ;
11
// T r a c e s
12
t r a c e ( myNumber ) ;
13
// T r a c e s
14 }
user.name
Para llamar una funcin lo nico que tens que hacer es poner parntesis despus del
nombre de la funcin y escribs tus argumentos dentro del parentsis, separados por comas.
As es como se llama una funcin llamada
sayHelloT o
de un objeto llamado
21
user.
var
user =
new
new:
User
2 {
p u b l i c function new ( t i t l e
3
4
//Do
String ,
name
String ) {
things
6 }
this.
3.5. If
1 i f ( age < 16) {
2
t r a c e ( "You
3 }
else
t r a c e ( "You
5 }
else
are
young " ) ;
almost
are
an
an
adult " ) ;
t r a c e ( "You
adult ") ;
7 }
var
age = 1 8 ;
2 trace (
i f ( a g e <18) {
3
4
"You
are
not
are
an
an
adult . " ;
} else {
5
6
"You
adult " ;
8 );
3.6. Switch
1 switch ( t i t l e ) {
case
2
3
"Mr" :
t r a c e ( "You
case
4
5
"Ms" ,
are
man" ) ;
t r a c e ( "You
are
a woman" ) ;
default :
6
7
trace ("I
don ' t
know
if
you
are
a man
or
a woman" ) ;
8 }
Si hay ms de un valor con el cual comparar debera ser separado por comas. Notar
que
3.7. While
Hay dos syntax posibles. El while loop normal:
1 while ( c o n d i t i o n ) {
2
exprToBeExecuted ;
3 }
Y el do while:
1 do {
2
exprToBeExecuted ;
3 } while ( c o n d i t i o n ) ;
Ejemplos:
1 while ( i < 1 8 ) {
2
trace ( i ) ;
i ++;
// W i l l
trace
numbers
from
to
17
included
// W i l l
trace
numbers
from
to
17
included
4 }
1 do {
2
trace ( i ) ;
i ++;
4 }
while ( i < 1 8 ) ;
3.8. For
Haxe tiene un loop de for que funciona sobre iteradores. Un iterador es un objeto que
soporta algunos mtodos denidos en el typedef del iterador. Tiene varios valores y los va
devolviendo uno por uno en cada llamada de la siguiente funcin.
Ejemplo:
1 for ( i
2
in
0...10){
trace ( i ) ;
//
Will
trace
numbers
from
to
3 }
Nota:
0 . . . 10
...
13 que devolver todos los int desde el primero (incluido) hasta el ltimo
un interador
(excluido).
Esta construccin es particularmente til para iterar sobre listas y arreglos.
Por ejemplo:
1 class
Te sth aXe
2 {
3
public
static
function main ( ) :
var
= new
Void
L i s t <S t r i n g >() ;
13 Error Chistoso!
23
for ( s
in
l ){
neko . Lib . p r i n t l n ( s ) ;
10
11
12 }
3.10. Return
La palabra clave
funcin (y salir).
24
class
User
2 {
3
var
p u b l i c function new ( )
sayHello
: String
Void ;
s a y H e l l o = function ( t o
};
String )
10 }
Las funciones locales pueden acceder a cualquier variable local declarada en el mismo
alcance que las variables estticas pero
cpp
//C++ c o d e
#if
3 #elseif neko
4
// Neko
code
5 #elseif php
6
//PHP
code
7 #e l s e
8
// Code
for
other
targets
9 #end
3.14. Tipado
3.14.1. Variables explcitamente tipadas
Variables son explcitamente tipadas si vos escribs su tipo al declararlas. Esto es lo
que hemos visto hasta ahora y se hace de la siguiente manera:
25
redeclarar
una variable con el mismo nombre y otro tipo. As que el siguiente cdigo
compila:
1 class
Main
2 {
public
static
function main ( )
var
var
e = 12;
e
e
:
:
String ;
Int ;
9 }
Aunque este cdigo compile, uno no debera estar haciendo esto porque puede ser
confuso a otros desarolladores o hasta a vos mismo si tens que leer tu cdigo varios das
despus
14 .
Por lo tanto, para mantener las cosas simples, una vez que una variable es tipada, su
tipo no se puede cambiar y slo se pueden asignar valores de ese tipo. As que lo siguiente
no funcionara:
1 class
Main
2 {
3
public
static
function main ( )
var
String ;
e = 12;
9 }
3.15. Herencia
En Haxe, una clase puede extender a otra clase. En tal caso, tiene todos los campos
de sus clases padres y tiene todos los tipos que tienen sus clases padres (ms su propio
tipo). Lo que eso signica, por ejemplo, es: cuando una funcin quiere un parmetro de
tipo A, si B extiende A, vos pods pasar una instancia de B a tu funcin. Esto se ve en
el siguiente cdigo:
1 class
Main
2 {
3
public
static
function main ( ) {
var
HumanBeing ;
c o n g r a t u l a t e ( human ) ;
public
9
10
human
static
function
t r a c e ( " Congrats
congratulate ( l t
" +
LivingThing )
l t . name ) ;
14 I.M: Por eso los programadores de Videojuegos lo hacen en las Game Jam en 24Hs.
26
11 }
12
13 c l a s s
LivingThing
14 {
var
15
public
16
p u b l i c function new ( )
17
name
String ;
{
18
19 }
20
21 c l a s s
HumanBeing extends
LivingThing
22 {
23
24
25
super () ;
26
t h i s . name = name ;
27
String )
28 }
function
outputString ( st
String )
Void ;
String
y devuelve
Void, esto signica que no devuelve ningn objeto. El tipo de la funcin se representa de
la siguiente manera:
String V oid
Otro ejemplo, la funcin:
List.f ilter.
27
Voy a simplicar las cosas un poco diciendo que este mtodo, que toma una una lista de
String podra ser declarado de la siguiente manera:
var
s;
2 s = " Hello
World " ;
String.
2. Asignando el valor de una variable a otra: si asigns a una variable que tiene tipo
desconocido el valor de una variable con un tipo conocido, su tipo tambin ser
inferido:
1
2
var
var
s;
t
String ;
3 s = t ;
28
Main
2 {
static
3
4
function
print ( s
String )
trace ( s ) ;
public
var
8
9
static
function main ( )
t;
print ( t ) ;
10
type ( t ) ;
11
12 }
DynamicTest
2 {
public
static
function main ( )
var
dynamicVar = 1 2 3 ;
dynamicVar
Dynamic ;
lastName
10 }
29
1 class
DynamicTest
2 {
public
static
function main ( )
var
var
dynamicVar
year
Dynamic ;
Int ;
y e a r = dynamicVar ;
9 }
Entonces aunque asignemos un String a una variable tipada como Int, el compilador
no se quejar. Pero deberan tener en mente que esto es en tiempo de compilacin! Si
uno abusa esta posibilidad, uno puede terminar con
DynamicTest
2 {
public
static
function main ( )
var
dynamicVar = function
dynamicVar
Dynamic ;
( name
String )
};
dynamicVar ( ) ;
10 }
Como pueden ver, es posible asignar funciones a una variable Dynamic y despus es
posible llamarla al igual que cualquier funcin. Aunque este cdigo compile, su xito
corriendo depende de la plataforma objetivo.
30
4. Arquitectura de un videojuego
Its dangerous to go alone! take this!
Legend of Zelda.
ProcessInput () ;
Update ( ) ;
Render ( ) ;
5 }
ProcessInput()
Se encarga de responder al input del jugador, normalmente se maneja con eventos
que vamos a explicar ms adelante.
Update()
Despus de responder al input del jugador (o no si no hace nada), hay que actualizar
los objetos del juego. Esto puede involucrar mover imgenes de lugar, detectar y
manejar colisiones, es decir, toda la lgica de los objetos se maneja aqu.
Render()
Despus de actualizar los objetos de nuestro juego tenemos que renderizarlos. Si los
actualizamos y no los renderizamos, los objetos no van a cambiar de lugar en el
monitor.
Ejemplo
1. Supongamos que tenemos un personaje que est contra una pared.
2. El jugador aprieta la tecla para moverse en esa direccin.
3. El
handle input detecta esa tecla e incrementa la velocidad del personaje, pero no
31
4. El
update actualiza la posicin del objeto movindolo una cierta distancia de acuerdo
del objeto, hay una parte del cdigo que se encarga de las colisiones. Y esa parte
del cdigo, detecta que el personaje y la pared han colisionado, y entonces mueve al
jugador 5 pxeles fuera de la pared.
7. Ahora le toca a la funcin
8. Como el personaje qued al nal en el mismo lugar, parece que no pas nada. Pero
internamente cada vez que te chocas con una pared la ests atravezando y la lgica
te reposiciona.
screen tearing,
que es cuando vemos una lnea horizontal en la pantalla porque una parte del juego est
ms actualizada que otra.
32
Variaciones de FPS
Supongamos que queremos que nuestro personaje se mueva 60 pxeles por segundo.
Entonces nosotros le damos una velocidad de 1 pixel por frame.
A una frecuencia de 60 FPS el personaje se mueve 60 pxeles a la derecha en un segundo.
Ahora supongamos que sufrimos de lag, y nuestro juego corri a 24 FPS. Ahora nuestro
personaje se mueve 24 pxeles en un segundo. Pero nuestro personaje tena que moverse
60 pxeles en un segundo independientemente de los fps. Nuestro personaje no debera
moverse ms rpido o ms lento dependiendo de los FPS, su velocidad debera ser constante.
Solucin:
Vamos a tener que agregar un poco de cdigo a nuestro game loop para poder corregir
ambos problemas:
33
1 while ( mWindow . i s O p e n ( ) )
2 {
3
t i m e S i n c e L a s t U p d a t e += c l o c k . r e s t a r t ( ) ;
timeSinceLastUpdate
ProcessInput () ;
Update ( TimePerFrame ) ;
TimePerFrame ;
10
Render ( ) ;
11 }
La condicin
update()
tantas veces como haga falta para que todo est actualizado.
Noten que render est por fuera del loop, ya que no importa cuntos render hagamos
si los objetos no se cambiaron de posicin no habr screen tearing.
Noten que update ahora tiene un argumento de tiempo, esto es para que la velocidad
de los objetos sea la misma sin importar a cuntos FPS corre.
Consideremos de nuevo el ejemplo anterior que queramos que tuviera velocidad de 60
pxeles por segundo. Su funcin de update del objeto tendra una pinta as:
1 public
function u p d a t e ( )
2 {
t h i s . x += 1 ;
3
4 }
Ahora, esto slo andara a 60 pxeles por segundo, cuando el juego corre a 60 FPS. Para
hacerlo independiente de los FPS tenemos que tomar como argumento el TimePerFrame:
1 public
function u p d a t e ( TimePerFrame :
Float )
2 {
t h i s . x += 6 0 * TimePerFrame ;
3
4 }
F lxG.elapsed
34
processInput () ;
update ( ) ;
render () ;
5 }
render().
hacer es agregar los objetos que queremos que sean renderizados a lo que se llama el
DisplayList. Y todo lo que este en el DisplayList va a ser renderizado automticamente.
Para agregar algo al DisplayList se usa el mtodo
add():
processInput () ;
update ( ) ;
4 }
4.3. Eventos
Un evento es una accin u ocurrencia detectada, que puede o no ser manejada por el
programa. Su uso principal es para responder al input del usuario pero vamos a ver que
sirve para otros nes:
Ejemplos de Eventos:
35
escuche
por un tipo determinado de objeto y se le asigna una funcin callback que va a ser llamada
cuando el evento sea detectado.
Por ejemplo:
1
2
3
4 private
5
function m o u s e P r e s s e d
firing
( e v e n t : MouseEvent )
Void {
= true ;
6 }
7
8 private
9
function m o u s e R e l e a s e d
firing
( e v e n t : MouseEvent )
Void {
= false ;
10 }
( FlxG . k e y s . p r e s s e d .DOWN)
// h a g a
algo
3 }
Este tipo de cdigo ira dentro de nuestro bloque de update, eliminando en Flixel la
necesidad de procesar los inputs en un bloque separado.
Dejando nuestro game loop de la siguiente manera:
1 while ( mWindow . i s O p e n ( ) )
2
update ( ) ;
3 }
36
F lxG.switchState(newP layState());
Cada estado que creamos tiene que extender la clase FlxState. Mtodos de la clase
FlxState:
create()
add(object:
FlxSprite)
remove(object:
FlxSprite)
37
update()
destroy()
38
FlxSprite es la clase que vamos a utilizar para mostrar imgenes en nuestros juegos.
Normalmente vamos a extender esta clase para agregar nuestras propias variables,
como por ejemplo puntos de vida, nivel, ataque, defensa.
Hay que tener en cuenta que siempre que sobreescribamos una funcin hay que llamar
a la funcin super() sino vamos a tener errores importantes en el juego.
velocity.x.
oat.
oat.
width: determina el ancho del hitbox del sprite que por defecto es el ancho de la
imagen. El
height: determina la altura del hitbox del sprite que por defecto es la altura de la
imagen.
oset: controla la posicin del hitbox del sprite. Tambin una dupla con valores x e
y. Normalmente debe ser modicado despus de cambiar el ancho o alto del hitbox.
39
Para simplicarnos la vida, la clase FlxSprite tiene su propio mtodo update() que
actualmente.
Por defecto lo nico que hace el update() de un sprite es actualizar su posicin de
acuerdo a su velocidad y actualizar su velocidad de acuerdo a su aceleracin.
Pero nosotros podemos sobreescribir ese mtodo y agregar nuestra propia lgica, siempre y cuando nos acordemos de llamar al mtodo
40
super.update().
6. Proyectos en Haxeixel
Game Over
:p
41
7. BreakOut
If people were inuenced by video games, then the
majority of Facebook users would be farmers by now.
Anonymous
http://haxeflixel.com/demos/Breakout/.
https://github.com/HaxeFlixel/flixel-demos/tree/dev/Arcade%20Classics/
Breakout.
Cdigo:
//
Ancho
del
juego
en
pixels
Alto
del
juego
en
pixels
2 var
g a m e H e i g h t : Int = 2 4 0 ;
3 var
i n i t i a l S t a t e : Class<FlxState> = P l a y S t a t e ;
1;
//
se
//
acomode
5 var
f r a m e r a t e : Int = 6 0 ;
6 var
s k i p S p l a s h : Bool = f a l s e ;
// no
las
Estado
dimensiones
muestre
42
//
el
loguito
de
de
inicial .
pantalla
flixel .
7.2.1. Atributos
1 class
extends FlxState
PlayState
2 {
3
private
static
inline
var BAT_SPEED : I n t = 3 5 0 ;
4
5
p r i v a t e var
_ b a l l : FlxSprite ;
7
8
p r i v a t e var _ w a l l s : FlxGroup ;
p r i v a t e var
_ l e f t W a l l : FlxSprite ;
10
p r i v a t e var _ r i g h t W a l l : FlxSprite ;
11
12
13
14
p r i v a t e var
_ b r i c k s : FlxGroup ;
Funcin
de
inicializacin
agregamos
_walls
al
Esto
el
de
tema
estado ,
los
_bricks
de
todos
las
es
una
paredes
tambin
ladrillos
las
los
tcnica
los
recursos
las
incluimos
incluimos
utilizada
en
haxe
en
posteriori
en
el
el
grupo
grupo
para
simplificar
tema
de
colisiones
*/
override p u b l i c function
//
FlxG . mouse . v i s i b l e
Escondemos
el
c r e a t e ( ) : Void
Mouse
= false ;
7
8
// Cramos
_bat = new
el
bate
FlxSprite (180 ,
10
_bat . makeGraphic ( 4 0 ,
11
6,
220) ;
F l x C o l o r . HOT_PINK) ;
12
13
// Creamos
14
_ b a l l = new
15
_ b a l l . makeGraphic ( 6 ,
16
_ball . e l a s t i c i t y
17
18
_ball . v e l o c i t y . y = 200;
la
bola
FlxSprite (180 ,
6,
160) ;
F l x C o l o r . HOT_PINK) ;
= 1;
200) ;
19
20
// U t i l i z a r e m o s
el
grupo
walls
para
colisiones
21
_ w a l l s = new FlxGroup ( ) ;
43
simplificar
el
los
las
22
23
24
// P a r e d
25
_ l e f t W a l l = new
26
_ l e f t W a l l . makeGraphic ( 1 0 ,
Izquierda
FlxSprite (0 ,
0) ;
240 ,
27
_ l e f t W a l l . immovable = true ;
28
_ w a l l s . add ( _ l e f t W a l l ) ;
F l x C o l o r .GRAY) ;
29
30
// P a r e d
31
_ r i g h t W a l l = new
32
_ r i g h t W a l l . makeGraphic ( 1 0 ,
33
_ r i g h t W a l l . immovable = true ;
34
_ w a l l s . add ( _ r i g h t W a l l ) ;
Derecha
FlxSprite (310 ,
0) ;
240 ,
F l x C o l o r .GRAY) ;
35
36
// P a r e d
37
_topWall = new
38
_topWall . makeGraphic ( 3 2 0 ,
39
40
_ w a l l s . add ( _topWall ) ;
de
Arriba
= Techo
FlxSprite (0 ,
0) ;
10 ,
F l x C o l o r .GRAY) ;
41
42
// P a r e d
43
_bottomWall = new
44
_bottomWall . makeGraphic ( 3 2 0 ,
45
46
_ w a l l s . add ( _bottomWall ) ;
de
Abajo =
Piso
FlxSprite (0 ,
239) ;
10 ,
F l x C o l o r .TRANSPARENT) ;
47
48
//
49
_ b r i c k s = new FlxGroup ( ) ;
Some
bricks
creamos
los
ladrillos
bricks
rromper
50
51
var bx : Int = 1 0 ;
52
var by : Int = 3 0 ;
53
54
var
b r i c k C o l o u r s : Array<Int> = [ 0 x f f d 0 3 a d 1 ,
xfffd8014 ,
0 xffff9024 ,
0 xff05b320 ,
0 xfff75352 ,
0 xff6d65f6 ] ;
55
56
for
( y in
for
57
0...6){
( x in
0...20){
58
59
t e m p B r i c k . makeGraphic ( 1 5 ,
60
t e m p B r i c k . immovable = true ;
61
_ b r i c k s . add ( t e m p B r i c k ) ;
62
bx += 1 5 ;
63
64
bx = 1 0 ;
65
66
15 ,
by ) ;
brickColours [ y ] ) ;
by += 1 5 ;
}
67
68
//
Agregamos
al
estado
todos
69
70
add ( _ w a l l s ) ;
71
add ( _bat ) ;
44
los
sprites
que
creamos
72
add ( _ b a l l ) ;
73
add ( _ b r i c k s ) ;
74
super . update ( ) ;
En
cada
llamado
del
bate
clickeamos
esto
una
*/
_bat . v e l o c i t y . x = 0 ;
Unas
lneas
compilacin
trasladarse
*/
10
#if
para
update ,
que
deje
seteamos
de
dispositivos
condicional ) ,
movimiento
cdigo
de
para
la
moverse
velocidad
si
no
direccin
5
7
funcin
la
es
la
directamente
descendente
idea
de
donde
con
el
tctiles
( utilizando
movimiento
toc y
deto
si
del
hace
reseteamos
bate
es
un
el
estado .
!FLX_NO_TOUCH
for
11
( touch
if
12
in
FlxG . t o u c h e s . l i s t )
( touch . p r e s s e d ) {
if
13
14
_bat . x = t o u c h . x ;
15
16
17
for
18
( swipe
if
19
in
FlxG . s w i p e s ) {
if
20
21
||
10) | |
170) ) {
( der , b ) ,
si
FlxG . r e s e t S t a t e ( ) ;
22
23
24
25
#end
26
27
28 / *
29
La
idea
posteriori
ocurri un
30
31
direccin
*/
if
32
33
evento
con
el
es
valor
la
las
} else
if
teclas
velocidad ,
( izq , a)
del
36
//
Si
( FlxG . k e y s . a n y P r e s s e d ( [ "RIGHT" ,
apret
la
letra
en
esa
BAT_SPEED ;
"D" ] ) && _bat . x < 2 7 0 ) {
_bat . v e l o c i t y . x = BAT_SPEED ;
35
bate
bat_speed
( FlxG . k e y s . a n y P r e s s e d ( [ "LEFT" ,
_bat . v e l o c i t y . x =
34
escuchar
alteramos
reseteamos
45
el
Juego .
37
if
38
FlxG . r e s e t S t a t e ( ) ;
39
40
if
41
}
43
if
44
( _bat . x > 2 7 0 ) {
_bat . x = 2 7 0 ;
46
47
( _bat . x < 1 0 ) {
_bat . x = 1 0 ;
42
45
( FlxG . k e y s . j u s t R e l e a s e d . R) {
Finalmente
detectamos
las
colisiones
48
49
R ec or da mo s
que
sprites ,
est
50
En
el
funcin
51
En
52
*/
el
decir
definido
caso
de
funcin
la
es
por
las
de
callback
sus
el
las
utiliza
la
funcionamiento
colisin fsica
luego
del
entre
choque
entre
( ball ,
bricks
entre
( ball ,
bat )
se
define
colisiones
se
define
53
54
FlxG . c o l l i d e ( _ b a l l ,
55
FlxG . c o l l i d e ( _bat ,
56
FlxG . c o l l i d e ( _ b a l l ,
57
_walls ) ;
_ball ,
ping ) ;
_bricks ,
hit ) ;
3
4
h i t ( B a l l : FlxObject ,
= false ;
Brick . e x i s t s
}
5
6
p r i v a t e function
p i n g ( Bat : FlxObject ,
B a l l : FlxObject ) : Void
var
b a t m i d : I n t = S t d . i n t ( Bat . x ) + 2 0 ;
var
b a l l m i d : I n t = Std . i n t ( B a l l . x ) + 3 ;
10
var
d i f f : Int ;
11
12
if
( b a l l m i d < batmid )
13
//
14
diff
15
16
Ball
else
if
17
//
18
diff
19
20
is
on
= batmid
the
{
left
else
the
bat
10 *
diff ) ;
( b a l l m i d > batmid ) {
Ball
on
the
= ballmid
right
of
the
bat
batmid ;
Ball . v e l o c i t y . x = (10
}
of
ballmid ;
Ball . velocity . x = (
}
diff ) ;
21
//
22
// A
Ball
la
hit .
ping .
los
ya
atributos .
colisiones
callback
caso
collide ,
que
is
little
perfectly
random X
in
the
to
stop
46
middle
it
bouncing
up !
la
funcin
23
B a l l . v e l o c i t y . x = 2 + FlxRandom . i n t R a n g e d ( 0 ,
24
8) ;
25
26 }
7.3. Tarea
Como podrn haber visto todava le faltan ciertos features para decir que es un juego,
por esto se proponen las siguientes actividades.
1. Agregar al juego un sistema de vidas y por lo tanto que se pueda perder.
2. Inventar tu propio sistema de puntaje e implementarlo.
3. Corregir movimiento de bate, es decir si ahora se teclean las 2 teclas juntas (izquierda,
derecha), el juego responde slo a un input en el update.
4. Modicar el random de la funcin Ping cuando cae al medio, a gusto.
5. Agregar un estado GameOver.hx que muestre el puntaje cuando perds todas tus
vidas.
6. Agregar un Nivel.
47
8. Imgenes y Animaciones
Now is not the time to use that!
Profesor Oak.
Vimos cmo crear sprites a partir de guras geomtricas usando el mtodo MakeGraphic(). Explicaremos ahora cmo generar sprites animados a partir de un
Tambin veremos cmo se usa la tcnica
sprite sheet.
Int ,
? Height
Dynamic ,
:
:
Int ,
? Animated
? Unique
Bool ,
Bool ,
? Key
? Reverse
String )
:
:
Bool ,
FlxSprite
Para cargar una imagen no animada se usa slo el primer argumento al cual le pasamos
el path de la imagen que queremos cargar, por ejemplo:
1
var
_ship
2 _ s h i p = new
FlxSprite ;
FlxSprite (x , y) ;
8.2. Animaciones
Para cargar una animacin a un sprite, tambin usamos la funcin loadGraphic.
La diferencia es que vamos a necesitar lo que se llama un
48
Para ver una animacin en nuestro juego a partir de un sprite sheet, necesitamos
intercambiar la imagen que se ve en pantalla por la imagen que le sigue en el sprite sheet
hasta llegar a la ltima y volver a repetir la animacin si hace falta.
Todo esto a un cierto frame rate, que no va a ser el mismo al cual corre el juego. Si los
sprites de Sonic cambiaran a 60 FPS necesitaramos tener muchos ms sprites para evitar
que la animacin se vea ultra acelerada. Es por eso que
propio FrameRate.
Ahora, veamos como usar la funcin loadGraphic() para cargar una animacin.
1 loadGraphic ( Graphic
2 Height
Int ,
? Unique
Dynamic ,
:
Bool ,
? Animated
? Key
String )
Bool ,
:
? Width
Int ,
FlxSprite
Graphic: es de tipo Dynamic, pero por ahora nosotros le vamos a pasar un String
que contenga el path de la imagen que queremos usar.
Animated: indica si la imagen es una sola imagen o si tiene una animacin.
Width: el ancho de cada uno de los frames de la animacin.
Height: la altura de cada uno de los frames de la animacin.
Ejemplo:
1
var
_thief
2 _ t h i e f = new
FlxSprite ;
FlxSprite (x , y) ;
true , 9 0 , 9 0 ) ;
4 add ( _ t h i e f ) ;
49
8.2.1. Comportamientos
No alcanza con slo cargar una sprite sheet para hacer una animacin, hace falta
denir comportamientos. Habrn notado que en distintas partes del sprite sheet trataban
distintos comportamientos de Sonic. Es decir, en una parte est empujando, en otra
haciendo el giro, en otra esperando, etc. Esto se
muy prctica que nos permite Haxeixel de organizar nuestro sprite sheet. Para agregar
un comportamiento a un Sprite usamos el siguiente mtodo:
1 a n i m a t i o n . add ( Name
Looped
String ,
Frames
: Int ,
Bool )
var
_thief
2 _ t h i e f = new
FlxSprite ;
FlxSprite (x , y) ;
true , 9 0 , 9 0 ) ;
2] ,
[0 ,
1,
16 ,
true ) ;
En nuestro ejemplo del ladrn, este comportamiento dice que se van a ver los frames
0,1,2 en ese orden a 16 frames por segundo y se va repetir indenidamente.
El mtodo play() recibe como argumento uno de los nombres de comportamientos que
se haya declarado anteriormente y lo anima.
Si no llamamos al mtodo play no se animar ningn comportamiento.
50
Dado que cargar una imagen lleva un cierto tiempo, tiempo en el cual el procesador
est ocupado, y nuestro juego no se actualiza. Ahora qu pasa si nuestro juego tiene
que cargar una cantidad grande de imgenes? Vamos a empezar a notarlo, a veces lo
pueden ver en juegos cuando recin empieza que, por unos segundos, todo anda ms lento
y despus arranca y anda bien.
Una manera de resolver esto es usando un
su vez tenemos otro problema al cargar imgenes, qu vamos a hacer con los recursos que
son creados indenidamente? Por ejemplo, balas, enemigos, misiles, etc. No nos alcanza
la memoria para crearlos todos al principio, porque podran ser innitos. La idea de ir
creando los recursos y destruirlos segn la necesidad, pero como ya vimos, eso produce un
tiempo de carga que puede relentizar nuestro juego. La solucin a este segundo problema
es el
9.1. Loading
La idea de loading es muy simple, slo empezar el juego despus de que todos los
recursos estn cargados. Estas son las famosas loading screens que vemos en todos los
juegos.
51
Una opcin es mostrar una imagen ja al jugador mientras el juego se carga. Pero una
solucin ms esttica es mostrar al jugador una barra a medida que se cargan los recursos.
Normalmente para realizar esto necesitaramos trabajar con hilos. Un hilo tendra que
estar cargando los recursos mientras otro actualiza la barra de loading.
new F lxAsyncLoop(Iterations : Int, Callback : Void Void, IterationsP erU pdate : Int);
Es bsicamente un loop que llama a la funcin Callback, una cantidad de veces igual
a Iterations, haciendo IterationsPerUpdate cantidad de iteraciones en cada update.
O sea que la carga de recursos se tiene que hacer dentro de la funcin Callback. Y esta
funcin tiene que comportarse de manera iterativa.
No nos sirve de nada una funcin que trata de cargar todos los recursos en una iteracin,
esto sera lo mismo que no usar esta funcin.
http://haxeflixel.com/demos/FlxAsyncLoop/
MenuState.
1 class
Main extends
Sprite {
g a m e H e i g h t : Int = 4 8 0 ;
4 var
i n i t i a l S t a t e : Class<FlxState> = MenuState ;
5 var
f r a m e r a t e : Int = 6 0 ;
...
7 }
f l i x e l . addons . u t i l . FlxAsyncLoop ;
3 import
f l i x e l . FlxG ;
4 import
f l i x e l . FlxSprite ;
5 import
f l i x e l . FlxState ;
6 import
f l i x e l . g r o u p . FlxGroup ;
7 import
f l i x e l . t e x t . FlxText ;
52
8 import
f l i x e l . u i . FlxBar ;
9 import
f l i x e l . u t i l . FlxColorUtil ;
10 import
f l i x e l . u t i l . FlxRandom ;
11 import
f l i x e l . util . FlxSpriteUtil ;
Atributos:
1
2 /*
Creamos
y
otra
var
nuestros
que
drops
tenga
lo
grupos ,
que
estemos
uno
para
por
mostrar
cargar :
barra
de
grpFinished
progreso
*/ p r i v a t e
_ g r p P r o g r e s s : FlxGroup ;
3 private
var _ g r p F i n i s h e d : FlxGroup ;
4 private
5 private
6
7 //
Creamos
8 private
una
fancy
progress
bar
9
10 //
Agregamos
11 p r i v a t e
una
Barra
de
Texto
la
Barra
de
Progreso
Mtodo Create:
1 override public function
c r e a t e ( ) : Void {
2 _ g r p P r o g r e s s = new FlxGroup ( ) ;
3 _ g r p F i n i s h e d = new FlxGroup ( _maxItems ) ;
4
5 //
Creamos
nuestro
Ciclo
de
Carga
addItem ,
100) ;
7
8 _bar = new F l x B a r ( 0 ,
50 ,
null ,
"" ,
0,
0,
100 ,
F l x B a r . FILL_LEFT_TO_RIGHT,
FlxG . w i d t h
true ) ;
9 _bar . c u r r e n t V a l u e = 0 ;
10 F l x S p r i t e U t i l . s c r e e n C e n t e r ( _bar ) ;
11 _ g r p P r o g r e s s . add ( _bar ) ;
12
13 v a r
aux = " L o a d i n g . . .
";
14 _barText = new F l x T e x t ( 0 ,
0,
15 _barText . s e t F o r m a t ( null ,
BORDER_OUTLINE,
28 ,
FlxG . w i d t h ,
0xffffff ,
aux + _maxItems ) ;
FlxText .
0 x000000 ) ;
16 F l x S p r i t e U t i l . s c r e e n C e n t e r ( _barText ) ;
17 _ g r p P r o g r e s s . add ( _barText ) ;
18
19 // No d e b e m o s
cargar
actualizar
el
grupo
de
fin
hasta
que
terminemos
de
todo
20 _ g r p F i n i s h e d . v i s i b l e
= false ;
21 _ g r p F i n i s h e d . a c t i v e = f a l s e ;
22
23 add ( _ g r p P r o g r e s s ) ;
24 add ( _ g r p F i n i s h e d ) ;
25
26 //
Agregamos
la
instancia
de
FlxAsyncLoop
53
Para
realizar
la
Carga
50 ,
27 add ( _loopOne ) ;
28
29 // I m p o r t a n t e :
No
olvidar
30 s u p e r . c r e a t e ( ) ;
31 }
function a d d I t e m ( ) : Void
2 {
3 / * En
cada
4 10 x 1 0
en
iteracin
una
de
nuestro
posicin y
con
ciclo ,
un
color
creamos
al
azar
un
Sprite
cuadrado
*/
5
6 var random_x = FlxRandom . i n t R a n g e d ( 0 ,
FlxG . w i d t h ) ;
FlxG . h e i g h t ) ;
8 var
sprite
= new
F l x S p r i t e ( random_x , random_y ) ;
9
10 // C o l o r
11 var
al
azar
r a n d o m _ c o l o r = F l x C o l o r U t i l . getRan domColo r ( 0 ,
255 ,
255) ;
12
13 s p r i t e . makeGraphic ( 1 0 ,
1 0 , random_color
);
14 _ g r p F i n i s h e d . add ( s p r i t e ) ;
15
16 //
Actualizamos
el
valor
de
la
progreso
el
17 _bar . c u r r e n t V a l u e = ( _ g r p F i n i s h e d . members . l e n g t h
_maxItems )
" + _maxItems ;
18 _barText . t e x t = " L o a d i n g . . .
barra
de
texto
100;
"
Mtodo Update:
1 override public function
u p d a t e ( ) : Void {
2 //
si
3 if
( ! _loopOne . s t a r t e d ) {
el
ciclo
no
empez => p l a y
_loopOne . s t a r t ( ) ;
5 } else {
6
//
Una
vez
sprites !
if
que
termina
notar
que
el
al
ciclo ,
utilizar
( _loopOne . f i n i s h e d ) {
_grpFinished . v i s i b l e
= true ;
_grpProgress . v i s i b l e
= false ;
10
_ g r p F i n i s h e d . a c t i v e = true ;
11
_grpProgress . a c t i v e = f a l s e ;
12
13
// D e s t r u y o
14
_loopOne . k i l l ( ) ;
15
_loopOne . d e s t r o y ( ) ;
16
el
ciclo
17 }
18 s u p e r . u p d a t e ( ) ;
19 }
54
oculto
el
grupos ,
loader
se
muestro
simplifica
los
todo !
Figura 12: Al ejecutarlo, veremos en orden estas pantallas, la primera reeja el estado
Cargando indicando el avance, y la segunda el estado nal con 5000 cuadraditos ubicados
al azar de distintos colores.
var
3 bullets
4
var
del
grupo
que
contiene
10
balas
n u m B u l l e t s : Int = 1 0 ;
= new FlxTypedGroup<FlxSprite>( n u m B u l l e t s ) ;
s p r i t e : FlxSprite ;
5 for
(i
sprite
in 0 ... n u m B u l l e t s ) {
s p r i t e . makeGraphic ( 8 ,
sprite . exists
b u l l e t s . add ( s p r i t e ) ;
= new
FlxSprite (
100 , 100) ;
2) ;
= false ;
10 }
11 add ( b u l l e t s ) ;
55
( FlxG . k e y s . j u s t P r e s s e d . SPACE) {
var
bullet . reset (x , y) ;
bullet . velocity .y =
b u l l e t : FlxSprite = PlayState . b u l l e t s . r e c y c l e () ;
200;
5 }
http://haxeflixel.com/demos/FlxInvaders/
56
i n i t i a l S t a t e : Class<FlxState> = P l a y S t a t e ;
Create.
Update.
El mtodo Create:
1 override
p u b l i c function
2 FlxG . mouse . v i s i b l e
c r e a t e ( ) : Void {
= false ;
// O c u l t a m o s
el
mouse
3
4 //
5 var
Lo
primero
que
hacemos
es
crear
Balas .
n u m P l a y e r B u l l e t s : Int = 8 ;
6 // No
olvidarse
de
inicializar
un
arreglo !
7 p l a y e r B u l l e t s = new FlxGroup ( n u m P l a y e r B u l l e t s ) ;
8 var
s p r i t e : FlxSprite ;
57
9
10 //
Creamos
una
cantidad
finita
11 f o r
(i
in 0 ...
12
//
Creamos
13
sprite
14
//
white
box
15
s p r i t e . makeGraphic ( 2 ,
8) ;
16
sprite . exists
17
//
18
p l a y e r B u l l e t s . add ( s p r i t e ) ;
de
balas
que
reciclaremos
numPlayerBullets ) {
un
= new
Create
sprite
2 x8
Agregamos
fuera
de
pantalla
( offscreen )
100 , 100) ;
FlxSprite (
= false ;
la
bala
al
grupo
de
balas
19 }
20
21 add ( p l a y e r B u l l e t s ) ;
22
23 //
Creamos
la
nave ,
que
es
el
jugador
lo
agregamos
al
estado
24 _ p l a y e r = new P l a y e r S h i p ( ) ;
25 add ( _ p l a y e r ) ;
26
27 // De
28 var
la
misma
manera :
inicializamos
los
aliens ,
incluyendo
sus
balas
n u m A l i e n B u l l e t s : Int = 3 2 ;
= new FlxGroup ( n u m A l i e n B u l l e t s ) ;
29 a l i e n B u l l e t s
30
31 f o r
(i
32
sprite
in 0 ...
33
s p r i t e . makeGraphic ( 2 ,
34
sprite . exists
35
a l i e n B u l l e t s . add ( s p r i t e ) ;
numAlienBullets ) {
= new
FlxSprite (
100 , 100) ;
8) ;
= false ;
36 }
37 add ( a l i e n B u l l e t s ) ;
38
39 //
Creamos
filas
c /u
con
10
aliens
de
un
color
los
agregamos
al
estado
40 var
n u m A l i e n s : Int = 5 0 ;
41 _ a l i e n s = new FlxGroup ( n u m A l i e n s ) ;
42 var a : Alien ;
43 var
c o l o r s : Array<Int >;
44
45 c o l o r s
GREEN,
[ F l x C o l o r . BLUE,
( F l x C o l o r . BLUE
( F l x C o l o r .GREEN |
F l x C o l o r .RED) ,
F l x C o l o r .GREEN) ,
FlxColor .
F l x C o l o r .RED ] ;
46
47 f o r
(i
48
a = new
in 0 ... n u m A l i e n s ) {
Alien (8 + ( i
c o l o r s [ Std . i n t ( i
49
% 10)
/
10) ] ,
32 ,
24 + S t d . i n t ( i
10)
32 ,
alienBullets ) ;
_ a l i e n s . add ( a ) ;
50 }
51
52 add ( _ a l i e n s ) ;
53
54 //
Finalmente
creamos
se
como
rrompen
escudos ,
todo
al
que
recibir
consisten
un
55 _ s h i e l d s = new FlxGroup ( ) ;
58
de
disparo .
cajitas
blancas
que
56
57 f o r
(i
58
sprite
in 0 ...
64) {
= new
F l x S p r i t e ( 3 2 + 80
FlxG . h e i g h t
Std . i n t ( i
32 + ( S t d . i n t ( ( i
% 16)
/
4)
16) + ( i
% 4)
4,
4) ) ;
59
60
s p r i t e . makeGraphic ( 4 ,
61
_ s h i e l d s . add ( s p r i t e ) ;
4) ;
62 }
63
64 add ( _ s h i e l d s ) ;
65
66 //
Este
grupo
almacena
las
cosas
las
que
el
las
que
los
mensaje
con
el
jugador
puede
disparar !
aliens
puede
disparar !
67 _ v s P l a y e r B u l l e t s = new FlxGroup ( ) ;
68 _ v s P l a y e r B u l l e t s . add ( _ s h i e l d s ) ;
69 _ v s P l a y e r B u l l e t s . add ( _ a l i e n s ) ;
70
71 //
Este
grupo
almacena
las
cosas
72 _ v s A l i e n B u l l e t s = new FlxGroup ( ) ;
73 _ v s A l i e n B u l l e t s . add ( _ s h i e l d s ) ;
74 _ v s A l i e n B u l l e t s . add ( _ p l a y e r ) ;
75
76 //
Finalmente
77 var
agregamos
un
t : FlxText = new F l x T e x t ( 4 ,
4,
estado
FlxG . w i d t h
8,
del
juego !
statusMessage ) ;
78 t . a l i g n m e n t = " c e n t e r " ;
79 add ( t ) ;
80 }
Mtodo Update:
1 override public function
2 //
Observar
que
necesitamos
de
u p d a t e ( ) : Void {
utilizamos
el
superposicin
efecto
de
overlaps
fsico
de
la
no
colisiones
colisin
slo
sino
ya
que
capturar
4 FlxG . o v e r l a p ( a l i e n B u l l e t s ,
_vsPlayerBullets ,
_vsAlienBullets ,
stuffHitStuff ) ;
stuffHitStuff ) ;
5
olvidarse
de
llamar
al
super . update !
7 super . update ( ) ;
8
9 //
10 i f
Ahora
verificamos
las
condiciones
de
victoria
de
derrota
prdida
( ! _player . e x i s t s ) {
11
//
12
s t a t u s M e s s a g e = "YOU LOST" ;
13
FlxG . r e s e t S t a t e ( ) ;
14 } e l s e
Moriste
if
=>
seteamos
el
estado
( _ a l i e n s . g e t F i r s t E x i s t i n g ( ) == null ) {
15
//
16
s t a t u s M e s s a g e = "YOU WON" ;
17
FlxG . r e s e t S t a t e ( ) ;
Mataste
Todos
el
elementos .
3 FlxG . o v e r l a p ( p l a y e r B u l l e t s ,
6 // Jams
no
los
aliens
=> G a n a s t e
18 }
19 }
59
evento
1 // S i m p l e m e n t e
2 private function
eliminamos
ambos
objetos
s t u f f H i t S t u f f ( O b j e c t 1 : FlxObject ,
O b j e c t 2 : FlxObject ) : Void
3 {
4
Object1 . k i l l ( ) ;
Object2 . k i l l ( ) ;
6 }
f l i x e l . FlxG ;
4 import
f l i x e l . FlxSprite ;
5 import
f l i x e l . g r o u p . FlxGroup ;
6 import
f l i x e l . u t i l . FlxRandom ;
7
8 class
9 //
extends FlxSprite {
Alien
Atributo
para
almacenar
el
tiempo
pasado
entre
disparos ,
para
limitarlos .
10 p r i v a t e
11 //
var _ s h o t C l o c k : Float ;
Almacenamos
12 p r i v a t e
var
la
posicin
original
para
lgica
la
del
movimiento .
_ o r i g i n a l X : Int ;
13
14
15 p u b l i c
16 //
Llamamos
17 s u p e r (X,
18 //
C o l o r : Int ,
B u l l e t s : FlxGroup ) {
super !
Y) ;
Cargamos
la
imgen
del
alien ,
ponemos
que
es
animado !
true ) ;
20 c o l o r = C o l o r ;
21 _ o r i g i n a l X = X ;
22 r e s e t S h o t C l o c k ( ) ;
23
24 / *
Ahora
creamos
queremos
en
para
independiente
25
una
simple
reproducir
dar
la
en
orden
sensacin
alteramos
el
1 ,2 ,3 ,1
de
que
frame
se
rate
pero
de
con
poco
r a n d = Math . f l o o r ( 6 + FlxRandom . f l o a t ( )
[0 ,
1,
28
29 //
dale
play !
30 t h i s . a n i m a t i o n . p l a y ( " D e f a u l t " ) ;
31
32 v e l o c i t y . x = 1 0 ;
33 }
34
35 override public function
u p d a t e ( ) : Void {
60
0,
los
mueven
*/
26 var
contiene
claro
2] ,
un
4) ;
rand ) ;
frames
nidices
manera
de
azar
arrancan
36 //
Si
los
aliens
ca mbi amos
37 i f
se
la
movieron
velocidad
( x < _originalX
38
x = _originalX
39
velocity .x =
40
v e l o c i t y . y++;
demasiado
para
el
de
otro
su
posicin
inicial
le
lado
8) {
8;
v e l o c i t y
.x;
41 }
42
43 //
Lo
44 i f
( x > _originalX + 8) {
mismo
en
el
otro
lado ,
45
x = _originalX + 8;
46
velocity .x =
v e l o c i t y
es
decir
simulamos
paredes
.x;
47 }
48
49 //
Comenzamos
contar
el
tiempo
cuando
pasamos
cierta
lnea
imaginaria
horizontal
50 i f
51
( y > FlxG . h e i g h t
_shotClock
0.35) {
FlxG . e l a p s e d ;
52 }
53
54
55 i f
56
( _ s h o t C l o c k <= 0 ) {
//
Si
puedo
disparar ,
velocidad . y
disparo
es
decir
reciclo
una
bala
con
positiva
57
resetShotClock () ;
58
var
59
b u l l e t . r e s e t ( x + width
60
b u l l e t : FlxSprite = c a s t ( c a s t ( FlxG . s t a t e ,
alienBullets . recycle () ,
/
PlayState ) .
FlxSprite ) ;
b u l l e t . width
2,
y) ;
61 }
62
63 s u p e r . u p d a t e ( ) ;
64 }
65
66 / *
67
funcin
Esta
nuevo ,
68
el
resetea
rango
va
el
tiempo
entre
en
que
11
este
alien ,
segundos
*/
69 p r i v a t e
function
r e s e t S h o t C l o c k ( ) : Void {
_ s h o t C l o c k = 1 + FlxRandom . f l o a t ( )
70
71 }
72 // F i n
de
la
clase
73 }
f l i x e l . FlxG ;
4 import
f l i x e l . FlxSprite ;
61
10;
pueden
disparar
de
5
6 class
extends FlxSprite {
PlayerShip
7
8 public
9 //
function
Centramos
new ( ) {
la
nave ,
hard
codeado
xq
sabemos
el
ancho
de
la
imagen
xD
10 s u p e r ( FlxG . w i d t h
6,
FlxG . h e i g h t
12 ,
11 }
12
13 override
p u b l i c function u p d a t e ( ) : Void {
14
15 // En
cada
update
frenamos
la
nave
16 v e l o c i t y . x = 0 ;
17
18 // Hacemos
19 i f
20
que
se
mueva
si
teclea
las
( FlxG . k e y s . a n y P r e s s e d ( [ "LEFT" ,
velocity .x
flechas !
"A" ] ) ) {
100;
21 }
22 i f
23
( FlxG . k e y s . a n y P r e s s e d ( [ "RIGHT" ,
"D" ] ) ) {
v e l o c i t y . x += 1 0 0 ;
24 }
25
26 //
Llamar
al
super . update !
27 s u p e r . u p d a t e ( ) ;
28
29
30 //
Simulamos
31 i f
( x > FlxG . w i d t h
32
una
pared
x = FlxG . w i d t h
la
derecha
width
width
4) {
4;
33 }
34
35 //
Simulamos
36 i f
( x < 4) {
37
una
pared
la
izquierda
x = 4;
38 }
39
40 // lgica
41 i f
del
disparo ,
sale
del
centro
de
la
nave
se
reciclan
( FlxG . k e y s . j u s t P r e s s e d . SPACE) {
42
var
b u l l e t : FlxSprite = c a s t ( c a s t ( FlxG . s t a t e ,
43
b u l l e t . r e s e t ( x + w i d t h /2
44
bullet . velocity .y =
playerBullets . recycle () ,
FlxSprite ) ;
b u l l e t . width /2 ,
140;
45 }
46
47 s u p e r . u p d a t e ( ) ;
48 }
49 // F i n
de
la
PlayState ) .
clase
50 }
62
y) ;
3. Que las balas estn en la capa ms alta. Es decir, redenir el mtodo update, agregando grupos que referencien capas, entonces slo en un lugar lo hago visible segn
que capa debe ir arriba de otra.
Figura 15: Es muy confusa la situacin actual. Hay balas arriba de aliens y debajo, no
deberamos agregar confusin al jugador.
63
Los sonidos y la msica de un videojuego son tan importantes como las imgenes o el
15 .
diseo. A veces una cancin puede hacer que un videojuego valga la pena jugarlo
Los videojuegos estn generando tantos ingresos que muchos msicos profesionales como Danny Baranowsky, compositor de Necrodancer, Desktop Dungeons, Drifter, Super
Meat Boy y otros, han decido dedicarse a componer msica exclusivamente para videojuegos.
Esto tambin es verdadero para otras profesiones como actores de voz o creadores de
efectos de sonidos.
A continuacin veremos cmo incluir sonidos y msica en nuestros juegos.
var
sound
FlxSound = new F l x S o u n d ( ) ;
Una vez que tenemos nuestro objeto, debemos cargarle un sonido incrustado:
1 s o u n d . loadEmbedded ( " a s s e t s /MainMenu . mp3" , true ) ;
1 loadEmbedded ( EmbeddedSound
2 :
Bool ,
? OnComplete
Bool ,
? AutoDestroy
64
EmbeddedSound:
Looped:
AutoDestroy :
1 sound . p l a y ( ) ;
sonidos.
podemos reciclar
var
2 add ( s o u n d s ) ;
3
4
var
s o u n d = new F l x S o u n d ( ) ;
var
s o u n d = new F l x S o u n d ( ) ;
var
sound
FlxSound = s o u n d s . r e c y c l e ( ) ;
13 s o u n d . p l a y ( ) ;
65
Si queremos que un sonido que dure ms all de un estado, podemos utilizar la clase
Reg.hx para crear una variable de sonido esttica que pueda ser modicada en cualquier
estado.
1 public
static
var
s o u n d : FlxSound = new F l x S o u n d ( ) ;
var s o u n d
#if flash
FlxSound = new F l x S o u n d ( ) ;
#else
s o u n d . loadEmbedded ( " a s s e t s /MainMenu . o g g " ) ;
#end
7 add ( s o u n d ) ;
8 sound . p l a y ( ) ;
pan : F loat,
playing : Bool,
volume : F loat,
x : F loat, indica la posicin en x del sonido, til solamente cuando usamos proximity().
y : F loat, indica la posicin en y del sonido, til solamente cuando usamos proximity().
66
pause() : Void,
resume() : Void,
stop() : Void,
f adeOut(Duration : Float, ?T o : Float) : Void, igual que el anterior slo que toma
lugar al nalizar la reproduccin y slo puede bajar el volumen. Por defecto:(1,0,1).
Pan: si el sonido aparte de modicar su volumen tambin va modicar la direccin de la cual viene.
67
Hasta ahora hemos creado juegos que no son persistentes, eso est bien para juegos
cortos o repetitivos como sera un arcade o un puzzle. Pero si queremos crear un juego
que dure ms de una hora debemos poder guardar el estado del juego para reanudarlo en
otro momento.
Veremos cmo poder hacer resolver este problema:
var
save
FlxSave = new F l x S a v e ( ) ;
Una vez hecho el enlace, podemos empezar a cargar o guardar datos usando el siguiente
campo:
1 save . data
data
es un campo de tipo
Dynamic.
= 42;
2 s a v e . d a t a . name =
3 save . data . s c o r e s = [ 3 0 0 , 1 0 0 , 6 6 6 ] ;
Y listo! Los datos se han guardado. Ahora cmo los recuperamos al correr el juego
de nuevo? Simple, primero hacemos el enlace al mismo nombre y recuperamos los datos:
1
var
save
FlxSave = new F l x S a v e ( ) ;
var
var
var
level
name
score
Int = s a v e . d a t a . l e v e l ;
String = s a v e . d a t a . name ;
:
:
Int = s a v e . d a t a . s c o r e s [ 0 ] ;
68
Ahora, recuerden que al trabajar con un objeto dinmico, no siempre puede tener
valores guardados, y esto puede llevar a tremendos errores al momento de la ejecucin.
Es por eso que siempre deberamos vericar que no sean
1
var
save
null:
FlxSave = new F l x S a v e ( ) ;
var
4 if
level
Int ;
( save . data . l e v e l
!= null )
level
= save . data . l e v e l ;
level
= 1;
6 else
7
Es muy importante entender que los datos guardados no tienen que ver con el objeto
que se utiliza para guardarlos, es por eso que el siguiente cdigo es vlido:
1
var
save
FlxSave = new F l x S a v e ( ) ;
= 5;
4
5
var
save2
FlxSave = new F l x S a v e ( ) ;
var
level
Int = s a v e 2 . d a t a . l e v e l ;
Se podra decir que el objeto save es una interface para acceder los datos guardados
pero no es dnde se guardan los datos, un ejemplo de algo que
1
var
save1
no funcionara:
FlxSave = new F l x S a v e ( ) ;
= 5;
4
5 save . bind ( " s l o t 2 " ) ;
6
var
level
Int = s a v e . d a t a . l e v e l ;
null.
En realidad, esto compila y corre. Pero si tratamos de leer el valor de level veremos que
NaN. En otros casos donde trabajamos con objetos que tienen mtodos (algo
ms complicado que un Int) veremos que efectivamente puede crashear el programa.
es igual a
Lo que se recomienda es tener una sola variable save dentro de la clase Reg.hx Dentro
de un estado se puede realizar el enlace y todos los otros estados pueden acceder a los
datos.
name : String ,
Slo se utiliza para saber el nombre, si queremos cambiar el nombre al cual estamos
enlazados debemos usar la funcin bind().
69
true
si es exitoso.
false si no
existe un enlace con ese nombre. No requiere un ush, as que usar con precaucin.
erase() : Bool,
destroy() : V oid,
70
primero llama a
Hasta ahora nuestros juegos han sido jos, es decir, la cmara del juego no se ha
movido. Eso es muy til para juegos de tipo puzzle u otros gneros donde no hace falta.
Pero en la gran mayora de juegos, vamos a tener que movernos a travs de nuestro mundo
virtual, y es ah donde entra en juego la cmara.
12.1. Qu es la cmara?
La cmara es una ventana para ver los objetos que hemos creado en nuestro juego.
Podemos agrandar o achicar esa ventana. Por defecto, tiene el mismo tamao que la
resolucin del juego. Tambin podemos cambiar la posicin de esa ventana. Y podemos
modicar qu parte de nuestro mundo la ventana est mirando.
Como pueden ver, todo lo que est fuera de la cmara, no se muestra. Por ms que
nuestro fondo verde fuese innito no se a va ver porque est fuera de la cmara. El color
71
F lxG.camera
Si queremos modicar los valores o llamar mtodos de esta cmara se hace de la
siguiente manera:
F lxG.camera.width = 640/2;
F lxG.camera.x = 200;
F lxG.camera.y = 200;
F lxG.f ocus(new F lxP oint(0, 400));
Tambin podemos crear ms cmaras si nos hiciera falta (til para juegos donde hay
splitscreen
16 , y otros casos ms.) En ese caso, hay que agregarla a la lista de cmaras.
var
c a m e r a = new FlxCamera ( S t d . i n t ( 6 4 0 / 2 ) , 0 , S t d . i n t ( 6 4 0 / 2 ) , 4 8 0 , 1 ) ;
4 c a m e r a . f o l l o w ( _char2 ) ;
5 FlxG . c a m e r a s . add ( c a m e r a ) ;
minimapa:
angle : F loat,
bgColor : Int,
16 Divisin de pantalla
72
height : Int,
width : Int,
style : Int,
altura de la cmara.
ancho de la cmara.
x : F loat,
la posicin
y : F loat,
la posicin
zoom : F loat,
instancia una
Color:
Duration:
F adeIn:
OnComplete:
F orce:
un estilo predenido.
73
Of f set : el oset del deadzone del estilo elegido. Slo disponible para PLATAFORMER,
LOCKON.
Lerp :
Duration :
OnComplete:
F orce:
Direction:
mtodo para detener todos los efectos de cmara que estn cor-
riendo.
s es alto.
ST Y LE _T OP DOW N _T IGHT (inline, null) : Int, idem supra pero con un cuadrado ms chico.
74
estn tocando. Puede tener tolerancia a la opacidad de los pxeles, es decir qu tan visibles
tienen que ser los pxeles para determinar si es una colisin o no.
1 FlxG . p i x e l P e r f e c t O v e r l a p ( S p r i t e 1
2 ? AlphaTolerance
Int ,
? Camera
FlxSprite , S p r i t e 2
FlxCamera ) : Bool
:
Sprite1:
Sprite2:
AlphaT olerance:
completamente visibles. 1
FlxSprite ,
tamente invisible.
Camera:
13.2.1. FlxTween
Tween viene de la palabra Inbetween. Es una manera de crear los frames para una
animacin de un sprite de manera automtica. Podemos Tweenear distintos valores de
un sprite a lo largo de una duracin, y los frames sern generados automticamente.
Por ejemplo, podemos cambiar el ngulo de un sprite por 90 grados a lo largo de un
periodo de 3 segundos.
75
O podemos usarlo para cambiar el color de un sprite a otro color a lo largo de medio
segundo. Hay varios tweens que podemos aplicar sobre un objeto:
Sprite:
T oAngle:
Duration:
Options:
lo explicaremos ms adelante.
Object:
CenterX :
la posicin
CenterY :
la posicin
Radius:
Angle:
Clockwise:
horario o antihorario.
DurationOrSpeed:
Sprite:
Duration:
F romColor:
T oColor:
el color nal.
F romAlpha:
T oAlpha:
el color inicial.
la opacidad inicial.
la opacidad nal.
76
Duration:
Object:
el objeto a tweenear.
F romX :
la posicin X inicial.
F romY :
la posicin Y inicial.
T oX :
la posicin X nal.
T oY :
la posicin Y nal.
DurationOrSpeed:
Object:
el objeto a tweenear.
P oints:
DurationOrSpeed:
num(F romV alue : Float, T oV alue : Float, Duration : Float, ?Options : TweenOptions) :
flixel.tweens.misc.NumTween, tweenea un valor numrico.
F romV alue:
T oV alue:
Duration:
el valor inicial.
el valor nal.
la duracin del tween en segundos.
Object:
F romX :
la posicin X original.
77
F romY :
la posicin Y original.
ControlX :
ControlY :
T oX :
la posicin X nal.
T oY :
la posicin Y nal.
DurationOrSpeed:
Object:
V alues:
tweenear
Duration:
13.2.2. TweenOptions
Es un objeto con los siguientes campos:
var
o p t i o n s : TweenOptions = {
bounceOut ,
var
type :
FlxTween . ONESHOT,
e a s e : FlxEase .
c o m p l e t e : onTweenEnd }
t w e e n = FlxTween . t w e e n ( _char ,
y:400 ,
Tipos de Tweens
78
x :300
},
0.8 ,
options ) ;
ON ESHOT (inline, null) : Int, un tween que corre una sola vez y se destruye cuando
termina.
al terminar.
ONESHOT y BACKWARD.
Tipos de Ease:
Hay muchos:
http://api.haxeflixel.com/types/flixel/tweens/FlxEase.html
elstico.
slo al terminar.
13.2.3. FlxGlitchSprite
new(T arget : F lxSprite, Strength : Int = 4, Size : Int = 1, Delay : F loat =
0,05, ?Direction : GlitchDirection) : F lxGlitchSprite
Crea una copia de un sprite con un efecto de distorsin. No se debe agregar el sprite
original al display, solo el GlitchSprite.
T arget:
el sprite a copiar.
Strength:
Size:
Delay :
79
13.2.4. FlxWaveSprite
N ew(T arget : FlxSprite, ?M ode : WaveMode, Strength : Int = 20, Center : Int =
1, Speed : Float = 3) : FlxWaveSprite: crea una copia de un sprite pero con un efecto
de ondas. Al igual que antes, slo se debe agregar al displaylist la copia.
T arget:
M ode:
el sprite a copiar.
imagen.
W aveM ode.BOT T OM :
inversa de BOTTOM.
Strength:
Center:
Speed:
13.2.5. FlxSpriteFilters
Podemos agregar ltros a nuestros sprites de la siguiente manera. Creamos un ltro de
alguno de los siguientes:
GlowF ilter
BlurF ilter
DropShadow
color:
Alpha:
la opacidad.
BlurX :
la cantidad de brillo en X.
BlurY :
la cantidad de brillo en Y.
Strength:
Quality :
Inner:
80
Knockout:
qu tan borroso se ve en X.
BlurY :
qu tan borroso se ve en Y.
Quality :
Alpha:
la opacidad de la sombra.
BlurX :
qu tan borroso se ve en X.
BlurY :
qu tan borroso se ve en Y.
Strength:
Quality :
HideObject:
81
17 .
Una vez creado un ltro, hay que crear un FlxSpriteFilter sobre un sprite y agregarle
ese ltro:
1 new
FlxSpriteFilter
( S p r i t e : FlxSprite ,
H e i g h t I n c r e a s e : Int =0)
Sprite:
W i d t h I n c r e a s e : Int =0 ,
FlxSpriteFilter
W idthIncrease:
cunto incrementar el ancho del sprite, til para ltros como blur
HeightIncrease:
Ejemplo:
1
2
var
var
filter
= new D r o p S h a d o w F i l t e r ( ) ;
c h a r F i l t e r = new
F l x S p r i t e F i l t e r ( _char , 1 0 , 1 0 ) ;
3 charFilter . addFilter ( f i l t e r ) ;
82
14. Tiles
En conclusin, los juegos son profesores. La pregunta es: qu estn enseando?
Raph Coster - A Theory of Game Design
Algunos tiles son continuos, es decir que esperan que haya otro tile que lo siga en
alguno de sus lados. Un tile puede ser continuo en cualquiera de sus cuatro lados. Esto
quiere decir que hay 16 combinaciones distintas de continuidad de un tile, yendo de cero
continuidad a continuidad en sus 4 lados.
Figura 18: (1) Un bosque continuo a derecha y izquierda. (2) Un bosque continuo hacia
arriba izquierda y abajo.
83
Ac los ceros quieren decir: No colocar tile y los unos quieren decir : Colocar tile. Y
por ltimo agregar el mapa a nuestro display list:
1 add (_map) ;
Y listo tenemos un mapa hecho con tiles! Si queremos que nuestro personaje colisione
con los tiles, solo hace falta agregarlo en el update:
1 FlxG . c o l l i d e ( _char ,
_map) ;
Este es un caso simple, donde use un tile que tena un espacio en blanco y una imagen
para cuando el tile esta en uso. Tambin se puede colocar ms de una imagen y usar los
nmeros que se pasan como argumento. Ej:
1 _map . loadMap ( " 0 , 1 , 2 , 2 , 1 , 0 , 0 , 3 " , " a s s e t s / t i l e 2 . png " ) ;
En este caso, cada nmero corresponde a un tile distinto dentro de la imagen que
le pase. Tambin se le puede decir que use el modo de
quiere decir que nosotros slo colocamos 0 y 1, y si en el mapa encuentra dos 1's conectados
usa los tiles correspondientes para continuarlos. En este caso nosotros debemos pasarle
los 16 tiles de continuidad.
1 _map . loadMap ( " 0 , 0 , 0 , 0 \ n
0 ,1 ,1 ,0\n
0 , 1 , 0 , 0 , 0 \ n0 , 0 , 0 , 0 " , " a s s e t s / t i l e 3 .
Tambin hay otro modo que es ALT. La diferencia entre ALT y AUTO es que AUTO
se usa para paredes nas mientras que ALT se usa para paredes gruesas que requieren
dibujos con esquinas en su interior.
Ac es muy importante colocar todos los ceros alrededor de los unos, porque sino el
AUTO o ALT va a asumir que tiene que colocar un tile continuo. Y presten atencin
que
las imgenes tienen que ir en ese orden predenido, sino el AUTO o ALT va
la funcin constructora.
84
StartingIndex: usado para colocar tiles vacos. Se recomienda dejar en cero. Ignorado si AutoTile es usado.
DrawIndex: a partir de este nmero los tiles sern visibles. Se recomienda dejar
en 1. Ignorado si AutoTile es usado.
function setT ileP roperties(T ile : Int, ?AllowCollisions : Int = 4369, ?Callback :
FlxObject FlxObject Void = null, ?CallbackF ilter : Class < Dynamic >=
null, ?Range : Int = 1) : Void, setea las colisiones y funciones callbacks para cada
tile.
AllowCollisions: establecemos desde dnde debe detectar colisiones, usar constantes de FlxObject: NONE, ANY, LEFT, RIGHT, etc.
CallbackFilter: si slo quers que la funcin callback se llame para ciertas clases.
85
True.
False.
RaySimplify:
Default:
True.
14.1.2. FlxTimeMapExt
Extiende la clase anterior agregando las siguientes funcionalidades:
setea el arreglo de
function setSlopes(?Lef tF loorSlopes : Array < Int >= null, ?RightF loorSlopes :
Array < Int >= null, ?Lef tCeilSlopes : Array < Int >= null, ?RightCeilSlopes :
Array < Int >= null) : Void, setea los arreglos de tiles como Pendientes, tiles
diagonales para corregir la colisin.
13 ,
21];
14 ,
22];
15 ,
23];
16 ,
24];
5 var tempC
12 ,
20];
: Array<Int> = [ 4 ,
6
7 l e v e l . s e t S l o p e s ( tempFL ,
tempFR ,
tempCL ,
tempCR ) ;
8 l e v e l . s e t C l o u d s ( tempC ) ;
14.1.3. FlxCaveGenerator
Un generador de cuevas al azar. Simplemente genera el data String para un tilemap, y
nosotros le pasamos las imgenes de los tiles.
86
87
15. Comunidad
Les dije que aprendan ingls.
Rodrigo Peralta
La comunidad indie es extremadamente til y ahora veremos qu nos puede ofrecer:
Recursos:
Antes que nada, voy a compartir el link que contiene todos los recursos que van a necesitar en su vida:
http://www.pixelprospector.com/indie-resources/.
En esa pgina
hay un montn de listas ya hechas de todos los posibles recursos que necesitemos. Todos
los links que voy a dar abajo estn en esa pagina.
Msica y Sonido
Hay excesivo material artstico dando vueltas en internet. Mucha gente que vive de
vender su arte a desarrolladores de videojuegos. Algunos tienen su propia pgina,
como por ejemplo:
http://oryxdesignlab.com:
portal/view/631339.
http://www.newgrounds.com/
http://www.pixelprospector.com/places-to-find-graphics-artists/
http://www.pixelprospector.com/the-big-list-of-musicians/
http://www.pixelprospector.com/places-to-find-musicians/
Como pueden ver, hay artistas que trabajan freelance, otros venden sus obras ya
creadas y otros ambas.Tambin hay material gratuito, aunque por razones obvias
hay menos y de menor calidad, dentro del sitiio
http://www.pixelprospector.com
podemos entrar a :
/the-big-list-of-royalty-free-graphics/
/the-big-list-of-royalty-free-music-and-sounds-free-edition/
Notar: la comunidad indie es tambin un excelente lugar para
conseguir trabajo.
Material de estudio:
Si recuerdan en las primeras unidades se habl de roles, la idea simple es que una
persona tiene que estar capacitada para cubrir bien su rol. Y todos los roles son
importantes y requieren capacitacin. Por esto se aconseja, como en cualquier mbito de la vida, no estancarse, acceder al bastsimo material de estudio para seguir
mejorando.
88
Marketing:
Muy importante, gente estudia careras para saber esto. No subestimes la importancia
que tiene el marketing en tu juego.
http://www.pixelprospector.com/the-big-list-of-indie-game-marketing/
http://www.pixelprospector.com/how-to-contact-press/
http://www.pixelprospector.com/contents-and-examples-of-press-kits/
Game Design:
Si penss que no existe una teora sobre cmo disear un juego ests subestimando
el arte de hacer juegos. Cualquiera puede hacer un juego pero no cualquiera puede
hacer uno bueno.
http://www.pixelprospector.com/the-big-list-of-game-design/
Msica:
Si quers aprender a hacer msica!
/the-big-list-of-sound-and-music-creation-software/
Grcos:
Si quers aprender a hacer arte grco!
/the-big-list-of-graphics-programs-windows-edition/
/the-big-list-of-drawing-and--animation/
/the-big-list-of-pixel-art-tutorials/
15.1. Comercializacin
Hay varias maneras de comercializar nuestros juegos que listaremos a continuacin.
15.1.1. Publicidades
Publicidades dentro de nuestros juegos.
http://www.pixelprospector.com/advertising-places-to-buy-targeted-ad-space/
15.1.2. Sponsors
Gente compra tu juego para ponerlo en su sitio.
https://www.fgl.com/
89
http://www.pixelprospector.com/the-big-list-of-online-game-stores/
http://www.pixelprospector.com/the-big-list-of-payment-processors/
http://itch.io/
http://gamejolt.com/
http://www.reddit.com/r/IndieGaming/
http://www.reddit.com/r/gamedev
90
#gamedev.
http://compohub.net/
91
Autores:
Bella Nicols.
Ilich Franco.
Passarino Ignacio.
Unanue Diego.
Autor:
Rodrigo Peralta.
92
Autores:
Arguello ngel.
Carrillo Florencia.
Moyano Miguel .
Verblud Javier David.
misma
.
era
...
93
Referencias
[1] Haxe 2 Beginner's Guide - Benjamin Dasnois
[2] SMFL Game Development - Artur Moreira, Jan Haller, Henrik Vogelius Hansson
[3]
haxeflixel.com
94