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.
fuente
Respuestas:
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).
fuente
Personalmente, construiría el mapa usando un editor de mosaico designado como TileEd . Este enfoque produce varios beneficios:
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
Sprite
clase o usar laCopy
función de laImage
clase.Actualización: Acabo de leer algunos de los documentos de SFML y definitivamente deberías usar
Drawable
o enSprite
lugar 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.fuente
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.
fuente
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/
fuente
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.
fuente