對於類似的任務(2D),我所做的就是創建一個簡單的四叉樹樣結構,每個節點可以包含其他子節點或碰撞檢測顯示對象的列表。請注意,如果對象(您的案例中的對象)移動很多,這將不會有效,因爲您每次移動時都需要將它們移動到正確的節點中。
一個簡單的例子類將是:
public class WorldPartitionNode {
private var minX : Number;
private var minY : Number;
private var maxX : Number;
private var maxY : Number;
private var width : Number;
private var height : Number;
private var _children : Vector.<WorldPartitionNode>;
private var _objects : Vector.<GameObject>;
public function WorldPartitionNode(x : Number, y : Number,
w : Number, h : Number, childLevels : int)
{
minX = x;
minY = y;
maxX = x + w;
maxY = y + h;
width = h;
height = h;
if (childLevels == 0) {
// This node should have no children, so instead it should
// contain display objects
_objects = new Vector.<GameObject>;
}
else {
_children = new Vector.<WorldPartitionNode>(4,true);
_children[0] = new WorldPartitionTreeNode(minX, minY, width/2, height/2, childLevels-1);
_children[1] = new WorldPartitionTreeNode(minX+width/2, minY, width/2, height/2, childLevels-1);
_children[2] = new WorldPartitionTreeNode(minX, minY+height/2, width/2, height/2, childLevels-1);
_children[3] = new WorldPartitionTreeNode(minX+width/2, minY+height/2, width/2, height/2, childLevels-1);
}
}
public function addObject(obj : GameObject) : void
{
if (_children) {
// This is not a leaf node, so add it to that of the child
// nodes in which it belongs.
var i : uint;
for (i=0; i<4; i++) {
var c : WorldPartitionNode = _children[i];
if (obj.x > c.minX && obj.y > c.minY && obj.x < c.maxX && obj.y < c.maxY) {
c.addObject(obj);
return; // Found node, so bail
}
}
}
else {
// This is a leaf node, so just add to the internal objects vector
_objects.push(obj);
}
}
public function checkCollisions(x : Number, y : Number) : GameObject
{
if (_children) {
// This node has children, so delegate to the right child
var i : uint;
for (i=0; i<4; i++) {
var c : WorldPartitionNode = _children[i];
if (x > c.minX && y > c.minY && x < c.maxX && y < c.maxY) {
return c.checkCollisions(x, y);
}
}
}
else {
// This is a leaf node (with objects directly in it) so loop through
// them all and check collision
var obj : GameObject;
for each (obj in _objects) {
if (obj.collidesWith(x, y))
return obj;
}
return null; //None if reached
}
}
}
這個類的實例將自身分爲四個矩形部分(兩行,兩列)如果childLevels > 0
,並創建相同類的實例爲每個的節點。這些節點將依次以相同的方式劃分它們的空間,直到總共有childLevels
個級別。
因此,您可以創建一個三級四叉樹(帶有64個分區葉節點),其中每個節點只是原始空間大小的1/64。當您使用addObject()
添加對象時,該對象將被添加到與其所在的平方對應的分區節點。
當您執行checkCollision()
時,它會遞歸childLevels
次直到找到正確的分區,然後僅爲該分區中的對象執行常規衝突檢測循環。
要建立三級樹,其中涵蓋了空間,也就是1024×1024像素:
var treeRoot : WorldPartitionNode = new WorldPartitionNode(0, 0, 1024, 1024, 3);
,並檢查您的導彈,並在樹中的對象之間的碰撞:
var missile : GameObject;
for each (missile in _missiles) {
var obj : GameObject = treeRoot.checkCollisions(missile.x, missile.y);
if (obj != null)
obj.kill(); // Was hit by missile
}
這可能會顯着加速碰撞檢測,但依賴於靜態(或很少移動)框,因爲如果它們移動,它們將不再位於正確的分區節點中,並且如果它們不是,則樹將無法找到衝突它們之間。
毫無疑問,智能化的分區系統在那裏,但是對於我需要在大空間分散拾取器(硬幣和c)以及玩家可以四處飛行以收集信息的項目,這對我來說非常有效他們。然後,我會讓樹檢查靜態拾取器和播放器之間的碰撞。
好主意,必須檢查一下。謝謝 – Vlad