Implementando uma câmera / viewport em um jogo 2D


20

Qual é a maneira mais prática de implementar câmera / viewport em um jogo 2D?

Eu li que devo armazenar a posição mundial do objeto em vez da posição relativa à tela?

Situação atual:

Eu implementei um jogo 2D simples, onde carrego objetos e níveis de arquivos XML. Atualmente, o arquivo XML de nível se parece com isso:

<map>
   <tile obj="ground" x="0" y="555" />
   <tile obj="ground" x="16" y="555" />
   <tile obj="ground" x="32" y="555" />
   ...
</map>

Todos os objetos têm uma "posição" do vetor 2D armazenando sua localização atual na tela.

O que eu quero que seja:

Ilustração de viewport / gameworld

Na foto:

  • A câmera é 800x600 ou 640x480
  • Blocos e sprites são 16x16 pixels.
  • O tamanho do mundo pode variar
  • As coordenadas provavelmente devem ser normalizadas em relação ao mundo, não à tela?
  • A posição da janela de visualização em relação ao x, y do jogador e se move quando o jogador atinge a zona morta da câmera (semelhante a este vídeo ).

Estou perguntando pseudo exemplos / artigos, mas se você precisar saber o que estou usando para o desenvolvimento: SDL & C / C ++.


11
Adicione seu terceiro link nos comentários aqui e eu posso adicioná-lo à sua pergunta.
MichaelHouse

Aqui está o que eu quis dizer com a zona morta da câmera: youtube.com/watch?v=89TRXUm8jMI #
bluekirai


Olá @Arthur Wulf White, quer elaborar? Obrigado.
bluekirai

A câmera mencionada é uma versão específica de uma câmera 2D geral que é usada apenas para compensar a visualização (sem rotação e zoom). O comportamento de rastreamento pode ser implementado verificando a distância entre o personagem do jogador e a câmera, movendo a câmera se a distância for muito grande.
wolfdawn

Respostas:


19

Você precisa ter todos os objetos posicionados em relação ao mundo em vez da tela. Sua câmera também deve ter suas próprias coordenadas mundiais para que possa ser desenhada em uma posição relativa no mundo. Também pode ser conveniente que sua câmera siga um objeto; portanto, onde quer que esteja, a câmera usa apenas suas coordenadas. Normalmente, as coordenadas da câmera a posicionam no canto superior esquerdo. Isso significa que a câmera teria uma posição mundial de aproximadamente (0,24) na imagem .

Quanto ao desenho dos objetos que a câmera pode "ver", você deve desenhar todos os objetos relativos às coordenadas do mundo da câmera. Para calcular a posição da tela de um objeto em relação à câmera, basta:

int screenX, screenY; //screen position of the object being drawn

screenX = object.x-camera.x;
screenY = object.y-camera.y;

Obviamente, alguns objetos não são realmente visíveis para a câmera, então você pode implementar um sistema de seleção de exibição.


2

É melhor fazer tudo isso na GPU usando as matrizes World e View, não modificando onde você desenha os objetos na CPU.

Dessa forma, você pode mudar a câmera arbitrariamente (até aproximar e afastar!) E ela funcionará magicamente. Você ainda pode selecionar a seleção, para economizar tempo de empate. E nenhum código para desenhar o mundo precisará ser alterado depois que você tiver configurado as matrizes de exibição e mundo corretamente.

No SDL, você provavelmente pode simplesmente incluir chamadas OpenGL, como glOrthoe glTranslate.

Veja este tópico .


Alguém pode explicar o voto negativo? Isso faz sentido.
Olá Mundo

11
Não votei em baixa, mas acho que é porque isso nem responde à pergunta. A questão é sobre como calcular algo, não se é mais eficiente ou mais fácil de fazer em uma GPU vs CPU. O OP até disse que está procurando pseudo exemplos. Não há dúvida de que o uso de uma combinação de matrizes de câmera / mundo / modelo seria mais eficiente, então mklingen tem um ponto a menos.
Dan Watkins

Esta resposta não é ruim! É mais específico para o desenvolvimento OpenGL / DX, mas é a abordagem correta, pois você pode apenas calcular uma matriz de conversão com base nas cores da câmera e mover objetos via matriz da câmera, sem alterar suas posições reais.
nenchev
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.