¿La mejor manera de crear un mapa para un juego 2D?

16

Pido disculpas por la palabra clave subjetiva "mejor".

Mi amigo y yo hemos comenzado la creación de un juego de aventuras en 2D. Será de arriba hacia abajo en el estilo de pokemon o zelda (solo la perspectiva). Hemos estado discutiendo métodos para crear un gran mapamundi que el jugador pueda atravesar sin forzar las capacidades de memoria de nuestra máquina.

Nuestro primer impulso fue crear un mapa grande y un círculo alrededor del jugador en el que se cargará el contenido. Supusimos que esto no durará mucho tiempo y decidimos dividir el mapa en secciones. Primero teníamos cuatro secciones grandes, pero nos dimos cuenta de que simplemente podíamos dividirlo en muchas secciones pequeñas.

Jugué un poco de Zelda del SNES y vi que, durante el cambio de un mapa, el contenido se podía cargar en ese momento. Lo que quiero decir es que, en lugar de simplemente verificar un área rectangular para que se carguen los datos, simplemente seccionamos el mapa en muchos fragmentos pequeños que cargan y descargan datos a medida que nos movemos de una porción de mapa a otra.

Hoy, me dijo que quería crear un simple mapa de matriz 2D [ANCHO] [ALTURA] que contiene datos sobre cada cuadrícula en el juego y es una operación constante de guardar en disco para datos que no necesitamos.

No estoy seguro de estas ideas y pensé que podría hacerlo aquí. Cualquier enlace, recursos o tutoriales sobre el tema serán muy apreciados, así como respuestas directas a nuestra pregunta sobre cómo hacerlo de manera eficiente.

IAE
fuente
¿Qué máquina estás usando?
David Titarenco
Windows con C ++ usando SFML hasta ahora (SFML está sujeto a cambios; C ++ no). No estamos apuntando a la portabilidad atm.
IAE
2
Si vas por la vieja escuela, Zelda en el NES usa mapas de 1 pantalla solamente. Los mapas pequeños ayudan a los jugadores a enfocar el alcance de su intención (es decir, en una mazmorra, solo se trata de su habitación. En diablo, los monstruos no se movían arriba y abajo de los pisos) y les permiten sentirse completos si han buscado en toda el área que los juegos en espacios abiertos como FAllout3 y Oblivion no te dan.
Stephen Furlani el

Respuestas:

27

En primer lugar, estima el tamaño de tu mapa. No asuma que un "gran mundo" no va a caber en la memoria. Hoy en día, un mapa que ocupa más de 10 mb en memoria es absolutamente aceptable, y puede rellenar MUCHO en 10 mb en un simple mundo 2D basado en mosaicos.

Si tiene un mundo realmente grande, la solución más sólida es utilizar trozos de mapa. Divide tu mundo en trozos de tamaño fijo (por ejemplo, 64x64). Cargue trozos sobre la marcha a medida que el jugador se mueve, manteniendo al menos un trozo cargado en todas las direcciones (es decir, cargue el trozo en el que se encuentra el jugador y todos sus vecinos).

En cuanto a la descarga de fragmentos, puede elegir entre varias estrategias. Descargar con impaciencia significa descargar y guardar en el disco todos los fragmentos en el momento en que el jugador se aleja lo suficiente; pero también puede retrasar la descarga para mejorar el rendimiento (guardar trozos, como cualquier acceso al disco, es una operación costosa).

No importa
fuente
66
Algunas matemáticas ilustrativas: 10 MB de Tile * s te dan un cuadrado con 1619 mosaicos por lado. Los mapas originales de Zelda eran 256 fichas en el lado largo y menos de la mitad que en el lado corto, por lo que su mapa podría ser más de 36 veces más grande que los primeros Zelda con ese uso de memoria. ¿Estás realmente preparado para hacer tanto contenido ? (No.)
@ user744 Ese comentario es increíblemente engañoso. Para crear un mapa, necesita algo más que punteros a mosaicos. También debe almacenar los datos que contienen los mosaicos. No todos los juegos 2D tienen una cantidad establecida de mosaicos fijos predefinidos.
Jeroen
5

Personalmente, construiría el mapa usando un editor de mosaico designado como TileEd . Este enfoque produce varios beneficios:

  • Utiliza menos recursos. Solo tiene que cargar una hoja de mosaico y un archivo de datos con índices para construir un mapa potencialmente interminable.
  • Dado que tendrá su mapa dividido en trozos realmente pequeños (dependiendo del tamaño de su mosaico), puede agregar / eliminar fácilmente filas / columnas mientras el personaje se mueve por el mundo.
  • Tener un archivo de datos que describe su mapa también le permite agregar información del terreno fácilmente. Esto permite diferentes tipos de fichas como paredes o lagos (es decir, obstáculos) o un pantano donde el movimiento del personaje podría ralentizarse ...
  • Por último, pero no menos importante, un mapa basado en mosaicos también es mucho más fácil de editar y ajustar más adelante porque siempre puede activar el editor, cambiar algunas cosas y guardar un nuevo archivo de datos.

