¿Cómo almacenar un nivel shmup?

12

Estoy desarrollando un shmup 2D (es decir, Aero Fighters ) y me preguntaba cuáles son las diversas formas de almacenar un nivel. Suponiendo que los enemigos están definidos en su propio archivo xml, ¿cómo definirías cuándo aparece un enemigo en el nivel?

¿Se basaría en el tiempo? Actualizaciones? ¿Distancia?

Actualmente hago esto en función del "tiempo de nivel" (la cantidad de tiempo que el nivel se está ejecutando; la pausa no actualiza el tiempo). Aquí hay un ejemplo (la serialización fue realizada por XNA):

<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:level="pekalicious.xanor.XanorContentShared.content.level">
  <Asset Type="level:Level">
    <Enemies>
      <Enemy>
        <EnemyType>data/enemies/smallenemy</EnemyType>
        <SpawnTime>PT0S</SpawnTime>
        <NumberOfSpawns>60</NumberOfSpawns>
        <SpawnOffset>PT0.2S</SpawnOffset>
      </Enemy>
      <Enemy>
        <EnemyType>data/enemies/secondenemy</EnemyType>
        <SpawnTime>PT0S</SpawnTime>
        <NumberOfSpawns>10</NumberOfSpawns>
        <SpawnOffset>PT0.5S</SpawnOffset>
      </Enemy>
      <Enemy>
        <EnemyType>data/enemies/secondenemy</EnemyType>
        <SpawnTime>PT20S</SpawnTime>
        <NumberOfSpawns>10</NumberOfSpawns>
        <SpawnOffset>PT0.5S</SpawnOffset>
      </Enemy>
      <Enemy>
        <EnemyType>data/enemies/boss1</EnemyType>
        <SpawnTime>PT30S</SpawnTime>
        <NumberOfSpawns>1</NumberOfSpawns>
        <SpawnOffset>PT0S</SpawnOffset>
      </Enemy>
    </Enemies>
  </Asset>
</XnaContent>

Cada elemento enemigo es básicamente una ola de tipos de enemigos específicos. El tipo se define en EnemyType, mientras que SpawnTime es el "tiempo de nivel" en el que debería aparecer esta ola. NumberOfSpawns y SpawnOffset es el número de enemigos que aparecerán y el tiempo que transcurre entre cada engendro, respectivamente.

Esta podría ser una buena idea o podría haber mejores por ahí. No estoy seguro. Me gustaría ver algunas opiniones e ideas.

Tengo dos problemas con esto: generar un enemigo correctamente y crear un editor de niveles. Lo del editor de niveles es un problema completamente diferente (que probablemente publicaré en el futuro: P).

En cuanto al desove correctamente, el problema radica en el hecho de que tengo un tiempo de actualización variable y, por lo tanto, debo asegurarme de no perder un engendro enemigo porque el desplazamiento de engendro es demasiado pequeño o porque la actualización tomó un poco más de tiempo . La mayoría de las veces lo arreglé, pero me parece que el problema está en cómo almaceno el nivel.

Entonces, ¿alguna idea? Comentarios?

Gracias de antemano.

pek
fuente

Respuestas:

4

Una forma de hacerlo sería basar el engendro no en el tiempo sino en la distancia horizontal recorrida (suponiendo desplazamiento lateral). Puedes almacenar tus olas enemigas en una cola con una distancia de disparo; cuando la distancia recorrida de tu jugador es mayor que la distancia de activación del objeto en la parte delantera de la cola, sácalo de la cola y engendra.

Esta solución se prestaría más a la integración con un editor de nivel gráfico que una solución basada en el tiempo. Sería mucho más fácil hacer coincidir puntos específicos a lo largo de su fondo de desplazamiento con cuando los enemigos desovan.

Cuenta
fuente
44
Y como beneficio adicional si cambia la velocidad de desplazamiento, ya sea globalmente o para una sección del nivel, mantendrá a los enemigos posteriores en sus posiciones de generación correctas, porque si fuera por tiempo, los enemigos aparecerían en los lugares correctos.
AttackingHobo
2

Le sugiero que estudie el código de PowerManga como referencia. Tienen dos tipos de niveles: niveles de desplazamiento lateral (tipo tirio) donde las cosas se colocan a una distancia específica desde el inicio del nivel y otras cosas se generan aleatoriamente, y niveles "fijos" (a la galaga) donde se analiza una sola onda después de que el anterior haya terminado su patrón.

Los patrones de onda, por supuesto, pueden planificarse eficientemente mediante curvas bezier sucesivas (la página de wikipedia tiene una animación ordenada para explicar eso).

Si puedo permitirme un comentario final, soltaría completamente XML aquí a favor de algo más expresivo, más fácil de mantener y más útil en la programación de juegos, como un script LUA.

HTH


fuente
Ya uso curvas bezier para almacenar movimientos enemigos (que también está serializado en xml). Principalmente estoy usando XML porque .NET y XNA tienen soporte incorporado para serialización / deserialización. El script LUA suena bien pero requerirá más trabajo. Sin embargo, siempre planeé usarlo, así que después de terminar un motor básico, definitivamente lo investigaré. Finalmente, la idea de generar una ola después de una anterior suena interesante.
Pek
2
XML está bien, siempre que sea generado por una herramienta y no editado a mano. Si bien los lenguajes de secuencias de comandos pueden ser útiles para casos especiales (por ejemplo, jefes), ese es un problema completamente separado para definir patrones de ataque estándar, ¿no es así?
bluescrn
0

Considera generar enemigos procesalmente. Sé que es bastante diferente de la respuesta que deseas, e indirectamente resuelve el problema por completo.

Si tuviera que hacer esto, le asignaría a cada unidad enemiga un valor de "puntos" de lo difícil que es, luego asignaría a los niveles algún número de puntos: 100 puntos valen cien enemigos de 1 punto, o un enemigo de 100 puntos, o cualquier cosa intermedia.

Probablemente necesite restringir esto un poco para que no obtenga un jefe de 100 puntos en el primer nivel, o que tenga un número mínimo de enemigos, y probablemente desee sondear periódicamente la lista de enemigos que quedan y tirar el siguiente en pantalla.

Podría ir un paso más allá al tener formaciones: colecciones de posiciones y puntos, por ejemplo. siete enemigos de un punto en una sola línea (fila o columna), o cinco puntos flanqueados por dos de 3 puntos.

cenizas999
fuente