Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Tile-Based Games
Gamedevelopment

Una introducción a la creación de un motor de mapas de mosaicos

by
Difficulty:IntermediateLength:LongLanguages:

Spanish (Español) translation by Elías Nicolás (you can also view the original English article)

En este tutorial, te ayudaré a crear niveles para cualquier género de juegos y a hacer que los niveles de diseño sean mucho más fáciles. Aprenderá cómo crear su primer motor de mapas de mosaicos para usar en cualquiera de sus proyectos futuros. Usaré Haxe con OpenFL, pero deberías poder seguirlo en cualquier idioma.

Esto es lo que trataremos:

  • ¿Qué es un juego basado en fichas?
  • Encontrar o hacer tus propios cuadros.
  • Escribir el código para mostrar los mosaicos en la pantalla.
  • Edición de diseños de mosaicos para diferentes niveles.

¡También puedes comenzar bien una nueva idea de juego!


¿Qué es un juego basado en mosaicos?

Naturalmente, Wikipedia tiene una definición en profundidad de lo que es un juego basado en mosaicos, pero para obtener la esencia básica hay solo algunas cosas que debes saber:

  1. Un mosaico es una imagen pequeña, generalmente rectangular o isométrica, que actúa como una pieza de arte del rompecabezas para crear imágenes más grandes.
  2. Un mapa es una agrupación de mosaicos reunidos para crear una (esperemos) "sección" visualmente atractiva (como un nivel o área).
  3. Basado en mosaicos se refiere al método de construcción de niveles en un juego. El código diseñará mosaicos en ubicaciones específicas para cubrir el área prevista.

Para ser aún más básico, lo pondré así:

Un juego basado en mosaicos establece fichas para crear cada nivel.

En referencia a los tipos de mosaicos comunes, rectangulares e isométricos, usaremos mosaicos rectangulares en este artículo por su simplicidad. Si decides probar los niveles isométricos algún día, hay matemática adicional involucrada para que funcione. (Una vez que hayas terminado aquí, echa un vistazo a este gran manual para crear mundos isométricos).

Hay algunos beneficios geniales que obtienes al usar un motor de mosaicos. La ventaja más evidente es que no necesitará crear imágenes masivas a mano para cada nivel individual. Esto reducirá el tiempo de desarrollo y reducirá el tamaño de los archivos. Tener 50 imágenes de 1280x768px para un juego de 50 niveles vs tener una imagen con 100 hace una gran diferencia.

Otro efecto colateral es que ubicar cosas en tu mapa usando código se vuelve un poco más fácil. En lugar de verificar cosas como una colisión basada en un píxel exacto, puede usar una fórmula rápida y fácil para determinar a qué mosaico necesita acceder. (Voy a repasar eso un poco más tarde).


Encontrar o hacer tus propios azulejos

Lo primero que necesitará al construir su motor de mosaico es un conjunto de mosaicos. Tienes dos opciones: usar las de otra persona, o hacer las tuyas propias.

Si decide utilizar mosaicos que ya se han creado, puede encontrar arte disponible gratuitamente en toda la web. La desventaja de esto es que el arte no se hizo específicamente para tu juego. Por otro lado, si solo estás creando prototipos o intentando aprender un nuevo concepto, las fichas gratuitas funcionarán.

Donde encontrar tus azulejos

Existen bastantes recursos para el arte libre y de código abierto. Aquí hay algunos lugares para comenzar su búsqueda:

  1. OpenGameArt.org
  2. Let's Make Games
  3. Pixel Prospector

Esos tres enlaces deberían darle lugares más que suficientes para encontrar algunos para sus prototipos. Antes de enloquecer agarrando todo lo que encuentres, asegúrate de entender en qué licencia está cubierto todo y con qué restricciones vienen. Muchas licencias le permitirán usar el arte libremente y para uso comercial, pero pueden requerir atribución.

Para este tutorial, utilicé algunas fichas de The Open Game Art Bundle para plataformas. Puede descargar mis versiones reducidas o los originales.

Cómo hacer tus propios azulejos

Si aún no te has dado el lujo de hacer arte para tus juegos, puede ser un poco intimidante. Afortunadamente, hay algunas piezas de software asombrosas y simples que te llevan al centro de todo para que puedas comenzar a practicar.

Muchos desarrolladores comienzan con el arte de píxeles para sus juegos y aquí hay algunas excelentes herramientas para eso:

  1. Aseprite
  2. Pyxel Edit
  3. Graphics Gale
  4. Pixen para los usuarios de Mac

