Como os videogames armazenam informações fora da tela?

16

Estou tentando criar um videogame do zero, mas sou muito novo nisso e continuo enfrentando problemas básicos. Mais importante, como os videogames armazenam informações fora da tela? O que quero dizer é: como o programa sabe o que exibir em seguida na tela? Ou ainda, se o player altera o ambiente, como essa alteração permanece na próxima vez que é carregada na tela?

Por exemplo, em New Super Mario Bros, se você acertar um? bloquear e depois sair da tela e voltar, ainda permanece atingido. Como essas informações são mantidas e executadas na próxima vez que o jogador carregar o bloco? Por que não é apenas redefinido?

Apenas algumas perguntas
fonte
24
Pediatria: Em Super Mario Bros, se você acertar um? bloquear e depois sair da tela, você não pode voltar - o jogo rola apenas em uma direção e todos os tubos de dobra são de uma única direção.
Trevor Powell
61
Ao ler um documento de texto e rolar para baixo, o seu processador de texto exclui o início do documento?
Philipp
31
O monitor mostra uma janela no mundo do jogo. O mundo existe fora da sua janela - você simplesmente não o vê.
Felsir 7/08/16
11
A pergunta de programação para novatos muito mais típica é: "Como exibo minhas informações na tela?". Trabalhe em qualquer tutorial de programação e, quando chegar a essa pergunta, já deverá ter a resposta para sua pergunta.
Peter - Unban Robert Harvey
4
Gostaria de saber que tipo de ambiente de desenvolvimento você está trabalhando para manter as coisas fora da tela soa mais complicado do que colocá-las na tela :) Ou isso é apenas uma questão puramente teórica?
Luaan 8/08/16

Respostas:

59

Normalmente você deve separar o estado lógico do seu ambiente de jogo da representação visual.

O jogador pode ver apenas uma pequena parte dele na tela, mas você ainda mantém o estado de todo o nível na memória e, geralmente, também calcula a mecânica do jogo para todo o nível. Quando o seu mundo é tão grande que isso exigiria muita memória RAM e / ou CPU, você pode suspender áreas mais distantes do disco rígido.

Sua sub-rotina de renderização verifica quais partes do nível estão atualmente na tela e as desenha apenas. O que estiver fora da tela não é desenhado, mas isso não significa que não é atualizado.

Philipp
fonte
37

Você está indo para trás.

Você começa com o estado lógico do seu jogo e modela isso. Todo o estado lógico do mundo inteiro quase certamente será demais para ser guardado na memória de uma só vez, então você o divide em partes menores que podem ser carregadas e salvas independentemente. Essas partes são geralmente chamadas de pedaços . Esses pedaços podem formar um mundo contínuo, mas também podem ser níveis / instâncias separados. A terminologia varia muito, dependendo do gênero e da técnica que você deseja usar.

Em seguida, você carrega as partes que são de interesse - ou seja, pedaços que estão nas proximidades do jogador. Os pedaços muito distantes são salvos no disco / armazenamento permanente e descarregados da memória.

E então, como último passo, você determina o que é realmente visível e cria a representação visual do estado atual do jogo e o renderiza na tela.

É claro que você tentaria não reconstruir toda a representação visual toda vez, mas armazená-la em cache e reutilizá-la se tiver peças já construídas, mas esse é o princípio principal.


Isso vale para qualquer programa que tenha saída. Se você escrever um programa com uma GUI normal, como um editor de texto, provavelmente modelará o documento e, em seguida, a GUI determinará o estado e as partes visíveis do documento e o renderizará para a tela. Ou preencha adequadamente os campos do formulário.

O principal é: Pense em onde e como você armazena os dados primeiro (provavelmente ao lado de como representá-los). Quase todo programa tem que lidar com armazenamento de dados. Existem muito poucos casos em que você não armazena nenhum dado.

