Game Development Reference
In-Depth Information
import
java.util.List;
import
com.badlogic.androidgames.framework.GameObject;
import
android.util.FloatMath;
public class
SpatialHashGrid {
List<GameObject>[] dynamicCells;
List<GameObject>[] staticCells;
int
cellsPerRow;
int
cellsPerCol;
float
cellSize;
int
[] cellIds =
new int
[4];
List<GameObject> foundObjects;
As discussed, we store two cell lists, one for dynamic objects and one for static objects. We
also store the cells per row and column, so that we can later decide whether a point we check is
inside or outside the world. The cell size also needs to be stored. The
cellIds
array is a working
array that we can use to store the four cell IDs a
GameObject
is contained in temporarily. If it is
contained in only one cell, then only the first element of the array will be set to the cell ID of the
cell that contains the object entirely. If the object is contained in two cells, then the first two
elements of that array will hold the cell ID, and so on. To indicate the number of cell IDs, we set
all “empty� elements of the array to
-1
. The
foundObjects
list is also a working list, which we can
return upon a call to
getPotentialColliders()
. Why do we keep those two members instead
of instantiating a new array and list each time one is needed? Remember the garbage collector
monster.
@SuppressWarnings("unchecked")
public
SpatialHashGrid(
float
worldWidth,
float
worldHeight,
float
cellSize) {
this
.cellSize = cellSize;
this
.cellsPerRow = (
int
)FloatMath.
ceil
(worldWidth / cellSize);
this
.cellsPerCol = (
int
)FloatMath.
ceil
(worldHeight / cellSize);
int
numCells = cellsPerRow * cellsPerCol;
dynamicCells =
new
List[numCells];
staticCells =
new
List[numCells];
for
(
int
i = 0; i < numCells; i++) {
dynamicCells[i] =
new
ArrayList<GameObject>(10);
staticCells[i] =
new
ArrayList<GameObject>(10);
}
foundObjects =
new
ArrayList<GameObject>(10);
}
The constructor of that class takes the world's size and the desired cell size. From those
arguments, we calculate how many cells are needed, and instantiate the cell arrays and the
lists holding the objects contained in each cell. Initialize the
foundObjects
list. All the
ArrayList
instances we create will have an initial capacity of ten
GameObject
instances. We do this to avoid
memory allocations. The assumption is that it is unlikely that one single cell will contain more
than ten
GameObject
instances. As long as that is true, the array lists don't need to be resized.
public void
insertStaticObject(GameObject obj) {
int
[] cellIds = getCellIds(obj);