Po pierwsze, piszę własną logikę gry tylko przez krótki czas, więc przepraszam, jeśli wydaje się to proste.
Dużo czytałem o drzewach quadów i wykrywaniu kolizji na podstawie siatki. Rozumiem logikę - w zasadzie nie sprawdzaj kolizji, chyba że obiekty są w pobliżu. Ale nigdy nie wspomniano, jak to faktycznie wykonać.
Mam w głowie kilka możliwych metod, ale nie jestem pewien, która z nich jest najlepsza
Ogólny test zderzeniowy - bez optymalizacji
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
}
}
przechowuj sąsiadów (metoda 1) Ale co, jeśli chcemy zoptymalizować kolizje, aby sprawdzić tylko obiekty znajdujące się w pobliżu. Czy nadal przebiegamy przez wszystkie obiekty, czy też tworzymy tablicę z obiektami blisko do sprawdzenia?
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
}
}
}
zapętl wszystkie obiekty, ale sprawdzaj tylko sąsiadów pod kątem kolizji (metoda 3) . Inną możliwością jest to, że wciąż zapętlamy wszystko, ale sprawdzamy, czy obiekty są w pobliżu przed przetestowaniem kolizji.
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
}
}
}
}
Przechowuj obiekty w danych kafelków (metoda 3) Używając systemu opartego na kafelkach, dopuszczaj inną opcję; Przechowuj obiekty znajdujące się na określonym kafelku w samych danych kafelka. Sprawdź, na którym kafelku obiekt jest otaczającym kafelkiem, zawierający obiekty, z którymi mógłby się zderzyć:
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
}
}
}
Zawsze staram się patrzeć na rzeczywisty świat jako przykład. Gdybym chciał porównać elementy tego samego koloru, nielogiczne byłoby sprawdzanie wszystkich elementów, nawet jeśli nie pasują one do koloru (Metoda 2, sprawdzanie każdego elementu). Prawdopodobnie zebrałbym przedmioty tego samego koloru (obiekty, które są blisko siebie) i sprawdziłbym je (metoda 1), zamiast sprawdzania wszystkiego.
To nie jest właściwe porównanie, ponieważ elementy podczas sprawdzania kolizji ciągle się przesuwają, więc zamówienie się pomieszało. To mnie dezorientuje.
Czy bardziej efektywnie byłoby sprawdzić każdy element, usuwając w ten sposób wysiłek generowania szeregu sąsiadów.
Czy może bardziej efektywne jest znajdowanie sąsiadów, dzięki czemu nie trzeba zapętlać tak wielu obiektów w celu sprawdzenia kolizji?
Ciągłe zmienianie danych na każdym kafelku wydaje się również bardzo intensywne, więc nie jestem pewien, czy to dobry pomysł ...
Myślałem o grze w obronę wieży, w której wieża musi wykrywać obiekty, jeśli znajdują się w zasięgu, zanim do nich strzelą. I głupio wydaje się sprawdzanie wszystkich przedmiotów, a czasami w pobliżu nie będzie żadnych przedmiotów.
Przepraszam za długi post, zawsze mając problem z wyjaśnieniem siebie!