Te sugiero que evites cargar bits del mapa durante el juego para evitar retrasos. Como se mencionó anteriormente, esto no debería ser necesario, ya que probablemente podrá mantener la hoja de mosaico en la memoria. Cuando el personaje entra en otra parte del "mundo", puedes cambiar la hoja de fichas por otra diferente (por ejemplo, las fichas de nieve reemplazadas por fichas de desierto).

Blitting los azulejos a la pantalla es probablemente la forma más rápida de renderizar su mapa. No conozco SFML, pero desde los documentos en su sitio deberías estar buscando en la Spriteclase o usar la Copyfunción de la Imageclase.

Actualización: Acabo de leer algunos de los documentos de SFML y definitivamente deberías usar Drawableo en Spritelugar de manipular imágenes por el bien del rendimiento. Aparentemente hay un cargador SFML embaldosado . Esa es probablemente una buena manera de hacer que algo funcione rápidamente.

bummzack
fuente
1

Comienza haciendo que el mapa tenga el tamaño requerido para contar la historia que deseas que cuente el juego. Pruebe en la máquina con la especificación mínima requerida para que las personas jueguen su juego. Si es demasiado lento, perfile y optimice.

Daniel X Moore
fuente
0

Usar una matriz 2D de mosaicos individuales es lo mejor en mi opinión. Puede tener todo el mapa grande completo como una matriz 2D y solo dibujar la parte que debe mostrarse en un momento dado. El siguiente es un ejemplo del uso de una matriz de mapas 2D con la biblioteca de juegos HTML5 tabageos (tbgs.js); http://actiontad.com/tabageosHTML5/Examples/BlitMathCameraAndTravelers/

mrall
fuente
-3

A menos que esté planeando reconstruir ultima-online (Fallout 3 u Oblivion), no hay razón para que el mundo sea transparente. Baldur's Gate y Icewind Dale son dos juegos que vienen a la mente que implementan mapas efectivos que no restan valor al juego.

De acuerdo, tienes mucha más potencia de computación que la que tenían, por lo que las pantallas de carga deberían ser mínimas, pero incluso Fallout y Oblivion tienen pantallas de carga para algunas cosas.

Todo lo que puedo decirte es que, para mí, estoy escribiendo una pequeña biblioteca Obj-C para el iPhone que toma un conjunto de mosaicos de 32x32 y lo dibuja en una NSImage. Obtengo aproximadamente 10 fps de esta manera, y probablemente debería estar usando OpenGL, pero solo necesito volver a dibujar si el personaje sale del rectángulo.

Deberías dividir el mapa en 9 tamaños de pantalla (para mí son bloques de 960x640), de modo que si el personaje se mueve fuera del bloque central, vuelvo a dibujar las 9 pantallas en una imagen grande (alrededor de 1,2 MB - da una gran cantidad de habitación por debajo del límite de 20 MB en iPhone 3G). Eso sucede bastante lento (mucho más lento que 10 fps), por lo que el nuevo dibujo no se nota durante el juego.

Probablemente me mudaré a OpenGL ES en algún momento, pero por ahora funciona bien.


[EDITAR]

Permíteme aclarar.

El algoritmo de dibujo para el fondo de 9 pantallas tarda 0.1 segundos (10 fps). A menos que su jugador pueda atravesar una pantalla completa en menos de una décima de segundo, el redibujado debe ser imperceptible durante el juego.

Stephen Furlani
fuente
El hecho de que 10 fps sea aceptable para su juego no lo convierte en una buena idea, especialmente en un dispositivo con restricciones de energía como un iPhone. Podría estar haciendo cero redibujos, dejar que el lado de la GPU maneje la rasterización y, de hecho, dejar que el programa pase un tiempo durmiendo, para que el teléfono no se caliente o se quede sin batería.
@Joe Wreschnig ... ??? Dije que se basa en la demanda, cuando el jugador mueve la pantalla, de lo contrario, la imagen de fondo para el UIImageView no se vuelve a dibujar , lo que ahorra poder de procesamiento. Tu comentario no tiene sentido.
Stephen Furlani el
No estoy haciendo un reclamo sobre los fps que requiere tu juego. Estoy diciendo que OpenGL puede proporcionar 60 fps para tal cosa de manera trivial (realmente, ni siquiera se habla de "redibujos" con escenas estáticas y OpenGL): si solo necesita 10 fps, usar OpenGL le permite no desperdiciar energía de la batería para otros "50 cuadros". Su método de dibujo es un desperdicio en un mundo con aceleración de GPU. Probablemente esté bien en una PC, pero no cuando está agotando una batería.
@ Joe, todavía no estoy seguro de lo que estás diciendo. Dibuja una imagen. Luego, la imagen se deja sola hasta que el jugador alcanza un límite, y luego vuelve a dibujar una nueva imagen. ¿Cómo desperdicia la vida de la batería? Solo "dibuja" a pedido, y el resto del tiempo la vista se dibuja utilizando el algoritmo de dibujo nativo de UIImageView.
Stephen Furlani