Estos son algunos de los programas más populares para hacer pixel art. Si quieres algo un poco más poderoso, GIMP es una excelente opción. También puede hacer algunas ilustraciones vectoriales con Inkscape y seguir algunos tutoriales sorprendentes en 2D Game Art For Programmers.

Una vez que agarras el software, puedes comenzar a experimentar con tus propios mosaicos. Como este tutorial está destinado a mostrarte cómo crear tu motor de mapas de mosaicos, no entraré en demasiados detalles sobre cómo crear los mosaicos, pero hay algo que siempre debes tener en cuenta:

Asegúrate de que tus fichas encajen perfectamente y agrega alguna variación para mantenerlas interesantes.

Si tus fichas muestran líneas obvias entre ellos cuando se juntan, tu juego no se verá muy bien. Asegúrate de dedicar algo de tiempo a la creación de un bonito "rompecabezas" de mosaicos al hacerlos perfectos y agregar alguna variación.


Escribir el código para mostrar los mosaicos

Ahora que hemos sacado todo el material del arte, podemos sumergirnos en el código para poner las fichas recién adquiridas (o creadas) en la pantalla.

Cómo mostrar un solo mosaico en la pantalla

Comencemos con la tarea básica de mostrar un solo mosaico en la pantalla. Asegúrate de que tus fichas sean del mismo tamaño y se guarden en archivos de imagen separados (más adelante hablaremos sobre las hojas de sprites).

Una vez que tenga los mosaicos en la carpeta de activos de su proyecto, puede escribir una clase de mosaico Tile muy simple.  Aquí hay un ejemplo en Haxe:

Como todo lo que estamos haciendo ahora es colocar un solo mosaico en la pantalla, lo único que hace la clase es importar la imagen del mosaico desde la carpeta de activos assets y agregarla como un elemento secundario al objeto.  Es probable que esta clase varíe mucho según el lenguaje de programación que utilice, pero debería poder encontrar fácilmente una guía sobre cómo mostrar una imagen en la pantalla.

Ahora que tenemos una clase de mosaico Tile , necesitamos crear una instancia de un mosaico Tile y agregarlo a nuestra clase principal:

La clase principal Main crea un nuevo mosaico Tile cuando se llama al constructor (se llama a la función new() cuando se inicia el juego) y se agrega a la lista de visualización.

Cuando se ejecuta el juego, también se llamará a la función main() y se agregará un nuevo objeto Main al escenario. Ahora debería tener su mosaico en la parte superior izquierda de la pantalla. Hasta aquí todo bien.

Sugerencia: si nada de eso tiene sentido,¡no se preocupe! Es solo el código estándar de Haxe. La clave para entender es que esto crea un objeto Tile y lo agrega a la pantalla.

Usar matrices para diseñar una pantalla completa de mosaicos

El siguiente paso es encontrar una forma de llenar toda la pantalla con mosaicos. Una de las formas más sencillas de hacerlo es completar una matriz con números enteros que representan una ID de mosaico tile ID. Luego puede iterar a través de la matriz para decidir qué mosaico mostrar y dónde mostrarlo.

Usted tiene la opción de usar una matriz típica o utilizar una matriz bidimensional. En caso de que no esté familiarizado con las matrices en 2D, es básicamente una única matriz que está llena de matrices múltiples. La mayoría de los lenguajes indicarán esto como nameOfArray[x][y] donde x e y son índices para acceder a un solo elemento.

Como x e y también se usan para coordenadas de pantalla, podría tener sentido usar x e y como coordenadas para nuestros mosaicos. El truco con las matrices 2D es entender cómo se organizan los enteros. Es posible que tenga que invertir la y y la x al iterar a través de las matrices (ejemplo a continuación).

Observe que en esta implementación, el elemento "0º" en la matriz es en sí mismo una matriz de cinco enteros. Esto significa que accedes a cada elemento con y primero y, luego x. Si intenta acceder al exampleArr[1][0], accederá al sexto mosaico.

Si aún no comprende cómo funcionan las matrices en 2D, no se preocupe. Para este tutorial usaré una matriz normal para mantener las cosas simples y hacer que las cosas sean más fáciles de visualizar:

El ejemplo anterior muestra cómo una matriz normal puede ser un poco más simple. Podemos visualizar exactamente dónde estará el mosaico y todo lo que tenemos que hacer es usar una fórmula simple (¡no te preocupes, viene!) Para obtener el azulejo que queremos.

Ahora vamos a escribir un código para crear nuestra matriz y llenarla con unos. El número uno será el ID que representa nuestro primer mosaico.

