Skip to content
samme edited this page Nov 4, 2024 · 5 revisions

Phaser 3 includes RTree, a spatial index class based on RBush. Phaser uses it for Arcade Physics bodies, but you can also use it yourself.

Nodes are indexed by { left, right, top, bottom } and searched with { minX, maxX, minY, maxY }.

For objects without { left, right, top, bottom }, you can set a toBBox() ("to bounding box") method that gives { minX, maxX, minY, maxY }.

// This tree is for game objects.
const gTree = new Phaser.Structs.RTree();

// Provide a bounding box.
gTree.toBBox = (g) => {
  const { left: minX, right: maxX, top: minY, bottom: maxY } = g.getBounds();

  return { minxX, maxX, minY, maxY };
}

gTree.load(gameObjects);
// This tree is for 2d vectors (points).
const vTree = new Phaser.Structs.RTree();

// Provide a bounding box.
vTree.toBBox = ({ x, y }) => ({ minX: x, maxX: x, minY: y, maxY: y });

vTree.load(vectors);

After load() you should validate your tree once:

console.assert(Number.isFinite(vTree.data.minX));
console.assert(Number.isFinite(vTree.data.maxX));
console.assert(Number.isFinite(vTree.data.minY));
console.assert(Number.isFinite(vTree.data.maxY));

To update the tree you need to clear() and then load() again with new data.

For nonrectangular objects, you can do a 2-phase search:

// This tree is for circles.
const cTree = new Phaser.Structs.RTree();

cTree.load(circles);

// Search at position:
const x = 0;
const y = 0;

const results = cTree
  .search({ minX: x, minY: y, maxX: x + 1, maxY: y + 1 })
  .filter(circle => circle.contains(x, y));
Clone this wiki locally