I'm working with a very large grid-based world that has around 50-90% of its grid spaces empty at any given time, therefore I chose to use a HashMap over an array.
The problem is that basic interactions don't seem to be working right, and I think it's because of some disconnect between the position the hashmap is using as a key and position as the grid object knows it.
These are the problems I'm having:
- object's ability to detect its neighbors is unreliable
- object deletion is unreliable
Here is the code:
The getNeighbors
method of GridObject
:
public ArrayList<GridObject> getNeighbors()
{
ArrayList<GridObject> neighbors = new ArrayList<GridObject>(8);
final int[] d = {-1, 0, 1};
for(int i : d)
for(int j : d)
if(j != 0 || i != 0) // Don't use (0, 0)
{ // Manager is just a wrapper for the HashMap; treat this like HashMap.get()
GridObject p = manager.get(location.x + i, location.y + j);
if(p != null) neighbors.add(p);
}
return neighbors;
}
This is from the update method of the Manager
class. MarkedForRemoval
is a java.util.Stack
of Points that is populated by GridObject
s that call Manager.markForRemoval()
, which just pushes a passed point into the stack. update()
runs once a frame:
public void update()
{
// libgdx graphics stuff
renderTarget.setColor(new Color(0f, 0f, 0f, 0f));
renderTarget.fill();
for(GridObject p : map.values())
{
renderTarget.drawPixel(p.location.x, p.location.y, Color.rgba8888(p.team.getColor()));
p.update();
}
while(!markedForRemoval.isEmpty())
map.remove(markedForRemoval.pop());
}
And this is the Manager.put()
method, which is the only way that new GridObjects are added:
public GridObject put(int x, int y)
{
final Point p = new Point(x, y);
return map.put(p, new GridObject(this, p));
}
And finally the Manager.get()
method:
public GridObject get(int x, int y)
{
return get(new Point(x, y));
}
I am using java.awt.Point to store the locations, which has both Objects.equals() and Object.hashCode() implemented correctly, as far as I know.
I am lost as to where I have gone wrong.