Primero, necesitamos crear una variable dentro de nuestra clase principal para mantener nuestra matriz:

Esto puede parecer un poco extraño, así que lo analizaré por ti.

El nombre de la variable es un mapa y le he dado un tipo muy específico: Matriz Array. La porción <Int> simplemente le dice a nuestro programa que la matriz solo contendrá enteros.  Las matrices pueden albergar casi cualquier tipo que desee, de modo que si está utilizando otra cosa para identificar sus teselas, puede cambiar el parámetro aquí.

A continuación tenemos que agregar un código al constructor de nuestra clase principal Main (recuerde, esta es la función new() ) para que podamos crear una instancia de nuestro mapa:

Esta línea creará un conjunto vacío que podemos llenar pronto con nuestros para probarlo. Primero, definamos algunos valores que nos ayudarán con nuestras matemáticas:

He hecho que estos valores sean public static porque esto nos dará acceso a ellos desde cualquier lugar de nuestro programa (a través de Main.Tile_WIDTH, etc.). Además, habrás notado que dividir SCREEN_WIDTH por TILE_WIDTH nos da 10 y dividir SCREEN_HEIGHT por TILE_HEIGHT nos da 6. Esos dos números se usarán para decidir cuántos enteros almacenar en nuestra matriz.

En este bloque de código, asignamos 10 y 6 a w y h, como mencioné anteriormente. Luego, debemos saltar a un bucle for para crear una matriz que pueda contener números enteros de 10 * 6. Esto representará suficientes teselas para llenar toda la pantalla.

tileMapDiagram1

Ahora tenemos nuestro mapa básico construido, pero ¿cómo vamos a decirle a los mosaicos que se coloquen en el lugar correcto? Para eso tenemos que volver a la clase Tile y crear una función que nos permita mover fichas a voluntad:

Cuando llamamos a la función setLoc (), pasamos las coordenadas x e y de acuerdo con nuestra clase de mapa (¡la fórmula llegará pronto, ¡lo prometo!). La función toma esos valores y los traduce en coordenadas de píxeles multiplicándolos por TILE_WIDTH y TILE_HEIGHT, respectivamente.

Lo único que queda por hacer para obtener nuestros mosaicos en la pantalla es decirle a nuestra clase principal Main que cree los mosaicos y los coloque en su lugar en función de su ubicación dentro del mapa.  Volvamos a Main e implementamos eso:

¡Oh si! Así es, ahora tenemos una pantalla llena de mosaicos. Analicemos lo que está sucediendo arriba.

La formula

La fórmula que sigo mencionando finalmente está aquí.

Calculamos x tomando el módulo (%) de i y w (que es 10, recuerda).

El módulo es solo el resto después de la división entera: \(14 \div 3 = 4 \text{ resto } 2\) así \(14 \text {modulo} 3 = 2 \).

Usamos esto porque queremos que nuestro valor de x vuelva a 0 en el inicio de cada fila, así que dibujamos el mosaico respectivo en el extremo izquierdo:

tile_grid_cols

En cuanto a y, tomamos el floor() de i / w (es decir, redondeamos ese resultado) porque solo queremos que y aumente una vez que hayamos llegado al final de cada fila y bajado un nivel:

tile_grid_rows
Sugerencia: la mayoría de los idiomas no requieren que invoque Math.floor() al dividir enteros; Haxe solo maneja la división entera de manera diferente. Si está utilizando un idioma que hace división de enteros, puede usar i / w (suponiendo que ambos sean enteros).

Por último, quería mencionar un poco sobre los niveles de desplazamiento. Por lo general, no creará niveles que se ajusten perfectamente a su ventana gráfica. Es probable que tus mapas sean mucho más grandes que la pantalla y no quieras seguir dibujando imágenes que el jugador no podrá ver. Con algunas matemáticas rápidas y fáciles, deberías poder calcular qué fichas deberían estar en la pantalla y qué fichas para evitar dibujar.

Por ejemplo: el tamaño de su pantalla es 500x500, sus mosaicos son 100x100 y su tamaño mundial es 1000x1000. Simplemente necesitaría hacer una comprobación rápida antes de dibujar fichas para descubrir qué fichas están en pantalla. Usando la ubicación de su ventana gráfica, digamos 400x500, solo necesitaría dibujar las fichas de las filas 4 a 9 y las columnas 5 a 10. Puede obtener esos números dividiendo la ubicación por el tamaño de la tesela, y luego compensando esos valores con la pantalla tamaño dividido por el tamaño del azulejo. Sencillo.

