📄 quadnode.java
字号:
package magic.scene;
import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import magic.actor2d.*;
// 代表四方树中的一个单节点
public class QuadNode extends Object
{
// the next unique id to assign a node
protected static int UNIQUE_ID = 0;
// 标志这个节点的唯一整数
protected int id;
// 包含这个节点的父节点
protected QuadNode parent;
// 这个节点的子节点数组
protected QuadNode[] nodes;
// 当节点为叶子节点时为真 (无子节点)
protected boolean leaf;
// 这个节点的关联对象
protected LinkedList objects;
// 节点边界
protected Rectangle2D bounds;
// 默认构造函数
private QuadNode()
{
id = -1;
parent = null;
nodes = null;
leaf = true;
objects = null;
bounds = null;
}
// 用给定的父节点、深度和边界构造一个QuandNode对象
public QuadNode(QuadNode p, int depth, Rectangle2D r)
{
parent = p;
bounds = r;
id = UNIQUE_ID++;
// 如何剩余深度为零,则节点是叶子节点
if(depth == 0)
{
leaf = true;
objects = new LinkedList();
nodes = null;
QuadTree.addLeaf(this);
}
// 否则,节点包含四个子节点
else
{
leaf = false;
objects = null;
nodes = new QuadNode[4];
double x = bounds.getX();
double y = bounds.getY();
double w = bounds.getWidth();
double h = bounds.getHeight();
// 创建子节点
nodes[0] = new QuadNode(this, depth - 1, new Rectangle2D.Double(x, y + h/2, w/2, h/2));
nodes[1] = new QuadNode(this, depth - 1, new Rectangle2D.Double(x + w/2, y + h/2, w/2, h/2));
nodes[2] = new QuadNode(this, depth - 1, new Rectangle2D.Double(x + w/2, y , w/2, h/2));
nodes[3] = new QuadNode(this, depth - 1, new Rectangle2D.Double(x, y, w/2, h/2));
}
}
// 如果节点是叶子节点则返回true
public final boolean isLeaf()
{
return leaf;
}
// 尝试把传来的对象插入到这个节点中
public void insert(
Moveable c, // 要插入的 Moveable 对象
boolean propagate // 如果为真且c不在这个节点的边界中则向上寻找
)
{
// 试图插入节点
if(bounds.contains(c.getBounds()) || bounds.intersects(c.getBounds()))
{
// 如果节点是叶子节点,则把对象插入链表中
if(isLeaf())
{
if(objects == null)
{
objects = new LinkedList();
}
if(! objects.contains(c))
{
objects.add(c);
}
}
// 如果节点不是叶子节点,则继续向下插
else
{
for(int i = 0; i < 4; i++)
{
if(nodes[i] != null)
{
nodes[i].insert(c, false);
}
}
}
}
// 否则,如果允许递归,则向上插入对象
else
{
if(propagate)
{
if(parent != null)
{
parent.insert(c, true);
}
}
}
}
// 将这个节点所包含的所有对象都平移x,y
public void moveAll(double x, double y)
{
if(objects == null || objects.isEmpty()) return;
Actor2D a;
for(int i = 0; i < objects.size(); i++)
{
a = (Actor2D) objects.get(i);
a.moveBy(x, y);
}
}
public void update()
{
if(objects == null || objects.isEmpty()) return;
// 更新链表,然后删除那些不再在这个节点中的对象
Moveable m;
for(int i = 0; i < objects.size(); i++)
{
m = (Moveable)objects.get(i);
m.update();
// 测试是否对象离开了这个节点,如果是,则向上插入
if(!bounds.contains(m.getBounds()) && !bounds.intersects(m.getBounds())) // might propagate upward
{
insert((Moveable)objects.remove(i), true);
}
}
// 获取更新后的大小,因为有些对象可能已经被删除
int size = objects.size();
// 检查本节点的每一个对象之间的冲突
for(int i = 0; i < size-1; i++)
{
Moveable a = (Moveable)objects.get(i);
for(int j = i+1; j < size; j++)
{
Moveable b = (Moveable)objects.get(j);
if(a.collidesWith(b))
{
a.addCollision(b);
b.addCollision(a);
}
}
}
}
public void paintBounds(Graphics2D g2d, Color c)
{
if(c == null) c = Color.RED;
g2d.setPaint(c);
g2d.draw(bounds);
}
} // QuadNode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -