Desarrollando videojuegos con cocos2d-html5 (3): Un vistazo al Hello World

cocos2d-tutorial-3

Un vistazo al Hello World

El objetivo de esta parte del tutorial es ver el código del proyecto funcional más simple que viene incluido con la instalación de cocos2d-html5. A través del código aprenderemos los conceptos fundamentales de cocos2d para hacer un primer acercamiento.

Comencemos por conocer de antemano las dos tecnologías que veremos el día de hoy.

HTML5

HTML es un lenguaje que demarca segmentos en un documento mediante elementos. El resultado de escribir un documento en HTML es un árbol de estos elementos, comenzando desde lo más general: definir un documento HTML completo, hasta lo más específico, estableciendo textos, su significado semántico (si es un titular, si es un párrafo, si es un enlace, etc.), u otro tipo de elementos, como botones o cuadros de texto para un formulario.

El inicio y el fin de estos elementos se señala con etiquetas, las que vemos tan característicamente, <html>, <body>, <div>, etc. Como regla de etiqueta en HTML, toda etiqueta que se abre, se debe cerrar.

El 5 en HTML5 es porque actualmente estamos empleando la quinta revisión de este lenguaje. A diferencia de un lenguaje como Java, HTML es el resultado de varias empresas que producen esta especificación para que los navegadores puedan entenderlo. Esto da como resultado que algunos navegadores interpretan esa especificación de maneras ligeramente distintas, cosa que podría afectar nuestro desarrollo. Sin embargo, para el tipo de trabajo que haremos acá, y para la mayoría de los casos que veremos en el tutorial, nuestro código va a funcionar bien en varios navegadores.

Javascript

Javascript es el lenguaje de facto que acompaña a HTML. Casi todos los navegadores modernos pueden interpretar Javascript, y es el lenguaje que utilizaremos para todo el tutorial, siendo pocos los elementos de HTML realmente necesarios. Con Javascript somos capaces de quitar e introducir elementos en el documento HTML, además de acceder a otras funcionalidades del navegador.

Javascript es un lenguaje interpretado. Eso significa que el navegador es capaz de leerlo directamente y ejecutar las instrucciones de un archivo. Si necesitas hacer un cambio en un archivo, lo abres con un editor de texto, lo guardas y recargas la página para observar el resultado. Para mantener la seguridad del usuario, los navegadores limitan el poder de Javascript a hacer algunas cosas que no perjudiquen la computadora donde se ejecuta el script. Es suficiente decir que tenemos suficiente libertad para implementar juegos completos.

Veremos con cocos2d-html5 que emplearemos algunos conceptos de programación orientada a objetos. En particular, estaremos definiendo clases, un andamiaje de código que se ejecutará en el momento que inicialicemos la clase y pase a ser un objeto. Las clases son unidades de código que utilizaremos para agrupar (el término correcto es encapsular) funcionalidades del juego. Por ejemplo, tendremos una clase que representa a una escena. La escena se encarga de mostrar gráficamente el estado de un juego, dibujando gráficos en el canvas. Otra clase, el director, se utiliza para indicarle al juego que queremos cambiar de escena. Tanto el director como la escena contienen código que en general no necesitamos conocer su interior para saber cómo funcionan y cómo se usan.

Veremos una y otra vez en estos archivos que el código que contiene no se ejecuta al momento, sino que se irá ejecutando en la medida de lo necesario (es decir, cuando se cree el objeto y comience a tener vida), desde el punto de partida de la aplicación.

Estructura de un juego

El “juego” más sencillo que puedes hacer en cocos2d-html5 se encuentra en el directorio HelloHTML5World del paquete comprimido que descargaste en la parte anterior de este tutorial. Vamos a revisar algunos archivos importantes uno por uno.

index.html

Esta la página web a la que la gente accede para jugar el juego.

Tratar los elementos en HTML5 merecen un tutorial propio. Por ahora, lo importante es conocer dos elementos. El primero de ellos es canvas:

<canvas id="gameCanvas" width="800" height="450"></canvas>

…y script:

<script src="cocos2d.js"></script>

El primer elemento, canvas, es la zona rectangular donde se va a desplegar gráficamente el juego, y el segundo elemento, script, incluye un archivo que contiene el punto de partida de código del juego.

cocos2d.js

El archivo cocos2d.js contiene el punto de inicio del juego. Es una gran función anónima que se define y se ejecuta en el momento.

Este archivo contiene una configuración básica del juego: si va a utilizar alguna de las dos librerías físicas que cocos2d trae (box2d o chipmunk), si va a mostrar el número de frames por segundo (ideal mientras se desarrolla), y el listado de archivos que conforma el juego. También al finalizar el desarrollo del juego, para reducir el tamaño de la descarga se emplea una versión minificada de cocos2d, con la misma funcionalidad pero con el código comprimido para que ocupe menos espacio.

La funcionalidad de este archivo en general no cambia entre proyectos: su objetivo es introducir al documento todos los scripts Javascript que definen al juego, incluyendo los propios de cocos2d y los que hayas creado tú. Al introducirlos al documento se cargan y al finalizar este proceso se ejecuta el script main.js, que veremos a continuación.

main.js

El script main.js crea la Aplicación de cocos2d. La aplicación inicializa muchísimas cosas que accederemos posteriormente. Entre esos objetos está el Director, que es un objeto que podemos acceder desde cualquier parte del código para dar instrucciones del juego (por ejemplo, ir de una escena a otra). Iremos viendo en el resto del tutorial de qué maneras podemos emplear al director.

Este script también hace la precarga del listado de recursos que haremos del juego, de manera que la funcionalidad del juego no se vea afectada por recursos que aún no se hayan descargado. Al finalizar esta etapa, el juego se inicia con la escena HelloWorldScene.

resources.js

Resources.js es un importante archivo que tenemos que actualizar cada vez que introduzcamos un nuevo recurso al juego. Recurso es todo aquello que no sea código y que será desplegado gráficamente o auditivamente.

Son recursos las imágenes, los sonidos, las fuentes tipográficas (TrueType o bitmap) y los mapas de tiles.

No es exagerado volver a destacar la importancia de mantener el listado de recursos actualizado en este archivo. Muchos errores posteriores en la programación se deben a no tener este listado con todos los archivos.

Es buena práctica definir los nombres de los archivos en variables que inician con el nombre “s_”. Como dentro de las escenas los tenemos que volver a emplear, podemos referirnos a esas variables para no tener que repetir el camino al archivo, cosa que es fuente de errores comunes.

myApp.js

¡Finalmente! myApp.js define la funcionalidad del juego, tanto la manera como se dibujan las cosas en pantalla, como el gameplay del mismo. Más tarde en el tutorial veremos que combinar ambas funciones en un solo objeto no siempre es deseable, sobretodo en juegos grandes y complejos, pero por ahora y para mantener la simplicidad, lo dejaremos de esta manera.

Clases básicas

Notemos cuatro clases que emplearemos constantemente en cocos2d: escenas (Scenes), capas (Layers), sprites y menus. Todas estas cuatro clases son extensiones de una clase llamada Nodo, que tiene unas propiedades que los otros 4 comparten, como la posición. La clase Nodo nos vendrá útil en otro momento.

La primera clase es la Escena o Scene. Una escena representa una ventana para el jugador, lo que puede ver.  Así puedes agrupar funcionalidades por escena. Por ejemplo: una escena para el menú principal del juego, una escena para una partida, una escena para indicar la victoria o la derrota y una escena para introducir el nombre en una tabla de puntuaciones.

La segunda es el Sprite. El sprite es un recuadro relleno con alguna gráfica, y tiene propiedades como posición, escalamiento y rotación. Cada elemento que vayas a dibujar en la escena es un sprite.

La tercera es la Capa o Layer. La escena ya incluye por defecto una capa, pero los sprites se superponen unos a otros dependiendo del orden en el que son añadidos. Las capas permiten agrupar a los sprites con mayor facilidad. Cocos2d incluye algunos tipos especializados de capas que tienen funcionalidades particulares.

La cuarta es el Menu. El menú es un tipo de capa que solo puede contener un tipo de objeto llamado MenuItem. Los MenuItems encapsulan funcionalidad básica para interfaces de usuario, léase botones. En vez de tener que programarlo todo para recibir entradas del mouse o de una interfaz touch, los objetos MenuItems ya tienen casi todo lo necesario para tener ese comportamiento.

Cómo leer myApp.js

Para entender el myApp.js de este Hello World hay que irse al final del archivo. HelloWorld Scene es la clase que vimos inicializar en main.js. Extiende a una escena, y le pone una función llamada onEnter, que no es ejecutada directamente por el programador, sino que la ejecuta automáticamente la librería después de inicializar el código propio de Scene.

Específicamente, la función onEnter de HelloWorldScene crea una capa, la inicializa y luego la agrega a la capa por defecto de la escena. Vámonos entonces a HelloWorldLayer.

En HelloWorldLayer se extiende una capa para agregarle la funcionalidad principal de este programa. Todo el proceso de creación está contenido en la función init(). Se crea un MenuItem que contiene dos imágenes, una para el botón en estado normal, y otra para cuando ha sido seleccionado. Se incluye también una función anónima que le da qué hacer al botón al ser presionado.

Anchor points, posiciones y el sistema de coordenadas gráficas de cocos2d

Fíjense que el item tiene dos propiedades importantes, el anchor point y la posición, que se establecen con las funciones setAnchorPoint() y setPosition(), respectivamente.

El Anchor Point establece en un item, y en un sprite, cuál es el punto gráfico de origen del objeto. El punto está en dos dimensiones, y cada componente es un número real de 0 a 1. El 0 en el eje x representa el extremo izquierdo del sprite, y el 1, el extremo derecho. El 0 en el eje y representa el extremo inferior del sprite, y el 1, el extremo superior.

Por otro lado, la posición establece en qué parte de la pantalla se dibujará el item o sprite. En un juego de cocos2d, el punto (0, 0), el origen de la pantalla está ubicado en la esquina inferior izquierda. El eje x aumenta hacia la derecha, y el eje y aumenta hacia arriba.

Esto último suele ser fuente de confusión para los programadores de Flash, que vienen acostumbrados a que el origen de la ventana es la esquina superior izquierda, y el eje x aumenta hacia la derecha, y el eje y hacia abajo. La razón de este sistema de coordenadas es porque cocos2d en casi todas sus presentaciones está amoldado al sistema de coordenadas de OpenGL, que es la librería que por debajo de todo está desplegando los gráficos. Considérense advertidos.

En la función init veremos la creación de un label, que es el objeto que emplearemos para agregar texto. En otra parte del tutorial veremos cómo podemos dibujar texto. También vemos un tipo específico de capa llamado LazyLayer, propio de cocos2d-html5, y la creación de un sprite.

Creando sprites

Si estás acostumbrado a crear objetos con la instrucción new, verás que la convención de cocos2d es usar funciones fábrica, como cc.Sprite.create(), debido a la herencia que tiene la librería de Objective-C. En este caso, se le pasa el nombre de un archivo, y cocos2d se encarga de cargar el archivo, leerlo e interpretarlo para desplegarlo en pantalla.

Finalizando todo

Al final de la función init(), veremos también que se crean acciones y se ejecutan con la función runAction(). Las acciones son un poderoso concepto de cocos2d que permite hacer muchísimas cosas, componiéndolas en código. Esto lo dejaremos para otra parte del tutorial.

Finalmente, llamamos a la función setTouchEnabled() para indicarle a cocos2d que este objeto va a procesar las entradas que se hagan con un dispositivo multi-touch, como un smartphone o tableta. Para poder procesar esas entradas, se escriben las funciones onTouchesBegan, onTouchesMoved, onTouchesEnded y onTouchesCancelled. Esto también lo detallaremos más adelante.

También existe dentro de myApp.js la función adjustSizeForWindow() que permite redimensionar automáticamente el elemento canvas para que ocupe la pantalla del navegador completamente y se actualice cuando cambias el tamaño de la ventana. Dejo esto como ejercicio para entender.

Más adelante

En la próxima parte del tutorial, iniciaremos un nuevo proyecto a partir de HelloWorld para cambiar algunas cosas y terminar de entender los conceptos que vimos en esta parte.

Navegar la seriePost anterior en la seriePróximo post en la serie

3 comentarios en «Desarrollando videojuegos con cocos2d-html5 (3): Un vistazo al Hello World»

Deja un comentario