Puede que aún no se parezca mucho, ya que todas las fichas son iguales, pero la base está casi lista. Lo único que queda por hacer es crear diferentes tipos de mosaicos y diseñar nuestro mapa para que se alineen y creen algo agradable.


Edición de diseños de mosaico para diferentes niveles

Muy bien, ahora tenemos un mapa que está lleno de los que cubre la pantalla. En este punto, debe tener más de un tipo de mosaico, lo que significa que tenemos que cambiar nuestro constructor de mosaico Tile para dar cuenta de eso:

Como utilicé seis fichas diferentes para mi mapa, necesitaba una declaración de cambio switch que cubriera los números del uno al seis. Notarás que el constructor ahora toma un entero como parámetro para que sepamos qué tipo de mosaico crear.

Ahora, tenemos que volver a nuestro constructor Main y arreglar la creación del mosaico en nuestro ciclo for:

Todo lo que teníamos que hacer era pasar el map[i] al constructor de Tile para que funcione nuevamente. Si intenta ejecutar sin pasar un número entero a Tile, le dará algunos errores.

Casi todo está en su lugar, pero ahora necesitamos una forma de diseñar mapas en lugar de llenarlos con mosaicos aleatorios. Primero, elimine el bucle for en el constructor Main que establece cada elemento en uno. Entonces podemos crear nuestro propio mapa a mano:

Si formatea la matriz como lo hice anteriormente, puede ver fácilmente cómo se organizarán nuestras fichas. También puede simplemente ingresar la matriz como una larga línea de números, pero la primera es agradable porque puede ver 10 a través y 6 abajo.

Cuando intente ejecutar el programa ahora, debería obtener algunas excepciones de puntero nulo. El problema es que estamos usando ceros en nuestro mapa y nuestra clase Tile no sabe qué hacer con un cero. Primero, arreglaremos el constructor agregando una marca antes de agregar la imagen secundaria:

Esta comprobación rápida asegura que no estamos agregando ningún nulo a los objetos de mosaico Tile que creamos.  El último cambio para esta clase es la función setLoc(). En este momento estamos tratando de establecer los valores x e y para una variable que no se ha inicializado.

Agreguemos otra verificación rápida:

Con esas dos correcciones simples en su lugar, y las fichas que proporcioné arriba, deberías poder ejecutar el juego y ver un nivel de plataformas simple. Como dejamos 0 como un "no mosaico", podemos dejarlo transparente (vacío). Si desea darle vida al nivel, puede poner un fondo antes de diseñar las fichas; Acabo de agregar un degradado azul claro para que parezca un cielo en el fondo.

tileMapDiagram2

Eso es prácticamente todo lo que necesita para configurar una forma sencilla de editar sus niveles. Intente experimentar un poco con la matriz y vea qué diseños puede obtener para otros niveles.

Software de terceros para diseñar niveles

Una vez que tenga lo básico, puede considerar usar otras herramientas para ayudarlo a diseñar niveles rápidamente y ver cómo son antes de lanzarlos al juego. Una opción es crear tu propio editor de niveles. La alternativa es tomar algún software que esté disponible de forma gratuita. Las dos herramientas populares son Tiled Map Editor y Ogmo Editor. Ambos hacen la edición de niveles mucho más fácil con múltiples opciones de exportación.


¡Acabas de crear un motor basado en mosaico!

Ahora ya sabe qué es un juego basado en fichas, cómo obtener algunas fichas para sus niveles, y cómo ensuciarse las manos y escribir el código para su motor, e incluso puede hacer una edición de nivel básico con una matriz simple . Solo recuerda que esto es solo el comienzo; hay mucha experimentación que puedes hacer para hacer un motor aún mejor.

Además, proporcioné los archivos fuente para que los revises. Así es como se ve el SWF final:

Descargue el SWF aquí....

...y aquí, de nuevo, está la matriz de la que se genera:

¡No te detengas aquí!

Tu próxima tarea es investigar un poco y probar algunas cosas nuevas para mejorar lo que hiciste aquí. Las hojas de Sprite son una excelente manera de mejorar el rendimiento y facilitar la vida. El truco es obtener un código sólido diseñado para leer desde una hoja de sprites, de modo que su juego no tenga que leer cada imagen individualmente.

También deberías comenzar a practicar tus habilidades artísticas haciendo algunos tilesets propios. De esa forma puedes obtener el arte correcto para tus juegos futuros.

Como siempre, deje algunos comentarios a continuación sobre cómo funciona su motor para usted, y tal vez incluso algunas demostraciones para que podamos probar su próximo juego de fichas.

Elías Nicolás
Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.