Atualmente, estou trabalhando por conta própria em um jogo baseado em blocos (pense em Terraria, mas menos fantástico (acho que é uma palavra? Desculpe se não é)).
De qualquer forma, atualmente tenho a detecção de colisão funcionando (mesmo nos casos de canto!), O que foi um grande passo para mim. Há algo extremamente gratificante em ver um sprite não correr por um bloco. Mas então tive a ideia de fazer benchmark. Péssima ideia.
1.000 quadrados, não há problema. 10.000 quadrados, para 3 caracteres, era meio que lento. 100.000 quadrados (mapa realmente grande), para 3 personagens, não eram jogáveis.
Estou tendo o problema em que não quero nem considerar os blocos que estão muito longe do jogador, personagens, itens etc., mas não quero carregar esses in-out de memória constantemente.
Aqui está o meu algoritmo até agora, fique à vontade para criticar.
foreach (Block in level)
{
if (distance from block to player > a specified amount)
ignore this block;
else
{
get the intersection depth between the two bounding boxes
if (depth of intersection != Zero-vector)
{
check y size vs x size
resolve on smallest axis
}
}
}
Como você notará, quando o tamanho do nível aumentar, a ordem desse algoritmo aumentará em N blocos. Eu gostaria de nem considerar blocos que nem sequer estão perto do jogador.
Acho que talvez use um (0,0) para (mapWidth, mapHeight) matriz dupla de blocos em vez de uma lista, calculando uma zona de perigo dependendo da posição da pessoa, por exemplo, se a posição do jogador estiver em (10, 20) parecerá de (0, 10) a (20, 30) ou mais.
Quaisquer pensamentos e considerações são impressionantes, obrigado.
Respostas:
Sim, você está pensando corretamente. Você deve usar uma matriz 2D de blocos, pois isso permite indexar blocos por posição.
E como o jogador só pode colidir com as peças ao redor, o número de verificações de colisão que você precisa fazer é muito pequeno. Obviamente, isso depende do tamanho do jogador. A amostra do Platformer faz o seguinte:
Verifique a amostra se você ainda tiver algum problema.
fonte
Eu acho que minha resposta seria sua resposta! ;-)
Se você tiver a posição (e o tamanho) do jogador, poderá calcular os índices das peças adjacentes (que são as únicas a serem verificadas em detalhes). Dessa forma, deve ser irrelevante o tamanho do seu mapa, depende apenas do tamanho real do seu jogador, resultando em mais peças possíveis para serem verificadas.
Talvez verifique o tutorial sobre colisões em riemers.net, se você ainda não o fez.
fonte
Ao lidar com um grande número de colisões, geralmente você deseja adotar uma estrutura mais avançada , como um Quadtree ou Hashmap para verificar essas colisões.
Como as peças são estáticas, sugiro o uso de um Quadtree. Uma árvore quad é composta de quads. Cada quad é composto de quatro retângulos e cada um desses retângulos são quads. Isso continua recursivamente até um tamanho especificado. Cada quad pode conter uma lista de peças que habitam essa área da tela. Dessa forma, quando você estiver verificando colisões, poderá
Agora, se você não quiser nem olhar para as telhas fora da tela, poderá fazer algo como
fonte