Programación de Juegos 2D HaxeFlixel

download Programación de Juegos 2D HaxeFlixel

of 95

description

Tutorial curso de Video Juegos, en HaxeFlixel, curso dado por FundaSoft Córdoba a Cargo de Rodrigo Peralta.Tiles, Sprite Sheets, FlxTween, ejemplos.Juegos en 2D.

Transcript of Programación de Juegos 2D HaxeFlixel

  • Curso de Videojuegos en 2D

    Peralta Rodrigo

    8 de julio de 2014

  • ndice

    1. Qu es y cmo se hace un videojuego? 6

    1.1. Qu es un videojuego? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

    1.2. Qu diferencia a un juego de otro? . . . . . . . . . . . . . . . . . . . . . . 8

    1.3. Gneros y Clones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    1.3.1. Gneros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    1.3.2. Clones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    1.4. Juegos basados en otros . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    1.5. Plataformas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

    1.5.1. Interfaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

    1.5.2. Recursos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

    1.6. Roles de un equipo de desarrollo . . . . . . . . . . . . . . . . . . . . . . . . 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

    1.7. 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. Qu es Haxeixel? Por qu Haxeixel? . . . . . . . . . . . . . . . . . . . 17

    2.2. Qu es Haxe? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    2.3. Instalacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    2.4. Eligiendo un IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    3. Hello World en Haxe 19

    3.1. Syntax Bsico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

    3.1.1. Constantes y sus tipos . . . . . . . . . . . . . . . . . . . . . . . . . 19

    3.1.2. Operadores Binarios y Unarios . . . . . . . . . . . . . . . . . . . . . 19

    3.1.3. Bloques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

    3.2. Declaracin de variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

    3.3. Acesso a campos y llamadas a funciones . . . . . . . . . . . . . . . . . . . 21

    3.4. Contruyendo una instancia de una clase . . . . . . . . . . . . . . . . . . . . 21

    3.5. If . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

    3.6. Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

    3.7. While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

    1

  • 3.8. For . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

    3.9. Break y Continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

    3.10. Return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

    3.11. Objetos annimos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

    3.12. Funciones Locales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

    3.13. Compilacin condicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

    3.14. Tipado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

    3.14.1. Variables explcitamente tipadas . . . . . . . . . . . . . . . . . . . . 25

    3.14.2. Tipado esttico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

    3.15. Herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

    3.16. Tipado de Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

    3.16.1. Funciones de Alto Orden . . . . . . . . . . . . . . . . . . . . . . . . 27

    3.17. Inferencia de Tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

    3.18. El tipo Dinmico, librndonos del sistema tipado . . . . . . . . . . . . . . 29

    3.18.1. Asignando a variables dinmicas . . . . . . . . . . . . . . . . . . . . 29

    3.18.2. Asignando desde variables dinmicas . . . . . . . . . . . . . . . . . 29

    3.18.3. Funciones en variables Dinmicas . . . . . . . . . . . . . . . . . . . 30

    4. Arquitectura de un videojuego 31

    4.1. Game Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

    4.1.1. Frames Por Segundo (FPS) . . . . . . . . . . . . . . . . . . . . . . 32

    4.1.2. Manejando FPS en Haxeixel . . . . . . . . . . . . . . . . . . . . . 34

    4.2. Manejando Render() en Haxeixel . . . . . . . . . . . . . . . . . . . . . . . 35

    4.3. Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

    4.3.1. Event Dispatcher . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

    4.3.2. Event Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

    4.3.3. Manejando Input en Haxeixel . . . . . . . . . . . . . . . . . . . . 36

    4.4. Estados de Juego . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

    5. Sprites: La clase FlxSprite 39

    5.1. Mtodos importantes de FlxSprite . . . . . . . . . . . . . . . . . . . . . . . 39

    5.2. Algunos atributos de FlxSprite . . . . . . . . . . . . . . . . . . . . . . . . 39

    6. Proyectos en Haxeixel 41

    7. BreakOut 42

    7.1. La clase Main.hx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

    7.2. La clase Playstate.hx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

    7.2.1. Atributos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

    7.2.2. Mtodo Create . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

    7.2.3. Mtodo Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

    7.2.4. Funciones Callback . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

    7.3. Tarea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

    2

  • 8. Imgenes y Animaciones 48

    8.1. Sprites a partir de imgenes . . . . . . . . . . . . . . . . . . . . . . . . . . 48

    8.2. Animaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

    8.2.1. Comportamientos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

    9. Tiempo de carga, Loaders 51

    9.1. Loading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

    9.1.1. La clase: FlxAsyncLoop . . . . . . . . . . . . . . . . . . . . . . . . 52

    9.2. Analizando la Demo: FlxAsyncLoop . . . . . . . . . . . . . . . . . . . . . . 52

    9.2.1. La Clase Main.hx . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

    9.2.2. La clase MenuState . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

    9.3. Evitando problemas con: Recycling . . . . . . . . . . . . . . . . . . . . . . 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

    10.Sonidos y Msica 64

    10.1. La Clase: FlxSound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

    10.2. Tiempo de Carga de Sonidos y Recycling . . . . . . . . . . . . . . . . . . . 65

    10.3. Agregando un Sonido a un Estado . . . . . . . . . . . . . . . . . . . . . . . 65

    10.4. Sonidos de acuerdo a plataformas . . . . . . . . . . . . . . . . . . . . . . . 66

    10.5. Atributos de un Objeto FlxSound . . . . . . . . . . . . . . . . . . . . . . . 66

    10.6. Mtodos de un Objeto FlxSound . . . . . . . . . . . . . . . . . . . . . . . 67

    11.Guardando Datos 68

    11.1. La clase: FlxSave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

    11.1.1. Atributos de FlxSave . . . . . . . . . . . . . . . . . . . . . . . . . . 69

    11.1.2. Mtodos de FlxSave . . . . . . . . . . . . . . . . . . . . . . . . . . 70

    12.Cmaras y ScaleModes 71

    12.1. Qu es la cmara? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

    12.2. La clase: FlxCamera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

    12.2.1. Atributos de FlxCamera . . . . . . . . . . . . . . . . . . . . . . . . 72

    12.2.2. Mtodos de FlxCamera . . . . . . . . . . . . . . . . . . . . . . . . . 73

    12.2.3. Estilos Predenidos de FlxCamera . . . . . . . . . . . . . . . . . . 74

    13.Funcionalidad Avanzada 75

    13.1. Pixel Perfect Collision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

    13.2. Efectos sobre nuestros Sprites . . . . . . . . . . . . . . . . . . . . . . . . . 75

    13.2.1. FlxTween . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

    3

  • 13.2.2. TweenOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

    13.2.3. FlxGlitchSprite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

    13.2.4. FlxWaveSprite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

    13.2.5. FlxSpriteFilters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

    14.Tiles 83

    14.1. La clase: FlxTileMap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

    14.1.1. Mtodos de FlxTileMap . . . . . . . . . . . . . . . . . . . . . . . . 84

    14.1.2. FlxTimeMapExt . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

    14.1.3. FlxCaveGenerator . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

    15.Comunidad 88

    15.1. Comercializacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

    15.1.1. Publicidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

    15.1.2. Sponsors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

    15.1.3. Tiendas Online . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

    15.1.4. Venta Directa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

    15.1.5. Tiendas Indie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

    15.2. Redes Sociales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

    16.Game Jams 91

    16.1. Nuestro 3hr Game Jam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

    16.2. La palabra elegida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

    16.3. Nuestros Juegos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

    16.3.1. Chernobyl Walker . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

    16.3.2. Green Goo Jump . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

    16.3.3. Radiation Scape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

    16.3.4. Rodri Activo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

    16.4. Y el Ganador es! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

    4

  • 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: [email protected] por

    cualquier duda o correccin del mismo.

    Illbele Maximiliano.

    5

  • 1. Qu es y cmo se hace un videojuego?

    Para m los juegos son el arte supremo, el medio supremo. Es la suma total

    de todos los medios expresivos de todos los tiempos, hecho interactivo.

    Phil Fish

    El desarrollo de videojuegos combina muchos campos diferentes como ser edicin gr-

    ca, 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 interdisciplina. Es por esto

    que es recomendable intentar abandonar la idea del oo programando solo en su casa

    e intentando hacer todo, dando el paso inicial con el desarrollo de juegos, hacia el difcil

    camino del trabajo en equipo

    1

    .

    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

    de vista mientras entretienen a su pblico.

    Slo porque son arte no quiere decir que un videojuego tiene que ser expresivo para ser

    exitoso, 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 Papers Please que trata sobre la depresiva vida

    de un empleado de aduana que tiene que juntar suciente plata cada da para que su

    familia pueda sobrevivir

    2

    .

    Ninguno es mejor que otro, simplemente son juegos muy distintos, que apuntan a

    pblicos diferentes. Pero la clave es la siguiente: un videojuego debe entretener!

    Nadie va comprar un juego para colgarlo en la pared o exponerlo en un museo. La gente

    juega videjuegos porque est aburrida y quiere pasar el tiempo.

    La diferencia entre videojuegos y otras formas de arte es que son fuertemente in-

    teractivos. Digo fuertemente porque un libro puede ser interactivo o una obra de teatro

    puede involucrar al pblico, pero un videojuego depende completamente de la in-

    teraccin con el jugador para entretenerlo.

    Es por esto que para implementar esta interaccin en un videojuego necesitamos:

    1

    I.M: lo malo de trabajar en equipo es que el resto se equivoca.

    2

    R.P: suena aburrido pero les juro que es divertido, a la media hora de estar jugndolo no

    tena ms plata para pagar el alquiler y mi hijo haba muerto

    6

  • 1. Tener imgenes y sonidos.

    Interactuamos con un videojuego, en la misma forma en la que interactuamos con

    el mundo, con nuestros sentidos. Los sentidos que usamos para interactuar con los

    videojuegos son la vista, el tacto y el odio

    3

    , 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

    como imagen y la msica puede incluirse dentro de los sonidos

    4

    .

    2. Poder reaccionar ante las acciones del jugador.

    Si un juego no reacciona a mis acciones no es un juego, es una pelcula o algo por el

    estilo. Cmo puede nuestro juego mostrarle al jugador que sus acciones hacen algo?

    simplemente modicando imgenes y reproduciendo sonidos.

    Supongamos que estamos jugando un juego de plataforma y el jugador mueve el

    joystick a la derecha. Nosotros tenemos que hacer que su personaje se mueva a la

    derecha con una animacin como si caminara.

    3

    Error chistoso!

    4

    R.P: podramos discutir si es as pero no lo vamos a hacer.

    7

  • 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.

    A veces hacer nada es interactuar! Si jugaron el juego asteroides van a saber

    que si se quedan quietos eventualmente un asteroide va a chocar contra ustedes y

    los va matar. No moverse es una decisin que tomaron y el juego reacciona ante esa

    decisin. Y esa es la forma que normalmente aprendemos a jugar un juego, viendo

    cmo reacciona ante nuestros inputs. Si nunca jugaron PAC-MAN cmo van a saber

    que tienen que correr de los fantasmas? Murindose, no les queda otra.

    1.2. Qu diferencia a un juego de otro?

    Para hacer juegos originales primero tenemos que entender muy bien qu determina

    que un juego sea distinto de otro.

    Interfaz

    La interfaz es la forma en la que nos comunicamos con el juego. Son las acciones que

    el juego nos permite realizar. Si un juego usa una interfaz distinta, por ms que el

    resto del juego sea igual, es un juego distinto.

    Ahora, ustedes me dirn Pero un mario para PC que usa las echas no es el mismo

    que un mario para PC que usa W-A-S-D? No, no es lo mismo. Slo da la casualidad

    de que las teclas W-A-S-D tienen la misma distribucin que las teclas de las echas,

    entonces es prcticamente lo mismo. Si tuviramos que jugar a el mario con las teclas

    Q-N-P-Z sera un juego mucho ms difcil, y si se jugara con el mouse? Eso s que

    sera un juego distinto. Si quieren ver un juego que usa la interfaz de manera muy

    original juegen MultiTask

    5

    .

    Figura 1: Screen Shot del Multitask

    5

    http://www.kongregate.com/games/icylime/multitask

    8

  • Recursos: imgenes y sonidos.

    Los recursos son los objetos sobre los cuales podemos realizar cambios para inter-

    actuar con el juego, son la esencia del juego. Si un juego usa recursos distintos, por

    ms que el resto del juego sea igual, es un juego distinto.

    De nuevo, ustedes me dirn: un juego donde mario tiene un traje azul no es el

    mismo juego? No, es casi lo mismo, es una diferencia tan chica que prcticamente

    no se notara. Pero si cambiamos a mario por un pingino, y cambiamos pastos verdes

    por nieve y hielo: hablamos de SuperTux! Que es muy parecido a mario, pero es un

    juego distinto.

    Figura 2: Sreen Shoot De Supertux

    O si agarramos Crush the Castle, y cambiamos la catapulta por una hondera,

    piedras por pjaros, y personas por chanchos: hablamos de Angry Birds!

    Figura 3: Crush the Castle Versus Angry Birds

    9

  • Reglas de interaccin con el jugador.

    Las reglas de interaccin denen qu cambios producen las acciones del jugador sobre

    el juego. Qu pasa cuando toco a un monstruo? Qu pasa si pongo esta caja ac?

    Qu pasa si golpeo a este jarro con mi espada? Todas esas cosas estn denidas por

    las reglas de interaccin.

    Si un juego usa reglas distintas de interaccin con el jugador, por ms que el resto

    del juego sea igual, es un juego distinto. En Mario cuando salts sobre un enemigo,

    lo mats, pero si lo tocs de frente te mata. En Sonic pasa lo mismo, pero si ests

    rodando hecho bolita tambin los mats. Una diferencia en las reglas de interaccin

    que hace que los juegos sean distintos entre s.

    Reglas de Interaccin con los Recursos

    Recuerdan cuando dije que hacer nada tambin es interactuar en algunos casos.

    Eso es porque tambin hay reglas de interaccin entre los recursos del juego. En

    asteroids Cmo reaccionan los asteroides cuando se chocan entre ellos? Rebotan o

    se atraviesan? Cmo rebotan? Con 100% de elasticidad o van perdiendo velocidad?

    Giran al rebotar? Qu pasa cuando llegan al borde de la pantalla? Salen del otro

    lado o desaparecen? Si un juego usa reglas distintas de interaccin con los recursos,

    por ms que el resto del juego sea igual, es un juego distinto.

    En conclusin, un videojuego est compuesto por una interfaz, recursos, y reglas de

    interaccin entre ellos. Si cambiamos cualquiera de estos elementos, por ms que sea un

    cambio menor, estaramos cambiando el juego.

    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

  • muchas ms posibilidades. Por ejemplo, la deteccin de movimiento di lugar a toda una

    montaa de juegos nuevos.

    Sucede lo mismo con los recursos? El arte no tiene lmite. Distintas historias, msica,

    dibujos y animaciones, dan un toque nico a cada juego hacindolos distintos y atrayendo

    distintos gustos. Y no nos olvidemos de las reglas de interaccin, las maneras de interactuar

    con nuestros recursos son innitas. Hay juegos esperando ser creados!

    1.3. Gneros y Clones

    1.3.1. Gneros

    Igual que la mayora de formas de arte, un videojuego se puede clasicar en gneros.

    Dos juegos pertenecen al mismo gnero cuando, independiente de sus inter-

    faces 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 gneros que existen tambin son

    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.

    1.4. Juegos basados en otros

    A veces un juego usa reglas de interaccin claves de un juego y las cambia un poquito

    y crea un juego distinto Esto est genial! Porque el arte no se puede crear sobre el vaco

    ya que es el producto realizado por una persona basado en su cultura, sus pensamientos

    y sentimientos con una nalidad esttica o comunicativa.

    Los gneros se crean de esta manera. Un juego nuevo sale y dene un gnero, y despus

    salen un montn de juegos distintos basados sus conceptos claves. Distintos juegos pueden

    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

    6

    , 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.

    La plataforma afecta drsticamente a nuestra interfaz y a nuestros recursos.

    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 in-

    terfaz 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

    como ser la PC o una consola

    7

    .

    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.

    En conclusin: una plataforma es una tecnologa que permite la creacin de

    juegos y como toda tecnologa, tiene sus lmites. De todos modos la cantidad de

    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. Roles de un equipo de desarrollo

    Ahora vamos a describir los roles necesarios en un equipo de desarrollo de videojuegos.

    Las personas involucradas en un equipo de desarrollo de un juego pueden

    ocupar uno o ms roles. Por ejemplo, alguno de ustedes puede ser buen artista y

    entonces hace el diseo, la programacion o el arte y para la msica contrats a un tercero.

    En este curso, vamos a tomar los roles de programadores, diseadores y si hace fal-

    ta, guionistas. Si alguien tiene las capacidades para cubrir otro rol, mejor! Igual, no se

    preocupen, ms adelante en el curso vamos a ver las distintas maneras de conseguir los

    recursos hechos por otros personas dedicadas, ya sean gratis, o pagas.

    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

    8

    .

    Lamentablemente, es el rol menos apreciado por el pblico, porque es invisible

    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: Qu bien programado que est este juego.

    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.

    1.7. Herramientas disponibles

    Hay muchsimas herramientas disponibles para la creacin de videojuegos. Cuando

    alguien decide empezar a desarollar videojuegos normalmente la primer pregunta que se

    hace es: Qu lenguaje de programacin debera usar? No es una pregunta fcil

    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.1. Lenguaje de programacin

    Si alguien no sabe lo que es puede abandonar la lectura ahora mismo o quizs no. Con

    los lenguajes de programacin implementamos la lgica de un juego, pero cmo hacs

    para mostrar imagenes? Hacer animaciones? Poner msica? Responder a las acciones

    del jugador. Algunos lenguajes vienen ms preparados que otros para estas cosas, pero en

    la mayora de casos vamos a necesitar usar libreras.

    Ejemplos: Python, C++, Java, Haxe.

    1.7.2. Libreras

    Las libreras nos proveen una interfaz a componentes de ms bajo nivel para simpli-

    car 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:

    texture.loadFromFile(image.png).

    Ejemplos: SFML, PyGame, OpenFL.

    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 arqui-

    tectura 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.

    Obviamente lo haramos una sola vez y despus copy-paste, copy-paste

    9

    . Un framework

    nos alivia de esta tarea dndonos una arquitectura ya armada, que en el 99% de los casos

    es mejor programada de la que hubiramos hecho nosotros y por lo tanto mucho ms

    eciente. Los frameworks tambin cuentan con un montn de libreras para hacer mucho

    ms rpido cosas que tardaramos meses en hacer.

    Ejemplos: HaxeFlixel, FlashPunk, Phaser.

    1.7.4. Creadores de juegos

    El ms alto nivel que existe. A esta altura no podemos ver lneas de cdigo. Los

    creadores de juego son programas con una interfaz de usuario que facilitan la creacin

    de juegos. Algunos son especcos para ciertos gneros mientras que otros permiten la

    creacin de mltiples tipos de juegos.

    Ejemplos: RPG Maker, Construct2.

    9

    I.M: Si no existiera el copy-paste no cometeramos el 80% de los errores al programar.

    15

  • 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 framework Haxeixel, ms adelante voy a justicar

    esta eleccin. Pero recuerden que a su pblico, generalmente, no le interesa cmo fue

    hecho su juego. La programacin es invisible al pblico. Por eso no pierdan tiempo

    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

    2.1. Qu es Haxeixel? Por qu Haxeixel?

    Haxeixel es un framework construido sobre:

    1. Haxe: lenguaje de programacin multiplataforma.

    2. OpenFL: conjunto de libreras multiplataforma.

    Por qu Haxeixel?

    1. Multiplataforma.

    Con Haxeixel podemos hacer juegos para casi cualquier plataforma a veces sin tener

    que cambiar una sola lnea de cdigo

    10

    .

    2. 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. Equilibrio entre libertad y facilidad.

    Al trabajar con un framework, por no ser de tan alto nivel, no nos limita lo que

    podemos crear, como lo hara un creador de juego o algunos motores. Ni tampoco

    programamos a tan bajo nivel para obligarnos a programar componentes compli-

    cadas, utilizando una gran cantidad de horas para decidir por ejemplo en qu lugar

    queremos un botn.

    4. Hay juegos exitosos hechos con Haxe y OpenFL.

    Esto es muy importante, es deprimente encontrar una tecnologa con la cual uno

    se encuentra cmodo y descubrir que nadie nunca vendi un solo juego con eso.

    Papers Please es considerado el mejor juego independiente del 2013. Y est hecho

    en OpenFL. Ahora, Haxeixel es un framework por encima de OpenFL. Pero porque

    empiecen con Haxeixel no quiere decir que no puedan terminar trabajando solo con

    OpenFL. Es ms, va haber ciertas cosas en las cuales vamos a tener que usar OpenFL

    porque Haxeixel no ofrece una librera para eso. Inclusive Haxeixel es un excelente

    punto para empezar a hacer juegos ya mismo!

    10

    R.P: Yo compil un juego para ash y android sin cambiar nada

    17

  • 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 pre-

    sentamos 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: http://haxe.org/download As que no hace falta decir mucho ms que:

    Next, Next, Next, No leer nada, Agree, Next.

    2.4. Eligiendo un IDE

    Para Windows, recomiendo http://www.flashdevelop.org/. Es lo que uso para tra-

    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 recomien-

    do 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-

    ux, no deberan hacerse los inteligentes y usar Linux

    11

    . Si se les complica mucho instalarlo

    y usan Mac, deberan sentirse mal por usar Mac

    12

    .

    11

    R.P

    12

    R.P

    18

  • 3. Hello World en Haxe

    Now you're thinking with portals.

    Portal

    Abran un archivo nuevo en su editor de texto favorito y llmenlo Main.hx

    Escriban lo siguiente:

    1 class Main

    2 {

    3 public stat ic function main ( )

    4 {

    5 t r a c e ( " h e l l o world" ) ;

    6 }

    7 }

    Ahora compila de la siguente manera:

    haxe -main Main -neko helloworld.n

    Y lo ejecutan de la siguiente manera:

    neko helloworld.n

    Yey! Hemos hecho nuestro primer programa en Haxe.

    3.1. Syntax Bsico

    3.1.1. Constantes y sus tipos

    Bool: true, false.

    Int: 1234, -456, 0xF, 0xF0.

    Float: 0.72, -0.45, .50, 1e2.

    String: Hello World, `Goodbye Cruel World', Hello somebody.

    EReg: /[a-ZA-Z]+/.

    Unknown: null.

    3.1.2. Operadores Binarios y Unarios

    Asignacin: =, +=, *=, -=... (La asignacin devuelve el valor, permite hacer cadenas).

    Comparacin: ==, =.

    Operadores Aritmticos: +, -, *, /,%.

    Operadores Booleanos: &&, ||.Operadores Bitwise: |, &, >>, >.Operadores Unarios: !, , ++, .

    3.1.3. Bloques

    Los bloques son importantes en Haxe, herramienta til para simplicar algunas expre-

    siones. Los bloques estn delimitados por llaves { }. Lo que los hace especial en Haxe es

    19

  • que tienen un valor y un tipo. El valor de un bloque y su tipo es igual al de la ltima

    expresin de este bloque. Notar que bloques vacos son de tipo Void.

    Mostramos un ejemplo a continuacin mostrando cmo nos simplica el cdigo:

    1 public stat ic function main ( ) : Void

    2 {

    3 var s : String ;4 s = i f ( true ) {

    5 "Vrai " ;

    6 } else {

    7 "Faux" ;

    8 }

    9 t r a c e ( s ) ;

    10 }

    En otros lenguajes sera:

    1 public stat ic function main ( ) : Void

    2 {

    3 var s : String ;4 i f ( true ) {

    5 s = "Vrai " ;

    6 } else {

    7 s = "Faux" ;

    8 }

    9 t r a c e ( s ) ;

    10 }

    3.2. Declaracin de variables

    Una variable se declara con la palabra reservada var. Hay dos maneras de declarar

    una variable. Una es a nivel de clase, la otra es declarando variables locales en bloques de

    cdigo.

    1. A nivel de clase:

    [public|private][static]var varName[: varType][= someV alue];

    Las variables son por defecto privadas, a menos que la clase implemente la interface

    Public. Slo a las variables estticas se les puede dar un valor cuando son declaradas.

    2. En un bloque de cdigo:

    var varName [: varType][= varV alue];

    Una variable est disponible desde la lnea donde se declara hasta donde termina el

    bloque en que se declar.

    20

  • 1 class Main

    2 {

    3 public stat ic function main ( )

    4 {

    5 var myNumber : Int = 15 ;6 }

    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 stat ic function main ( )

    4 {

    5 var myNumber : Int = 15 ;6 myNumber = 2 ;

    7 t r a c e (myNumber) ; //Traces 2

    8 {

    9 var myNumber : Int = 1 ;10 t r a c e (myNumber) ; //Traces 1

    11 }

    12 t r a c e (myNumber) ; //Traces 2

    13 }

    14 }

    3.3. Acesso a campos y llamadas a funciones

    Para acceder a campos y llamar a mtodos en Haxe se utiliza la notacin de punto.

    As que si uno quiere acceder la variable name de un objeto llamado user se hace de la

    siguiente manera:

    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 sayHelloTo de un objeto llamado user.

    user.sayHelloTo(Mr, Benjamin);

    21

  • 3.4. Construyendo una instancia de una clase

    Se usa la palabra clave new:

    1 var user = new User ( "Mr" , "Benjamin" ) ;

    Un ejemplo de la clase User podra ser:

    1 class User

    2 {

    3 public function new( t i t l e : String , name : String) {

    4 //Do t h i n g s

    5 }

    6 }

    Se puede llamar al constructor de la superclase usando super() con parmetros si hiciera

    falta. Para acceder a la clase actual se usa la palabra clave this.

    3.5. If

    1 i f ( age < 16) {

    2 t r a c e ( "You are young" ) ;

    3 } else i f ( age >= 16 && age < 18) {

    4 t r a c e ( "You are almost an adul t " ) ;

    5 } else {

    6 t r a c e ( "You are an adult " ) ;

    7 }

    Tambin podemos usar lo que aprendimos de bloques:

    1 var age = 18 ;2 t r a c e (

    3 i f ( age

  • 3.7. While

    Hay dos syntax posibles. El while loop normal:

    1 while ( cond i t i on ) {

    2 exprToBeExecuted ;

    3 }

    Y el do while:

    1 do{

    2 exprToBeExecuted ;

    3 }while ( cond i t i on ) ;

    Ejemplos:

    1 while ( i< 18) {

    2 t r a c e ( i ) ; //Wil l t r a c e numbers from 0 to 17 inc luded

    3 i++;

    4 }

    1 do{

    2 t r a c e ( i ) ; //Wil l t r a c e numbers from 0 to 17 inc luded

    3 i++;

    4 } while ( i < 18) ;

    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 in 0 . . . 1 0 ) {

    2 t r a c e ( i ) ; // Wil l t r a c e numbers from 0 to 9

    3 }

    Nota: 0 . . . 10 es una construccin especial. El operador . . . recibe dos int y devuelve

    un interador

    13

    que devolver todos los int desde el primero (incluido) hasta el ltimo

    (excluido).

    Esta construccin es particularmente til para iterar sobre listas y arreglos.

    Por ejemplo:

    1 class TesthaXe

    2 {

    3 public stat ic function main ( ) : Void

    4 {

    5 var l = new List() ;6 l . add ( "He l lo " ) ;

    13

    Error Chistoso!

    23

  • 7 l . add ( "World" ) ;

    8 for ( s in l ) {

    9 neko . Lib . p r i n t l n ( s ) ;

    10 }

    11 }

    12 }

    3.9. Break y Continue

    La palabra break es usada para salir de un ciclo prematuramente.

    La palabra continue es usada para ir directamente a la siguente iteracin de nuestro

    ciclo sin ejecutar el cdigo despus de la palabra continue.

    3.10. Return

    La palabra clave return es usada para salir de una funcin o devolver un valor de una

    funcin (y salir).

    3.11. Objetos annimos

    Los objetos annimos pueden ser creados en cualquier momento utilizando llaves.

    var user = {age : 12, name : Benjamin};

    Figura 4: Haxe tiene DuckTyping

    24

  • 3.12. Funciones Locales

    Funciones locales son funciones sin un nombre, llamadas comnmente funciones ann-

    imas. Son valores que pueden ser asignados a cualquier variable, por ejemplo:

    1 public class User

    2 {

    3 var sayHe l lo :String Void ;4 public function new( ) {

    5 sayHe l lo = function( to : String) {

    6 t r a c e ( "He l lo " + to ) ;

    7 } ;

    8 sayHe l lo ( "World" ) ;

    9 }

    10 }

    Las funciones locales pueden acceder a cualquier variable local declarada en el mismo

    alcance que las variables estticas pero no pueden acceder la variable this.

    3.13. Compilacin condicional

    Haxe nos permite hacer compilacin condicional, esto signica que ciertas partes del

    cdigo son compiladas mientras que otras se ignoran dependiendo de las banderas que le

    damos al compilador y de qu plataforma tenemos como objetivo.

    Instrucciones de compilacin condicional siempre empiezan con el comando #if

    1#i f cpp

    2 //C++ code

    3 #elseif neko

    4 //Neko code

    5 #elseif php

    6 //PHP code

    7#else

    8 //Code f o r o ther t a r g e t s

    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:

    var myV ar : TypeOfMyV ariable;

    3.14.2. Tipado esttico

    En Haxe, una vez que una variable ha sido declarada y se sabe su tipo, no es posi-

    ble asignarle un valor de otro tipo. Aunque debera notarse que el compilador permite

    25

  • redeclarar una variable con el mismo nombre y otro tipo. As que el siguiente cdigo

    compila:

    1 class Main

    2 {

    3 public stat ic function main ( ) {

    4 var e : String ;5 e = " St r ing " ;

    6 var e : Int ;7 e = 12 ;

    8 }

    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 stat ic function main ( )

    4 {

    5 var e : String ;6 e = "Test " ;

    7 e = 12 ;

    8 }

    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 stat ic function main ( ) {

    4 var human : HumanBeing ;5 human = new HumanBeing ( "Benjamin" ) ;

    6 cong ra tu l a t e (human) ;

    7 }

    8 public stat ic function cong ra tu l a t e ( l t : LivingThing ) {

    9 t r a c e ( "Congrats " + l t . name) ;

    10 }

    14

    I.M: Por eso los programadores de Videojuegos lo hacen en las Game Jam en 24Hs.

    26

  • 11 }

    12

    13 class LivingThing

    14 {

    15 public var name : String ;16 public function new( ) {

    17 name = "" ;

    18 }

    19 }

    20

    21 class HumanBeing extends LivingThing

    22 {

    23 public function new(name : String)

    24 {

    25 super ( ) ;

    26 this . name = name ;

    27 }

    28 }

    (Haxe no tiene ningn tipo de multi-herencia. )

    3.16. Tipado de Funciones

    Las funciones tambin son tipadas. Esto es bueno por dos razones: es posible pasar

    una funcin como parmetro a otra funcin y guardar funciones tipadas en una variable.

    Expresando el tipo de una funcin

    Todas las funciones en Haxe son tipadas, as que por ejemplo, cuando uno escribe:

    1 public function outputStr ing ( s t : String) : Void ;

    Sabemos que la funcin outputString toma un parmetro de tipo String y devuelve

    Void, esto signica que no devuelve ningn objeto. El tipo de la funcin se representa de

    la siguiente manera:

    String V oidOtro ejemplo, la funcin:

    public function sumAndCeil(a : Float, b : Int) : Int;

    Tiene tipo:

    Float Int Int

    3.16.1. Funciones de Alto Orden

    Como mencionamos antes, una funcin puede tomar como argumento otra funcin.

    Esto es til por ejemplo para aplicar ltros en listas o arreglos. Hay tal cosa en la librera

    estndar:

    List.filter.

    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:

    public function filter(f : String Bool) : List < String >;

    Como deben haber adivinado, esta funcin toma una funcin como parmetro, pasa cada

    elemento de la lista a ella, si la funcin devuelve true, entonces suma ese elemento a una

    lista que devuelve.

    El tipo de esta funcin es el siguiente:

    (String Bool) List < String >

    Las funciones tambin pueden devolver una funcin; en este caso, simplemente tienes

    que poner los parntesis despus de la ltima echa del tipo:

    public function takesStringReturnsFunction(s : String) : String Bool;

    Esta funcin tiene el tipo:

    String (String Bool)Toma un String y devuelve una funcin que toma un String y devuelve un Bool. Llamando

    la funcin devuelta sera tan simple como escribir:

    takesStringReturnsFunction(Hello)(World);

    3.17. Inferencia de Tipos

    Cuando omitimos el tipo de una variable en el momento de su declaracin el compilador

    inferir el tipo de la variable segn el tipo utilizado en su primera referencia.

    Hay varias maneras de que el compilador adivine el tipo de tus variables.

    1. Asignando un Valor: cuando asigns un valor a una variable que tiene un tipo de-

    sconocido, su tipo ser inferido como el tipo de el valor asignado, as que por ejemplo,

    si escribs:

    1 var s ;2 s = "He l lo World" ;

    El tipo de s ser inferido a 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 var s ;2 var t : String ;3 s = t ;

    28

  • Ac el tipo inferido de s es String.

    3. Pasando la variable como parmetro de funcin

    Cuando pasas una variable a una funcin, su tipo es inferido como aquel que es

    esperado por la funcin. Por ejemplo:

    1 class Main

    2 {

    3 stat ic function pr in t ( s : String) {

    4 t r a c e ( s ) ;

    5 }

    6

    7 public stat ic function main ( ) {

    8 var t ;9 p r i n t ( t ) ;

    10 type ( t ) ;

    11 }

    12 }

    3.18. El tipo Dinmico, librndonos del sistema tipado

    Cuando uno dene una variable como tipo Dynamic, esto signica que el compilador

    no har ningn chequeo de tipos en esta variable en tiempos de compilacin.

    3.18.1. Asignando a variables dinmicas

    Cuando declars una variable como Dynamic, vas a poder asignarle cualquier valor en

    tiempo de compilacin. As que el siguiente cdigo es compilable:

    1 class DynamicTest

    2 {

    3 public stat ic function main ( ) {

    4 var dynamicVar : Dynamic ;5 dynamicVar = "He l lo " ;

    6 dynamicVar = 123 ;

    7 dynamicVar = {name : "John" , lastName : "Doe" } ;

    8 dynamicVar = new Array() ;

    9 }

    10 }

    No le va molestar al compilador aunque ests asignando distintos valores con distintos

    tipos a la misma variable.

    3.18.2. Asignando desde variables dinmicas

    Uno puede asignar el contenido de cualquier variable dinmica a una variable de

    cualquier tipo. Es ms, se podra decir que el tipo Dynamic puede ser usado en lugar

    de cualquier tipo y que una variable de tipo Dynamic es de cualquier tipo. Con eso en

    mente, uno puede ver que ahora se puede escribir y compilar este cdigo:

    29

  • 1 class DynamicTest

    2 {

    3 public stat ic function main ( ) {

    4 var dynamicVar : Dynamic ;5 var year : Int ;6 dynamicVar = "He l lo " ;

    7 year = dynamicVar ;

    8 }

    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 un comportamiento muy raro.

    3.18.3. Funciones en variables Dinmicas

    Tambin es posible guardar funciones en las variables Dynamic y llamarlas:

    1 class DynamicTest

    2 {

    3 public stat ic function main ( ) {

    4 var dynamicVar : Dynamic ;5 dynamicVar = function (name : String) {

    6 t r a c e ( "He l lo " + name) ;

    7 } ;

    8 dynamicVar ( ) ;

    9 }

    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.

    Antes de empezar a programar necesitamos aprender la arquitectura de un videojuego.

    Por ms que el framework implemente la arquitectura por nosotros, necesitamos entender

    cmo funciona para poder utilizarla. Lo que se va a ver al principio no es la forma de

    trabajo de Haxeixel, pero sirve para entender qu es lo que esta haciendo Haxeixel por

    nosotros.

    4.1. Game Loop

    El game loop es el cdigo central del juego, y normalmente tiene esta forma:

    1 while (mWindow. isOpen ( ) ) {

    2 Process Input ( ) ;

    3 Update ( ) ;

    4 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

    lo mueve, esa es la funcin del update.

    31

  • 4. El update actualiza la posicin del objeto movindolo una cierta distancia de acuerdo

    a la velocidad del objeto, dejndolo solapado sobre la pared.

    5. En el monitor todava no se vi ningn cambio.

    6. Ahora, dentro de la misma funcin update, despus de moverse segn la velocidad

    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 render, que dibuja todos los objetos sobre la pantalla.

    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.

    4.1.1. Frames Por Segundo (FPS)

    Ahora, nuestro game loop de antes tiene 2 problemas:

    No limita la cantidad de FPS.

    No corrige variaciones de FPS.

    Limitar los FPS

    Hay varios problemas que surgen de no limitar la cantidad de FPS.

    El primero sera que el juego corre a distintas velocidades en distintas computadoras,

    en algunos casos tan rpido que el juego se vuelve injugable.

    El segundo problema es que, si nuestro game loop corre ms rpido que la frecuencia

    del monitor, el monitor no va a tener tiempo de terminar nuestro pedido de render() antes

    de que le enviemos otro pedido de render(), vamos a ver lo que se llama screen tearing,

    que es cuando vemos una lnea horizontal en la pantalla porque una parte del juego est

    ms actualizada que otra.

    32

  • Figura 5: Ejemplo: Screen Tearing

    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 con-

    stante.

    Figura 6: El problema del lag y los FPS

    Solucin:

    Vamos a tener que agregar un poco de cdigo a nuestro game loop para poder corregir

    ambos problemas:

    33

  • 1 while (mWindow. isOpen ( ) )

    2 {

    3 timeSinceLastUpdate += c lock . r e s t a r t ( ) ;

    4 while ( t imeSinceLastUpdate > TimePerFrame )

    5 {

    6 timeSinceLastUpdate = TimePerFrame ;7 Process Input ( ) ;

    8 Update (TimePerFrame ) ;

    9 }

    10 Render ( ) ;

    11 }

    La condicin (timeSinceLastUpdate > TimePerFrame) corrige el primer error limi-

    tando los FPS para que no vayan ms rpido que TimePerFrame.

    El while que contiene esa condicin corrige el segundo error encargndose de correr el

    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 update ( )

    2 {

    3 this . x += 1 ;

    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 update (TimePerFrame : Float)

    2 {

    3 this . x += 60*TimePerFrame ;

    4 }

    Ahora s, sto se va a mover a 60 pxeles por segundo sin importar el FPS.

    4.1.2. Manejando FPS en Haxeixel

    Dentro del archivo GameClass.hx encontraremos:

    var frameRate : Int = 60;

    Para cambiar el framerate en el cual el juego debera correr simplemente cambiamos ese

    valor. Ni siquiera tenemos que pasar como argumento el valor TimePerFrame a la funcin

    update(). Si nos hiciera falta saber cunto tiempo paso desde el ltimo frame podemos

    acceder ese valor usando la siguiente variable:

    FlxG.elapsed

    34

  • Gracias a esto nuestro game loop volvera a:

    1 while (mWindow. isOpen ( ) ) {

    2 proce s s Input ( ) ;

    3 update ( ) ;

    4 render ( ) ;

    5 }

    4.2. Manejando Render() en Haxeixel

    En Haxeixel no tenemos que llamar la funcin render(). Lo nico que tenemos que

    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():

    add(newFlxText(0, 0, 100, Hello World!));

    Por lo tanto nuestro game loop queda:

    1 while (mWindow. isOpen ( ) ) {

    2 proce s s Input ( ) ;

    3 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

  • Event.SOUND_COMPLETE : un sonido termin su reproduccin.

    MouseEvent.CLICK: el mouse hizo click.

    KeyboardEvent.KEY_DOWN: una tecla fue presionada.

    4.3.1. Event Dispatcher

    Es un objeto que puede generar eventos. Event.SOUND_COMPLETE es generado por

    un objeto de tipo Sound cuando termina su reproduccin. En este caso nosotros podramos

    repetir el sonido o cambiarlo. Pero para hacer eso necesitamos otra cosa.

    4.3.2. Event Handler

    Son objetos que pueden manejar eventos. Uno le pide a un event handler que 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 Lib.current.stage.addEventListener(MouseEvent.MOUSE_DOWN,mousePressed);2 Lib.current.stage.addEventListener(MouseEvent.MOUSE_UP,mouseReleased);3

    4 private function mousePressed ( event :MouseEvent) : Void {

    5 f i r i n g = true ;

    6 }

    7

    8 private function mouseReleased ( event :MouseEvent) : Void {

    9 f i r i n g = fa l se ;

    10 }

    4.3.3. Manejando Input en Haxeixel

    Los eventos son usados en OpenFL pero no son tan usados en Flixel.

    En Flixel lo que hace es captura todos los eventos que ocurrieron entre el ltimo frame

    y el frame actual. Tambin podemos ver eventos continuos como por ejemplo, si una tecla

    est siendo continuamente apretada.

    1 i f (FlxG . keys . p re s s ed .DOWN) {

    2 //haga a l go

    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. isOpen ( ) ) {

    2 update ( ) ;

    3 }

    36

  • 4.4. Estados de Juego

    Hasta ahora nuestro Game Loop nos permite hacer juegos muy simples. Pero si quisiramos

    un juego que tiene un men con una intro, un men de opciones, un men de seleccin

    de niveles, los niveles en s, y por ltimo el Game Over.

    Organizar todo ese cdigo dentro de nuestra funcin update sera horrible y tedioso.

    Tendramos que estar agregando y sacando objetos con cada cambio de men y sera una

    sola funcin de cientos de lneas de cdigo.

    Por suerte el sistema de Estados nos facilita esto muchsimo. Cada men sera repre-

    sentado como un estado, cada uno con sus propios recursos y su propia funcin update.

    De esta manera cada estado tendra recursos distintos y respondera de manera distinta

    al jugador.

    Por ejemplo, los controles del juego slo deberan estr habilitados en el estado de

    juego. Mientras que en el men slo responde cuando se hace click sobre los botones de

    START o OPTIONS. Cambiar de estado se vuelve tan simple como llamar la funcin:

    FlxG.switchState(newPlayState());

    Figura 7: Estados de un Juego

    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

  • 5. Sprites: La clase FlxSprite

    Thank you Mario! But our princess is in another castle!

    Mario

    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.

    5.1. Mtodos importantes de FlxSprite

    loadGraphic() : recibe un string con el path de una imagen y la carga. Para poder

    ver la imagen el Sprite tiene que ser agregado a algn estado con add().

    makeGraphic(): se utiliza para crear imgenes a partir de rectngulos y un color, por

    ejemplo dibujar un cuadrado rojo.

    5.2. Algunos atributos de FlxSprite

    x : posicin horizontal del Sprite. Cero es el borde izquierdo de la pantalla e incre-

    menta hacia la derecha.

    y : posicin vertical del Sprite. Cero es el borde superior de la pantalla e incrementa

    hacia abajo.

    velocity : velocidad del Sprite, su posicin va cambiar de acuerdo a este valor en cada

    update(). Es una dupla (x,y), donde cada atributo guarda la velocidad horizontal y

    vertical respectivamente. Se acceden de la siguiente manera: velocity.x.

    acceleration : aceleracin del Sprite, su velocidad va cambiar de acuerdo a este valor

    en cada update(). Al igual que velocity es un punto con valores x e y, de tipo oat.

    scale: controla la escala de la imagen, es lo que modicamos si queremos agrandar o

    achicar la imagen. Tambin una dupla (x,y), de tipo oat.

    width: determina el ancho del hitbox del sprite que por defecto es el ancho de la

    imagen. El hitbox es el rea que se va usar para controlar si hay una colisin.

    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

    corre automticamente si el sprite fue agregado al estado que est corriendo

    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, siem-

    pre y cuando nos acordemos de llamar al mtodo super.update().

    40

  • 6. Proyectos en Haxeixel

    Game Over

    :p

    Ahora vamos a ver qu archivos y carpetas conforman un proyecto de Haxeixel y cul

    es la funcin de cada uno.

    Podemos crear un proyecto a partir de un template:

    flixel tpl n Nombre

    El comando nos crear un directorio con los siguientes archivos:

    Project.xml: contiene los settings de la aplicacin. Ac se denen opciones como

    resolucin, nombre de la aplicacin, fps, si es pantalla completa o no, orientacin de

    la pantalla si es un dispositivo mvil, etc.

    Main.hx: el main de nuestro juego. Este archivo es el nico que tiene cdigo de

    OpenFL, nunca vamos a tener que editarlo.

    Reg.hx: una clase para guardar valores globales estticos. Se usa para compartir

    valores entre distintos estados. Viene con varios ejemplos.

    GameClass.hx: esta clase contiene los settings del juego. La diferencia entre las op-

    ciones de esta clase y las opciones en Project.xml es que stas son las del juego

    mientras que las de Project.xml son las de la aplicacin (o si sirve para entenderlo

    mejor, de la ventana). El juego corre dentro de la aplicacin (o ventana), esto quiere

    decir que si Project.xml tiene una resolucin de 800x600 y GameClass.hx de 640x480

    el juego va correr dentro de una ventana de 800x600 pero slo va a ocupar 640x480.

    El resto va a tener el color de Background que hayamos denido en Project.xml.

    MenuState.hx y PlayState.hx son estados de juego vacos. Ac es donde vamos a

    escribir todo el cdigo de nuestro juego, creando otros estados ms si hiciera falta.

    Probablemente tambin tengamos que crear otras clases que extienden a FlxSprite.

    41

  • 7. BreakOut

    If people were inuenced by video games, then the

    majority of Facebook users would be farmers by now.

    Anonymous

    Prctico: analizando el cdigo de BreakOut

    Ahora en clase vamos a analizar el cdigo del demo BreakOut:

    Juego: http://haxeflixel.com/demos/Breakout/.

    Cdigo: https://github.com/HaxeFlixel/flixel-demos/tree/dev/Arcade%20Classics/

    Breakout.

    Comando para crear el proyecto de BreakOut: ixel create.

    Figura 8: Diagrama de Clases del Breakout

    7.1. La clase Main.hx

    La clase Main.hx, no tiene lgica simplemente crea al iniciar una intancia de PlayState,

    en ella lo nico que solemos cambiar son los siguientes atributos:

    1 var gameWidth : Int = 320 ; // Ancho de l juego en p i x e l s

    2 var gameHeight : Int = 240 ; // Alto d e l juego en p i x e l s

    3 var i n i t i a l S t a t e :Class = PlayState ; // Estado i n i c i a l .

    4 var zoom :Float = 1; // se acomode a l a s dimensiones de p an t a l l a5 var f ramerate : Int = 60 ;

    6 var sk ipSp la sh :Bool = fa l se ; //no muestre e l l o g u i t o de f l i x e l .

    42

  • 7.2. La clase Playstate.hx

    PlayState Hereda de la clase FlxState, y sobreescribe los mtodos create y update:

    7.2.1. Atributos

    1 class PlayState extends FlxState

    2 {

    3 private stat ic inl ine var BAT_SPEED: Int = 350 ;

    4

    5 private var _bat :FlxSprite ;

    6 private var _ball :FlxSprite ;

    7

    8 private var _walls :FlxGroup ;

    9 private var _leftWal l :FlxSprite ;

    10 private var _rightWall :FlxSprite ;

    11 private var _topWall :FlxSprite ;

    12 private var _bottomWall :FlxSprite ;

    13

    14 private var _bricks :FlxGroup ;

    7.2.2. Mtodo Create

    1 /* Funcin de inicializacin de todos l o s recur sos y a p o s t e r i o r i l o s

    agregamos a l estado , l a s paredes l a s inc lu imos en e l grupo

    _wal ls y l o s l a d r i l l o s tambin l o s inc lu imos en e l grupo

    _bricks Esto es una tcnica u t i l i z a d a en haxe para s im p l i f i c a r

    e l tema de l a s c o l i s i o n e s

    2 */

    3 override public function c r e a t e ( ) :Void

    4 {

    5 // Escondemos e l Mouse

    6 FlxG . mouse . v i s i b l e = fa l se ;

    7

    8 //Cramos e l ba te

    9 _bat = new FlxSpr i t e (180 , 220) ;

    10 _bat . makeGraphic (40 , 6 , FlxColor .HOT_PINK) ;

    11 _bat . immovable = true ;

    12

    13 //Creamos l a bo l a

    14 _ball = new FlxSpr i t e (180 , 160) ;

    15 _ball . makeGraphic (6 , 6 , FlxColor .HOT_PINK) ;

    16 _ball . e l a s t i c i t y = 1 ;

    17 _ball . maxVelocity . s e t (200 , 200) ;

    18 _ball . v e l o c i t y . y = 200 ;

    19

    20 // Ut i l i z a remos e l grupo wa l l s para s im p l i f i c a r e l tema de l a s

    c o l i s i o n e s

    21 _walls = new FlxGroup ( ) ;

    43

  • 22

    23

    24 //Pared I z qu i e r da

    25 _leftWal l = new FlxSpr i t e (0 , 0) ;

    26 _leftWal l . makeGraphic (10 , 240 , FlxColor .GRAY) ;

    27 _leftWal l . immovable = true ;

    28 _walls . add ( _leftWal l ) ;

    29

    30 //Pared Derecha

    31 _rightWall = new FlxSpr i t e (310 , 0) ;

    32 _rightWall . makeGraphic (10 , 240 , FlxColor .GRAY) ;

    33 _rightWall . immovable = true ;

    34 _walls . add ( _rightWall ) ;

    35

    36 //Pared de Arriba = Techo

    37 _topWall = new FlxSpr i t e (0 , 0) ;

    38 _topWall . makeGraphic (320 , 10 , FlxColor .GRAY) ;

    39 _topWall . immovable = true ;

    40 _walls . add (_topWall ) ;

    41

    42 //Pared de Abajo = Piso

    43 _bottomWall = new FlxSpr i t e (0 , 239) ;

    44 _bottomWall . makeGraphic (320 , 10 , FlxColor .TRANSPARENT) ;

    45 _bottomWall . immovable = true ;

    46 _walls . add (_bottomWall ) ;

    47

    48 // Some b r i c k s , creamos l o s l a d r i l l o s o b r i c k s a rromper

    49 _bricks = new FlxGroup ( ) ;

    50

    51 var bx : Int = 10 ;

    52 var by : Int = 30 ;

    53

    54 var br i ckCo lour s :Array = [0 xffd03ad1 , 0 x f f f 75352 , 0

    x f f fd8014 , 0 x f f f f 9 0 2 4 , 0 xf f05b320 , 0 x f f 6d65 f 6 ] ;

    55

    56 for ( y in 0 . . . 6 ) {

    57 for ( x in 0 . . . 2 0 ) {

    58 var tempBrick :FlxSprite = new FlxSpr i t e (bx , by ) ;

    59 tempBrick . makeGraphic (15 , 15 , br i ckCo lour s [ y ] ) ;

    60 tempBrick . immovable = true ;

    61 _bricks . add ( tempBrick ) ;

    62 bx += 15 ;

    63 }

    64 bx = 10 ;

    65 by += 15 ;

    66 }

    67

    68 // Agregamos a l e s tado todos l o s s p r i t e s que creamos

    69

    70 add ( _walls ) ;

    71 add (_bat ) ;

    44

  • 72 add ( _ball ) ;

    73 add ( _bricks ) ;

    74 }

    7.2.3. Mtodo Update

    1 override public function update ( ) :Void

    2 {

    3 super . update ( ) ;

    4 /* En cada l lamado a l a funcin update , seteamos l a v e l o c i dad

    de l ba t e a 0 e s t o es para que de j e de moverse s i no

    c l i ckeamos una direccin

    5 */

    6 _bat . v e l o c i t y . x = 0 ;

    7

    8 /* Unas lneas de cdigo para d i s p o s i t i v o s tctiles ( u t i l i z a n d o

    compilacin cond i c i ona l ) , l a idea de movimiento d e l ba t e es

    t r a s l a d a r s e d irec tamente a donde toc y s i hace un

    movimiento descendente con e l de to reseteamos e l e s tado .

    9 */

    10 #if !FLX_NO_TOUCH

    11 for ( touch in FlxG . touches . l i s t ) {

    12 i f ( touch . pre s s ed ) {

    13 i f ( touch . x > 10 && touch . x < 270)

    14 _bat . x = touch . x ;

    15 }

    16 }

    17

    18 for ( swipe in FlxG . swipes ) {

    19 i f ( swipe . d i s t anc e > 100) {

    20 i f ( ( swipe . ang le < 10 && swipe . ang le > 10) | | (swipe . ang le > 170 | | swipe . ang le < 170) ) {21 FlxG . r e s e t S t a t e ( ) ;

    22 }

    23 }

    24 }

    25 #end

    26

    27

    28 /*

    29 La idea a p o s t e r i o r i es escuchar l a s t e c l a s ( i zq , a ) ( der , b ) , s iocurri un evento a l teramos l a ve l oc idad , d e l ba te en esa

    direccin con e l v a l o r bat_speed

    30 */

    31 i f (FlxG . keys . anyPressed ( [ "LEFT" , "A" ] ) && _bat . x > 10) {

    32 _bat . v e l o c i t y . x = BAT_SPEED;33 } else i f (FlxG . keys . anyPressed ( [ "RIGHT" , "D" ] ) && _bat . x < 270) {

    34 _bat . v e l o c i t y . x = BAT_SPEED;

    35 }

    36 // Si apret l a l e t r a R reseteamos e l Juego .

    45

  • 37 i f (FlxG . keys . j u s tRe l ea s ed .R) {

    38 FlxG . r e s e t S t a t e ( ) ;

    39 }

    40 i f (_bat . x < 10) {

    41 _bat . x = 10 ;

    42 }

    43 i f (_bat . x > 270) {

    44 _bat . x = 270 ;

    45 }

    46

    47 /* Finalmente detectamos l a s c o l i s i o n e s

    48

    49 Recordamos que l a funcin c o l l i d e , u t i l i z a l a colisin fsica en t re l o s

    s p r i t e s , es d e c i r que e l funcionamiento luego d e l choque ya

    est d e f i n i d o por sus a t r i b u t o s .

    50 En e l caso de l a s c o l i s i o n e s en t re ( b a l l , b r i c k s ) se d e f i n e l a

    funcin c a l l b a c k h i t .

    51 En e l caso de l a s c o l i s i o n e s en t re ( b a l l , ba t ) se d e f i n e l a funcin

    c a l l b a c k ping .

    52 */

    53

    54 FlxG . c o l l i d e ( _ball , _walls ) ;

    55 FlxG . c o l l i d e (_bat , _ball , ping ) ;

    56 FlxG . c o l l i d e ( _ball , _bricks , h i t ) ;

    57 }

    7.2.4. Funciones Callback

    1 private function h i t ( Ba l l :FlxObject , Brick :FlxObject) :Void

    2 {

    3 Brick . e x i s t s = fa l se ;

    4 }

    5

    6 private function ping (Bat :FlxObject , Ba l l :FlxObject) :Void

    7 {

    8 var batmid : Int = Std . int (Bat . x ) + 20 ;

    9 var bal lmid : Int = Std . int ( Ba l l . x ) + 3 ;

    10 var d i f f : Int ;

    11

    12 i f ( ba l lmid < batmid ) {

    13 // Ba l l i s on the l e f t o f the ba t

    14 d i f f = batmid bal lmid ;15 Ba l l . v e l o c i t y . x = ( 10 * d i f f ) ;16 } else i f ( ba l lmid > batmid ) {

    17 // Ba l l on the r i g h t o f the ba t

    18 d i f f = bal lmid batmid ;19 Ba l l . v e l o c i t y . x = (10 * d i f f ) ;

    20 } else {

    21 // Ba l l i s p e r f e c t l y in the middle

    22 // A l i t t l e random X to s top i t bouncing up !

    46

  • 23 Ba l l . v e l o c i t y . x = 2 + FlxRandom . intRanged (0 , 8) ;

    24 }

    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 MakeGraph-

    ic(). Explicaremos ahora cmo generar sprites animados a partir de un sprite sheet.

    Tambin veremos cmo se usa la tcnica Recyling para hacer un juego ms eciente.

    8.1. Sprites a partir de imgenes

    Para cargar una imagen a un Sprite usamos la siguiente funcin:

    1 loadGraphic ( Graphic : Dynamic , ?Animated : Bool , ?Reverse : Bool , ?

    2 Width : Int , ?Height : Int , ?Unique : Bool , ?Key : String) : 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 : FlxSprite ;2 _ship = new FlxSpr i t e (x , y ) ;

    3 _ship . loadGraphic ( " a s s e t s / sh ip . png" ) ;

    4 add (_ship ) ;

    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 sprite sheet que consiste

    de una serie de imgenes o frames separados que formarn distintas animaciones.

    Por ejemplo, uno de los sprite sheets de Sonic 2 tendra esta pinta:

    Figura 9: Sprite sheet del Sonic 2

    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 las animaciones corren a su

    propio FrameRate.

    Ahora, veamos como usar la funcin loadGraphic() para cargar una animacin.

    1 loadGraphic ( Graphic : Dynamic , ?Animated : Bool , ?Width : Int , ?

    2 Height : Int , ?Unique : Bool , ?Key : String) : 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 _thie f : FlxSprite ;2 _th ie f = new FlxSpr i t e (x , y ) ;

    3 _th ie f . loadGraphic ( " a s s e t s / t h i e f . png" , true , 9 0 , 9 0 ) ;

    4 add ( _thie f ) ;

    Figura 10: Ladrn

    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 llama comportamiento y es una forma

    muy prctica que nos permite Haxeixel de organizar nuestro sprite sheet. Para agregar

    un comportamiento a un Sprite usamos el siguiente mtodo:

    1 animation . add (Name : String , Frames : Array, ?FrameRate : Int , ?

    Looped : Bool)

    Donde animation es un campo del Sprite que contiene nuestras animaciones.

    Name: indica el nombre del nuevo comportamiento para referenciarlo luego.

    Frames: un arreglo de nmeros indicando qu frames van a ser usados en este com-

    portamiento y en qu orden.

    FrameRate: establecemos el framerate al cual va correr este comportamiento. (As

    es, distintos comportamientos pueden tener distintos framerates.)

    Looped: indica si el comportamiento deber repetirse o slo ejecutarse una vez.

    Ejemplo:

    1 var _thie f : FlxSprite ;2 _th ie f = new FlxSpr i t e (x , y ) ;

    3 _th ie f . loadGraphic ( " a s s e t s / t h i e f . png" , true , 9 0 , 9 0 ) ;

    4 _th ie f . animation . add ( " d e f au l t " , [ 0 , 1 , 2 ] , 16 , true ) ;

    5 _th ie f . animation . play ( " d e f au l t " ) ;

    6 add ( _thie f ) ;

    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

  • 9. Tiempo de carga, Loaders

    When problem solving is removed from a game, it

    ceases to be a game and becomes just an activity.

    Jesse Schell - The Art of Game Design

    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 loader, que detallaremos a continuacin. A

    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 Recyling, que tambin explicaremos a continuacin.

    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.

    Figura 11: Loading Screens

    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.

    9.1.1. La clase: FlxAsyncLoop

    Por suerte HaxeFlixel nos provee la clase FlxAsyncLoop, que simplica mucho esto.

    Se usa de la siguiente manera:

    1 new FlxAsyncLoop(Iterations : Int, Callback : Void Void, IterationsPerUpdate : 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.

    9.2. Analizando la Demo: FlxAsyncLoop

    Podemos ver la demo entera en: http://haxeflixel.com/demos/FlxAsyncLoop/

    9.2.1. La Clase Main.hx

    Lo nico interesante para observar en la clase Main.hx es cmo dene las dimensiones

    del juego, su frame rate y el estado Inicial que va a llamarse cuando se ejecute Main:

    MenuState.

    1 class Main extends Sp r i t e {

    2 var gameWidth : Int = 640 ;

    3 var gameHeight : Int = 480 ;

    4 var i n i t i a l S t a t e :Class = MenuState ;

    5 var f ramerate : Int = 60 ;

    6 . . .

    7 }

    9.2.2. La clase MenuState

    Imports:

    1 package ;

    2 import 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 . F lxSpr i t e ;

    5 import f l i x e l . F lxState ;

    6 import f l i x e l . group . FlxGroup ;

    7 import f l i x e l . t ex 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 . F lxCo lo rUt i l ;

    10 import f l i x e l . u t i l . FlxRandom ;

    11 import f l i x e l . u t i l . F l xSp r i t eU t i l ;

    Atributos:

    1

    2 /* Creamos nues t ros drops grupos , uno para mostrar barra de progreso

    y o t ra que tenga l o que estemos por cargar : grpFin i shed */private

    var _grpProgress : FlxGroup ;

    3 private var _grpFinished :FlxGroup ;

    4 private var _loopOne :FlxAsyncLoop ;

    5 private var _maxItems : Int = 5000 ;

    6

    7 // Creamos una fancy progre s s bar

    8 private var _bar :FlxBar ;

    9

    10 // Agregamos una Barra de Texto a l a Barra de Progreso

    11 private var _barText :FlxText ;

    Mtodo Create:

    1 override public function c r e a t e ( ) :Void {

    2 _grpProgress = new FlxGroup ( ) ;

    3 _grpFinished = new FlxGroup (_maxItems ) ;

    4

    5 // Creamos nues tro Cic lo de Carga

    6 _loopOne = new FlxAsyncLoop (_maxItems , addItem , 100) ;

    7

    8 _bar = new FlxBar (0 , 0 , FlxBar .FILL_LEFT_TO_RIGHT, FlxG . width 50 ,50 , null , "" , 0 , 100 , true ) ;

    9 _bar . currentValue = 0 ;

    10 F l xSp r i t eUt i l . s c reenCenter (_bar ) ;

    11 _grpProgress . add (_bar ) ;

    12

    13 var aux = "Loading . . . 0 / " ;

    14 _barText = new FlxText (0 , 0 , FlxG . width , aux + _maxItems ) ;

    15