Polygnome
fonte
7
pedaços? Eu chamaria esses pedaços menores de níveis .
gbjbaanb
3
Isso é bom, exceto "para que você o divida em partes menores que podem ser carregadas e salvas de forma independente. Essas partes são geralmente chamadas de pedaços", que parecem ser específicos para jogos com mundos muito grandes. Muitos jogos não precisam fazer isso. Eu não ficaria surpreso se você pudesse caber na memória todos os dados de nível de todos os side-scrollers 2D já criados.
user253751
3
@gbjbaanb 'Nível' é um termo datado e 'chunk' é muito mais abrangente e um conceito claramente distinto. Nem todos os pedaços são níveis e nem todos os níveis são pedaços.
Lilienthal
3
Eu acho que uma maneira útil de pensar sobre isso é que deve ser tecnicamente possível jogar o jogo inteiro sem que um único pixel seja renderizado, ou seja, a totalidade do jogo é separada da representação visual.
Nathan K
11
@ Lilienthal com certeza, mas acho que o nível ainda é de uso comum, e muitos jogos ainda têm o conceito - não tenho certeza de que algum deles apareça na tela "loading chunk" ao buscar uma nova "arena" e o jogador os percorrerá. Por isso, pode ser mais compreensível, principalmente para o OP que é novo nos jogos do que um termo relativamente técnico que ele talvez nunca tenha visto antes.
precisa saber é o seguinte
6

Como já foi dito, você mantém um mapa (por exemplo, em uma matriz) e desenha a parte visível na tela, e não lê de volta na tela.

Mas em alguns sistemas mais antigos, você literalmente mantinha os dados fora da tela. Por exemplo, haveria 400x300 pixels de memória de vídeo para uma tela de 320x200, e você definiria uma janela de exibição para ela ("inicie em X = 10 Y = 30"). Então você pode rolar a tela apenas ajustando um registro. Você não precisaria gastar os cem mil ciclos necessários para mover os bytes; basta mudar onde o hardware de vídeo começa a lê-los.

O NES possui isso, combinado com um sistema baseado em bloco: http://wiki.nesdev.com/w/index.php/PPU_scrolling

O NES nunca constrói a imagem completa na memória, porque não possui RAM suficiente. Em vez disso, há uma matriz de RAM que define um conjunto de blocos com duas telas. Um byte por tipo de bloco. O hardware de vídeo procura as coordenadas de deslocamento do bloco e X / Y para decidir qual pixel deve aparecer a qualquer momento.

pjc50
fonte
6
Embora seja verdade, esse é um detalhe de implementação - o princípio principal ainda é que você tem algum estado lógico e o processa (e, como eu disse, armazena algumas partes dele, já prepara algumas coisas que entrarão no ponto de vista a seguir etc.).
Polygnome
2
@ Polygnome Bem, eu escrevi muitos jogos em que a tela era o estado do jogo. É incrível o que você pode fazer com 4.000 bytes de VRAM! :)
Luaan 8/08/16
1

Bem, se você está fazendo esse tipo de pergunta, terá um longo caminho para chegar ao ponto em que pode fazer um jogo. Mas, chegando ao cerne da sua pergunta, o programa pode salvar o estado de muitas coisas diferentes nas variáveis ​​que estão no backend do seu programa. Vejamos alguns exemplos.

Mario Brothers (ou similar) salva o estado do nível em que você está. Isso pode incluir o quão longe você foi antes de morrer, se um bloco foi atingido ou não. Em um sentido mais orientado a objetos, o jogo apenas diz "seja um bloco aqui" e o bloco existe. quando você bate no bloco, o bloco muda seu próprio estado interno para dizer "fui atingido". Dados como esse podem ser armazenados de várias maneiras.

Seu processador de texto salva seus dados em uma estrutura de dados. Agora, existem muitas e muitas maneiras de implementá-las, mas provavelmente ela usa alguma forma de árvore. Em uma árvore, você tem pelo menos um nó. Qualquer coisa adicionada antes de ir para a esquerda. Qualquer coisa adicionada depois, vai para a direita. Depois de adicionar três nós, você tem dois deles pendurados no nó do meio. E a árvore pode crescer ainda mais com a adição de novas peças em qualquer lugar e a árvore se reconstruirá. Exemplo de árvore Ou pense nos jogos de tiro em que seu inimigo vagueia. Cada um deles possui variáveis ​​que rastreiam sua localização, vida, etc., de modo que, quando você machuca um, ele se lembra de que foi ferido.

Tudo isso requer um conhecimento das estruturas de dados. Vai muito além do que você vê na tela. Sugiro ler sobre matrizes, listas, hashes (às vezes chamados de dicionários ou mapas) e depois voltar ao seu problema.

Aqui estão alguns bons materiais de partida:

BSD
fonte
0

Até certo ponto, isso é uma função de como o 3D é renderizado. Por exemplo, o OpenGL seleciona automaticamente a geometria fora do intervalo -1,0, +1,0 no espaço da tela XY (Z é mais complexo, mas semelhante). A geometria descartada nunca gera fragmentos (aproximadamente pixels) e, portanto, nunca é transformada em imagem real, apesar de ter sido enviada ao sistema para renderização. De qualquer forma, é impossível gravar no espaço fora da janela de renderização (se tudo estiver funcionando como deveria).

