Primeiro de tudo, eu só tenho escrito minha própria lógica de jogo por um tempo, então peço desculpas se isso pode parecer simples.
Eu tenho lido muito sobre árvores quad e detecção de colisão baseada em grade. Eu entendo a lógica - basicamente não verifique se há colisão, a menos que os objetos estejam perto basicamente. Mas nunca é mencionado como o realmente executa isso.
Eu tenho alguns métodos possíveis na minha cabeça, mas não sei qual é o melhor
Teste geral de colisão - sem otimização
for(var i:int = 0; i < objects.length; i++){
//find object A
var objectA = objects[i];
for(var j:int = i + 1; j < objects.length; j++){
//find object B
var objectB = objects[j];
if(objectA.collidesWith(objectB){
//handle collision logic
}
}
armazenar vizinhos (método 1) Mas e se quisermos otimizar as colisões para verificar apenas os objetos que estão próximos. Ainda executamos todos os objetos ou criamos uma matriz com objetos próximos para verificar?
var objects:Array = new Array();
var neighbours:Array = new Array();
for(var i:int = 0; i < objects.length; i++){
//find object A
var objectA = objects[i];
for(var j:int = i + 1; j < objects.length; j++){
//find object B
var objectB = objects[j];
if(objectA.isNear(objectB){
neighbours.push(objectA, objectB);
}
}
}
//somewhere else
for(i:int = 0; i < neighbours.length; i++){
//only check neighbours
for(j:int = i + 1; j < neighbours.length; j++){
if(objectA.collidesWith(objectB){
//handle collision logic
}
}
}
repetir todos os objetos, mas verificar apenas os vizinhos quanto à colisão (método 3) A outra possibilidade é que ainda percorremos tudo, mas verificamos se os objetos estão próximos antes de testar a colisão.
for(var i:int = 0; i < objects.length; i++){
//find object A
var objectA = objects[i];
for(var j:int = i + 1; j < objects.length; j++){
//find object B
var objectB = objects[j];
if(objectA.isNear(objectB){
//they are near - check collision!
if(objectA.collidesWith(objectB){
//handle collision logic
}
}
}
}
Armazenar objetos em dados de bloco (método 3) O uso de um sistema baseado em bloco permite outra opção; Armazene os objetos que estão em um bloco específico nos próprios dados do bloco. Verifique para ver em qual bloco o objeto está, os blocos ao redor contêm objetos com os quais podem colidir:
var ObjectA;
for(var i:int = 0; i < 4; i ++){
//check 4 surrounding tiles from object A
if(Object.currentTile + surroundingTile[i] CONTAINS collidable object){
//check collision!
if(objectA.collidesWith(surroundingTile.object){
//handle collision logic
}
}
}
Eu sempre tento olhar o mundo real como um exemplo. Se eu quisesse comparar itens da mesma cor, pareceria ilógico verificar todos os itens, mesmo que não correspondam à cor (método 2, verifique cada item). Provavelmente eu coletaria os itens da mesma cor (objetos próximos) e os verificaria (método 1), em vez de verificar tudo.
Esta não é uma comparação adequada, pois os itens na verificação de colisão estão em constante movimento, de modo que o pedido se confunde. Isso está me confundindo.
Seria mais eficiente verificar cada item, removendo assim a tensão de continuar gerando uma matriz de vizinhos.
Ou é mais eficiente encontrar vizinhos e não ter que percorrer tantos objetos para verificar a colisão?
Continue alterando os dados em cada bloco também parece muito intensivo, então não tenho certeza se é uma boa idéia.
Eu estive pensando em um jogo de defesa de torre em que a torre precisa detectar objetos se os objetos estiverem ao alcance antes de atirar nela. E parece tolo verificar todos os itens, enquanto em alguns momentos não haverá objetos próximos.
Peço desculpas pelo longo post, sempre tendo problemas para me explicar!