4. Some optimizations

In a few of the recent posts I have mentioned points we could optimize later. I will show some of said optimizations in this post. First we will take a look at the creation and usage of objects, then we take a peek at improving the drawing process.

There are quite a few more optimizations (I have made) which I will either add or place in a new post depending when I remember or use them.

Object creation

The biggest resource hogger is the continuous creation of objects which are only used for a short amount of time.

An example

This is a small and modified piece of my path following system. The actual movement is handled by another system (the movement system). We grab the deltaX and deltaY, normalize the vector and scale it by maxSpeed. We then have the velocity in the x and y directions which we store in velocity's vx and vy variables. The problem here is the constant use of "new Vector2", which results in the allocation of new memory only to be used until the end of this method. This method is called up to 500 times per frame, can you see the waste of memory?

Vector2 vector;  
protected void process() {  
   //calculate deltaX and deltaY
   vector = new Vector2(deltaX, deltaY).nor().scl(MAXSPEED);
   velocity.vx = vector.x;
   velocity.vy = vector.y;
}

A better version is below. We removed the "new Vector2" part so it no longer allocates new memory every single time. This alone sped up my code by almost 10% (from 78fps average to 85fps average) on my ASUS Transformer.

Vector2 vector = new Vector2.Zero;  
protected void process() {  
   //calculate deltaX and deltaY
   vector.set(deltaX, deltaY).nor().scl(MAXSPEED);
   velocity.vx = vector.x;
   velocity.vy = vector.y;
}

Taking object creation one step further

In a future phase of my project, when necessary, I will perform some other optimizations like reusing objects for enemies, projectiles etc.

Drawing

The drawing code in my first 2 posts were awfully basic, no optimization whatsoever. One very straightforward optimization is to not draw any unnecessary tiles, like the tiles outside our viewport. For this we give the drawing loops certain parameters (startX, startY, endX, endY) and only draw between those values.
Like so:

for(int x = startX; x < endX; x++) {  
 for(int y = startY; y < endY; y++) {
    //draw
 }
}

For the SpriteCache version we can do:

cache.draw(cacheID, startY * world.width + startX, (endY - startY) * world.width + (endX - startX));  

This should speed up your code a LOT. In my testing map we have 2312 tiles which are being redrawn continuously. After this change we draw about 30x50 = 1500 tiles. The larger the map the more you benefit and this also results in a more steady use of resources, no matter your map size.

comments powered by Disqus