По-перше, я лише короткий час писав власну логіку гри, тому вибачаюся, якщо це може здатися прямо вперед.
Я багато читав про квадратичні дерева та виявлення зіткнень на основі сітки. Я розумію логіку - в основному не перевіряйте на зіткнення, якщо об'єкти не знаходяться поблизу. Але ніколи не згадується, як насправді це виконувати.
У мене є кілька можливих методів в голові, але я не впевнений, що найкраще
Загальний тест на зіткнення - немає оптимізації
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
}
}
зберігати сусідів (метод 1) Але що робити, якщо ми хочемо оптимізувати зіткнення лише для перевірки об'єктів, які знаходяться поруч. Чи все-таки ми пробігаємося через усі об’єкти чи створюємо масив з близькими об’єктами, щоб перевірити їх?
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
}
}
}
петлю всіх об'єктів, але тільки перевіряйте сусідів на зіткнення (метод 3) . Інша можливість полягає в тому, що ми все ще перебираємо все, але перевіряємо, чи є об'єкти поруч, перш ніж тестувати зіткнення.
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
}
}
}
}
Зберігання об’єктів у даних даних плиток (метод 3) Використання системи на основі плитки дозволяє використовувати інший варіант; Зберігайте об’єкти, які знаходяться на певній плитці, у самих даних плиток. Перевірте, на якій плитці знаходиться об'єкт оточуючих плиток, які містять об'єкти, з якими він міг зіткнутися:
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
}
}
}
Я завжди намагаюся дивитись на реальний світ як на приклад. Якщо я хотів порівняти предмети одного кольору, здавалося б, нелогічно перевіряти кожен предмет, навіть якщо вони не відповідають кольору (метод 2, перевірте кожен предмет). Я б, мабуть, збирав елементи одного кольору (об'єкти, які знаходяться поруч один з одним) і перевіряв їх (метод 1), а не перевіряти все.
Це не підходяще порівняння, оскільки предмети при перевірці зіткнень постійно рухаються, тому замовлення змішується. Що мене бентежить.
Було б ефективніше перевіряти кожен елемент, тим самим знімаючи напругу продовжувати створювати масив сусідів.
Або більш ефективно знайти сусідів, таким чином, не потрібно перебирати стільки предметів, щоб перевірити зіткнення?
Продовжуйте змінювати дані на кожній плитці також дуже інтенсивно, тому я не впевнений, чи це гарна ідея.
Я думав про гру оборонної вежі, де башта повинна виявляти предмети, якщо об’єкти знаходяться в зоні, перш ніж вона стріляє по ній. І просто здається нерозумним перевіряти всі предмети, хоча іноді поблизу не буде об’єктів.
Прошу вибачення за довгий пост, завжди маючи проблеми з поясненням себе!