我正在制作2D游戏,看看我能做些什么。现在我正处于我必须进行物体碰撞的部分,我选择使用四叉树。手头的问题是将对象插入多个子节点。所以我遇到的问题是当我将一个对象插入树中时,树应该将对象放入可能的最低叶节点。但由于某种原因,我还没有发现每个父节点中至少有一个对象仍然存在。
所以我的问题是你们可以帮助识别并提供上述问题的可能解决方案。如果你们这些问题无法解决,你们可以提供另一种解决方法。
我的代码:
package net.evergone.engine;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.lwjgl.util.vector.Vector2f;
import org.newdawn.slick.Color;
import net.evergone.EverGone;
import net.evergone.game.BasicRectangle;
public class QuadtreeNode
{
private int MAX_OBJECTS = 2;
private int MAX_LEVELS = 6;
private int level = 0;
private boolean children = false;
private static boolean temp = false;
private BasicRectangle boundBox;
private ArrayList<BasicRectangle> objects;
private QuadtreeNode[] nodes;
/**
*
* Default constructor for QuadtreeNode
*/
public QuadtreeNode(int level, BasicRectangle boundBox)
{
this.level = level;
this.boundBox = boundBox;
objects = new ArrayList<BasicRectangle>();
nodes = new QuadtreeNode[4];
}
/**
*
* Splits the parent node into 4 leef nodes
*/
public void split()
{
float parentX = boundBox.getPosition().getX();
float parentY = boundBox.getPosition().getY();
nodes[0] = new QuadtreeNode(level+1, new BasicRectangle(new Vector2f(parentX+boundBox.getWidth()/2, parentY), boundBox.getWidth()/2, boundBox.getHeight()/2));
nodes[1] = new QuadtreeNode(level+1, new BasicRectangle(new Vector2f(parentX, parentY), boundBox.getWidth()/2, boundBox.getHeight()/2));
nodes[2] = new QuadtreeNode(level+1, new BasicRectangle(new Vector2f(parentX, parentY+boundBox.getHeight()/2), boundBox.getWidth()/2, boundBox.getHeight()/2));
nodes[3] = new QuadtreeNode(level+1, new BasicRectangle(new Vector2f(parentX+boundBox.getWidth()/2, parentY+boundBox.getHeight()/2), boundBox.getWidth()/2, boundBox.getHeight()/2));
children = true;
}
public int[] getIndex(BasicRectangle r)//TODO use intersection methods
{
int[] indexs = new int[4];
int e = 0;
float verticalMidpoint = boundBox.getPosition().getX() + (boundBox.getWidth() / 2);
float horizontalMidpoint = boundBox.getPosition().getY() + (boundBox.getHeight() / 2);
//BasicRectangle can completely fit within the top quadrants
boolean topQuadrant = (r.getPosition().getY() <= horizontalMidpoint);
//BasicRectangle can completely fit within the bottom quadrants
boolean bottomQuadrant = (r.getPosition().getY()+r.getHeight() >= horizontalMidpoint);
//BasicRectangle can completely fit within the left quadrants
boolean leftquadrant = (r.getPosition().getX() <= verticalMidpoint);
//BasicRectangle can completely fit within the right quadrants
boolean rightQuadrant = (r.getPosition().getX()+r.getWidth() >= verticalMidpoint);
if(topQuadrant && rightQuadrant)
{
indexs[e] = 0;
e++;
}
if(topQuadrant && leftquadrant)
{
indexs[e] = 1;
e++;
}
if(bottomQuadrant && leftquadrant)
{
indexs[e] = 2;
e++;
}
if(bottomQuadrant && rightQuadrant)
{
indexs[e] = 3;
}
for(int i =1;i<indexs.length;i++)
if(indexs[i] == 0)
indexs[i]=-1;
return indexs;
}
public void insert(BasicRectangle r)//TODO
{
if(children)
{
int[] indexs = getIndex(r);
for(int e : indexs)
if(e != -1)
nodes[e].insert(r);
return;
}
objects.add(r);
if(objects.size()>MAX_OBJECTS && level < MAX_LEVELS)
{
if(!children)
split();
int i = 0;
while(i<objects.size())
{
int[] indexs = getIndex(objects.get(i));
for(int e : indexs)
if(e != -1)
nodes[e].insert(objects.get(i));
objects.remove(i);
i++;
}
}
objects.trimToSize();
}
/**
* Return all objects that could collide with the given object
*/
public void retrieve(List<BasicRectangle> returnObjects, BasicRectangle r)
{
if(children)
{
int[] indexs = getIndex(r);
for(int e : indexs)
if(e != -1)
nodes[e].retrieve(returnObjects, r);
return;
}
for(BasicRectangle e : objects)
if(!returnObjects.contains(e))
returnObjects.addAll(objects);
/*if(!temp)
retrieveHelper(returnObjects);
temp = true;*/
while(returnObjects.contains(r))
returnObjects.remove(r);
}
public void retrieveHelper(List<BasicRectangle> returnObjects)
{
if(children)
for(QuadtreeNode e : nodes)
e.retrieveHelper(returnObjects);
returnObjects.addAll(objects);
}
/**
*
* clears the node
*/
public void clear()
{
objects.clear();
if(children)
for(QuadtreeNode e : nodes)
if(e != null)
{
e.clear();
e = null;
}
children = false;
temp = false;
}
public BasicRectangle getBoundBox()
{
return boundBox;
}
/**
*
* Strictly debug only (draw method with be Quadtree.java)
*/
public void draw()
{
if(children)
for(QuadtreeNode e : nodes)
e.draw();
else
boundBox.drawOutLine();
}
public void debugIndex(BasicRectangle r)
{
int[] indexs = getIndex(r);
System.out.println(Arrays.toString(indexs));
System.out.println("Parent node: "+objects.size());
for(BasicRectangle e : objects)
e.setColor(Color.yellow);
for(int e : indexs)
if(e != -1)
System.out.println("node "+e+": "+nodes[e].objects.size());
}
public QuadtreeNode[] getNodes()
{
return nodes;
}
}
答案 0 :(得分:0)
在insert方法中,而不是删除对象(objects.remove(i);)将i的对象设置为null(objects.set(i,null);)。