8. Mundo em chunks
Só existe o que está perto do jogador. O resto é recriado quando ele volta.
O mundo é dividido em quadrados de tamanho fixo, os chunks. O jogador está sempre dentro de um deles, e o jogo mantém vivos só os 9 ao redor (uma grade 3x3). Quando o jogador cruza a borda para outro chunk, os que ficaram longe são destruídos e os que faltam são criados. Como o terreno é determinístico (semente + coordenada), o chunk recriado sai idêntico ao que foi destruído.
Setas ou WASD movem o jogador. O retângulo tracejado é a grade 3x3 (ou 5x5). Cada chunk mostra a própria coordenada.
As três contas
// 1. em que chunk o jogador está
cx = floor(jogador.x / TAMANHO_CHUNK)
cz = floor(jogador.z / TAMANHO_CHUNK)
// 2. quais chunks deveriam existir (raio 1 = grade 3x3)
desejados = {}
para dz em -raio..raio, dx em -raio..raio:
desejados.add( (cx + dx, cz + dz) )
// 3. criar os que faltam, destruir os que sobram
para cada (c) em desejados que não está em vivos: criar(c)
para cada (c) em vivos que não está em desejados: destruir(c) // ou devolver ao pool
| Nome | O que é |
|---|---|
TAMANHO_CHUNK | lado do chunk em unidades de mundo. Aqui 32; em Unity com 1 vértice por metro, algo entre 64 e 240. |
cx, cz | coordenada do chunk, inteira. O chunk (2, −1) cobre x de 64 a 95 e z de −32 a −1. |
floor | arredonda para baixo. Sem isso, −0,5 vira chunk 0 em vez de −1 e a grade pula na origem. |
raio | 1 dá 3x3; 2 dá 5x5. Cada passo de raio multiplica o custo. |
vivos | dicionário chunk → objeto na cena, com chave "cx,cz" |
pool | em vez de destruir, esconder e guardar; ao criar, pegar um do pool e só repintar. Evita alocar malha nova toda hora. |
A costura
cx × 32 + x). Cada chunk sai igual ao outro e as bordas não batem. Ligue "amostrar em coordenada local" no painel e veja.
para z em 0..TAMANHO-1, x em 0..TAMANHO-1:
gx = cx * TAMANHO + x // global: continua de onde o vizinho parou
gz = cz * TAMANHO + z
altura[x, z] = fbm(gx * escala, gz * escala)
Um segundo detalhe: dois chunks vizinhos precisam compartilhar a fileira de vértices da borda. Se o chunk tem 32 quadrados, ele tem 33 vértices por lado, e o vértice 32 de um é o vértice 0 do outro. Sem isso aparece uma fresta entre eles.
Thread no Godot) e só montar a malha no frame seguinte; ou gerar o anel de fora antes de o jogador chegar nele.