I'm using python for coding.
So i'm making a game engine which the main loop is something like that:
def mainLoop(self):
'''This loop run's every frame per second.'''
#Go through all sprite objects inside this scene.
for sprite in self.sprites:
#Update the sprite inside the quadtree.
if sprite.position.changed():
self.quadtree.update(sprite)
#Render the sprite only if it is inside the screen resolution.
if sprite.onScreen():
sprite.render()
#----------Get possible collision----------#
possible_collisions = self.quadtree.get()
for object in possible_collisions:
sprite.getCollision(object)
#----------Get possible collision----------#
#Run the logic of this sprite object.
if sprite.hasScript():
sprite.runScript()
Firstly i thought that the quadtree (for reducing the collision checks) was the problem. But it wasn't that, my quadtree is working perfectly. So in order to find out what was causing latency for a big amount of sprite objects into the scene, i disabled the collision detection algorithm and run the engine again in order to see if the efficiency will be better. Then i found out that it was still very slow. Finally the problem was the for loop. Even that the game loop wasn't doing to much to waste time, because the for loop was too big the frames where being delayed anyway.
So i thought of a solution but it costs in game mechanics. I will devide my scene using a quadtree, and i will only work with sprites inside this area (depended where the camera position is). So i will only run the scripts of those sprites. This will make the engine a lot faster but objects outside the specified area will be disabled because their scripts won't run. For example if an enemy is hunting the player, but the player moves far enough so the enemy will be placed in a quadtree node where is outside of the current node, the enemy's script will be disabled and he will freeze. In the image below, you can see how my scene will be devided.
Please notice that the red rectangles are not devisions of the scene but the big red rect is. The 9 rectangles shows how many windows the quadtree node is (A window has the screen (game) resolution).
The collision checks will also occur only for the sprites inside this area.
So the main loop now will loop like this:
def mainLoop(self):
area = self.quadtree.get()
for sprite in area:
#Update the sprite inside the quadtree.
if sprite.position.changed():
self.quadtree.update(sprite)
#Render the sprite only if it is inside the screen resolution.
if sprite.onScreen():
sprite.render()
#This is O(N^2) but i think will be ok because the area list will not be to big.
for sp in area:
if sp != sprite:
sp.getCollision(sprite)
#Run the logic of this sprite object.
if sprite.hasScript():
sprite.runScript()
There must be a better solutions for this problem, so i'm hearing suggestions.
Thank you for your time.
Just from curiosity, in modern game engines like unity 3d, an enemy who is at the other side of the map while the player is in the oposite side, will the enemy's logic run? Also assume that the scene is realy big!!!