Hey guys,
a friend and me are currently developing a 2d rpg game and having some trouble with efficiency for map structure.
The structure yet looks like:
1 world, containing several regions. The regions itself contain an array of chunks(2x2) and every chunk contains an array of blocks(40x40), which have 32px x 32px size.
Every block has a list of objects(entities, landscape, structures, e.g).
The function im working on is how to find entities in range around a point(can be a position of a unit) for aggro targeting, aoe spells e.g.
Currently my solution is that every entity stores the block where it is in and then searches recursively for the blocks neighboors and checks whether these neighboors containing objects which are in range.
Heres the sample code:
-LivingObject is an entity for storing the position
-These functions are stored in the block class(this. refers to a block)
public List<Object.LivingObject> getLivingObjectsInRange(Vector3 _Position, float _Range)
{
List<Object.LivingObject> result = new List<Object.LivingObject>();
List<Block> visitedBlocks = new List<Block>();
getLivingObjectsInRange(_Position, _Range, result, visitedBlocks);
return result;
}
public void getLivingObjectsInRange(Vector3 _Position, float _Range, List<Object.LivingObject> result, List<Block> visitedBlocks)
{
if (!visitedBlocks.Contains(this))
{
foreach (Object.LivingObject var_LivingObject in this.objects)
{
float distance = Vector3.Distance(_Position, var_LivingObject.Position);
if (distance <= _Range)
result.Add(var_LivingObject);
}
visitedBlocks.Add(this);
if (this.leftNeighbour != null && _Position.X - _Range < this.Position.X)
this.leftNeighbour.getLivingObjectsInRange(_Position, _Range, result, visitedBlocks);
if (this.rightNeighbour != null && _Position.X + _Range > this.Position.X + Block.BlockSize)
this.rightNeighbour.getLivingObjectsInRange(_Position, _Range, result, visitedBlocks);
if (this.bottomNeighbour != null && _Position.Y + _Range > this.Position.Y + Block.BlockSize)
this.bottomNeighbour.getLivingObjectsInRange(_Position, _Range, result, visitedBlocks);
if (this.topNeighbour != null && _Position.Y - _Range < this.Position.Y - Block.BlockSize)
this.topNeighbour.getLivingObjectsInRange(_Position, _Range, result, visitedBlocks);
}
}
The problem im facing is that this function drops the fps of the game from 60 to 2, when i create about 300 entities and every entity searches for other entities it can attack. This function gets called every update event as long as the entity has no target.
Do you have any suggestions on how we should structure our map data types or improve the functions to stay at 60fps? We are just in the beginning of the map development and entity storage so i would appreciate any hints how the storage and searching can be as efficient as possible
Greetings
Crashkurs