Em alguns contextos, basta confiar nesse comportamento como uma otimização. No entanto, você ainda precisa passar todos os dados do jogo por pelo menos um estágio de renderização (vertex shaders) antes que a placa de vídeo possa saber o que é visível. Em algo como, digamos, Skyrim, isso seria impraticável. Você não apenas precisa enviar todos os vértices do mundo através do pipeline de renderização, mas também carregar todos os vértices na memória do sistema / vídeo. Isso é ineficiente, se possível.

Portanto, muitos jogos farão uso da seleção baseada em CPU. Eles normalmente implementam algum tipo de sistema de nível de detalhe (LOD), em que a qualidade e a existência de ativos são impactadas pela importância em que elas são avaliadas em um determinado contexto. Uma malha piramidal pode ser uma aproximação aceitável para uma montanha se você estiver a 80 quilômetros dela. Se você não consegue vê-lo (como se estivesse bloqueado por outras montanhas), não há necessidade de carregá-lo. Existem vários métodos mais complexos para fazer isso, que são tópicos que não considero diretamente relevantes para a profundidade solicitada por essa pergunta, mas observe o mosaico para um dos exemplos mais comuns.

A verdadeira essência disso é que o visual é apenas o produto do jogo. Os dados reais não têm nada a ver diretamente com o que você está vendo ou não vendo na maioria das vezes, e os dados são filtrados por vários estágios para remover informações estranhas antes de chegar ao ponto em que uma imagem é gravada na tela. Dependendo do design do mecanismo, o visual pode ser extremamente dissociado da lógica real do jogo, na medida em que algo como ter uma interface 2D e 3D para o mesmo jogo seja uma possibilidade. É até possível para muitos mecanismos de jogos rodarem sem saída, seja como for; Às vezes, isso é usado para testar a IA do jogo.

É aí que as coisas podem ficar complicadas, no entanto. Em algo simples como um jogo de Mario, não é muito proibitivo calcular o movimento de todos os inimigos no nível, mesmo que eles não sejam visíveis. Nos contextos modernos, o que está acontecendo fora da tela é uma questão real de consideração séria. Se houver várias cidades inteiras de NPCs, como você lida com o comportamento delas quando são completamente descartadas - como quando o jogador está em uma cidade diferente? Deseja realmente calcular centenas de decisões dos NPCs em todo o mapa? A resposta geralmente é não, mas a abordagem exata para fazer isso pode variar, e pode ter alguns impactos no jogo.

É importante observar que é assim que as coisas funcionam agora . Os próprios jogos antigos do Mario provavelmente foram programados de maneiras muito diferentes (não sei falar exatamente), dadas as limitações extremas de hardware da época. O conceito de 3D não existia naquela época; hoje, quase todos os jogos, mesmo os totalmente 2D, usam a renderização 3D de alguma forma, mesmo que não saibam. O hardware de vídeo moderno é o primeiro em 3D, e a renderização em 2D (pelo menos quando faz uso adequado do hardware) simplesmente ignora a 3ª dimensão.


fonte
Além das técnicas de LoD, seria bom adicionar um gráfico de cenário a essa resposta - onde um mundo pode ser mantido na memória e 'CPU selecionado' com base no que está dentro da visualização.
Gbjbaanb
0

Para responder à sua pergunta: os videogames mantêm o estado do mundo dos jogos em uma estrutura de dados abstrata que não tem nada a ver com a tela. Isso é renderizado na tela conforme necessário (ou seja, dependendo de onde o jogador está).

Os jogos que usam a RAM de vídeo diretamente para fins de estado existiam nos anos 80 nos 8 bits, talvez até na era dos 16 bits, mas a menos que você esteja desenvolvendo para essa plataforma ou para alguns µC que custam sua RAM em KB de GB, esqueça.

Dito isto, você parece ser muito novo em tudo relacionado à programação ou a questão não teria surgido. Sugiro ir passo a passo, programando coisas muito fáceis primeiro; talvez algo que tenha apenas entrada / saída textual (avisos simples e tudo isso). Para ser sincero, o tempo em que fiz isso foi há cerca de 30 anos, então não tenho recursos realmente bons para você, mas sua biblioteca local pode ser apenas melhor que a Internet para dar um bom começo na programação.

AnoE
fonte