Como armazenar um nível de shmup?

12

Estou desenvolvendo um shmup 2D (ou seja, Aero Fighters ) e fiquei imaginando quais são as várias maneiras de armazenar um nível. Supondo que os inimigos sejam definidos em seu próprio arquivo xml, como você definiria quando um inimigo aparecer no nível?

Seria baseado no tempo? Atualizações? Distância?

Atualmente, faço isso com base no "tempo do nível" (a quantidade de tempo em que o nível está sendo executado - a pausa não atualiza o tempo). Aqui está um exemplo (a serialização foi feita pelo 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 inimigo é basicamente uma onda de tipos de inimigos específicos. O tipo é definido no EnemyType enquanto SpawnTime é o "tempo de nível" em que essa onda deve aparecer. NumberOfSpawns e SpawnOffset é o número de inimigos que aparecerão e o tempo gasto entre cada spawn, respectivamente.

Esta poderia ser uma boa ideia ou poderia haver melhores por aí. Não tenho certeza. Eu gostaria de ver algumas opiniões e idéias.

Eu tenho dois problemas com isso: gerar um inimigo corretamente e criar um editor de níveis. A questão do editor de níveis é um problema completamente diferente (que provavelmente vou postar no futuro: P).

Quanto à desova corretamente, o problema está no fato de eu ter um tempo de atualização variável e, portanto, preciso ter certeza de que não perco uma semente inimiga porque o deslocamento da desova é muito pequeno ou porque a atualização levou um pouco mais de tempo . Eu consertei isso na maior parte do tempo, mas parece-me que o problema está em como armazeno o nível.

Então, alguma ideia? Comentários?

Agradeço antecipadamente.

pek
fonte

Respostas:

4

Uma maneira de fazer isso seria basear a semente não no tempo, mas na distância horizontal percorrida (assumindo o deslocamento lateral). Você pode armazenar suas ondas inimigas em uma fila com uma distância de disparo; quando a distância percorrida do seu jogador for maior que a distância do gatilho do objeto na frente da fila, retire-o da fila e crie-o.

Essa solução se prestaria mais à integração com um editor de nível gráfico do que com uma solução baseada no tempo. Tornaria muito mais fácil combinar pontos específicos ao longo de seu plano de rolagem quando os inimigos aparecerem.

Conta
fonte
4
E como um bônus, se você alterar a velocidade de rolagem, globalmente ou em uma seção do nível, ele manterá os inimigos posteriores em suas posições de spawn corretas, porque se fosse baseado no tempo, os inimigos apareceriam nos pontos corretos.
AttackingHobo
2

Eu sugiro que você estude o código do PowerManga como referência. Eles têm dois tipos de níveis: níveis de rolagem lateral (do tipo tirano), onde as coisas são posicionadas a uma distância específica do início do nível e outras coisas são geradas aleatoriamente, e os níveis "estáticos" (à galaga), nos quais uma onda é analisada apenas após o anterior terminar seu padrão.

É claro que os padrões de onda podem ser planejados com eficiência por sucessivas curvas de bezier (a página da wikipedia possui uma animação interessante para explicar isso).

Se eu puder pagar um comentário final, deixaria o XML completamente aqui em favor de algo mais expressivo, mais fácil de manter e mais útil na programação de jogos, como um script LUA.

HTH.


fonte
Eu já uso curvas bezier para armazenar movimentos inimigos (que também são serializados em xml). Estou usando principalmente XML porque o .NET e o XNA têm suporte interno para serialização / desserialização. O script LUA parece bom, mas exigirá mais trabalho. No entanto, eu sempre planejei usá-lo, então, depois de terminar um mecanismo básico, definitivamente analisarei. Finalmente, a idéia de gerar uma onda depois da anterior parece interessante.
pek
2
XML é bom, desde que seja gerado por uma ferramenta e não editado à mão. Embora as linguagens de script possam ser úteis para casos especiais (por exemplo, chefes), esse é um problema completamente separado para definir padrões de ataque padrão, não é?
bluescrn
0

Considere gerar inimigos proceduralmente. Eu sei que é bem diferente da resposta que você deseja e indiretamente resolve o problema completamente.

Se eu fizesse isso, atribuiria a cada unidade inimiga um valor de "pontos" de quão difícil é, e atribuiria aos níveis um certo número de pontos - 100 pontos valem cem inimigos de 1 ponto ou um inimigo de 100 pontos, ou qualquer coisa intermediária.

Você provavelmente precisaria restringir um pouco isso para não conseguir um chefe de 100 pontos no primeiro nível ou para ter um número mínimo de inimigos, e provavelmente deseja pesquisar periodicamente a lista de inimigos restantes e puxar o próximo na tela.

Você poderia dar um passo adiante tendo formações: coleções de posições e pontos, por exemplo. sete inimigos de um ponto em uma única linha (linha ou coluna) ou cinco pontos ladeados por dois de três pontos.

ashes999
fonte