# Android Array Lag?

I am making a platform game for Android. It is sort of a tile based game. I added bullets and enemies with AI and a bunch of tile types.

I created a simple map with no Enemies. Everything was running well and smooth until I shot a bunch of bullets randomly everywhere. A couple of hundreds of bullets later, the FPS lowered.

I made a test to find out if the bullets were the problem so I made another simple map with just a tile to stand on and left it for a while. Minutes later, I played around with it a bit to check if the FPS changed and it didnt. I reloaded the same map and shot a lot of bullets. Minutes later, the FPS was visibly lower even after the number of bullets were zero.

Points to note:

• Programmed FPS is 30
• Tested on a Samsung Galaxy Y and Samsung Galaxy W
• Any tile, enemy, bullet that is off screen is not drawn to prevent lag
• Bullets collide with Tiles (if they dont collide with in 450 frames, they are removed from the array)
• I used List bullets = new ListArray();
• I used bullets.add(new Bullet(x, y, params...));
• I used for(...){ if(...){ bullets.remove(i); } }

Code for bullet:

private void drawBullets(Canvas canvas) {
for (int i = 0; i < bullets.size(); i++) {
Bullet b = bullets.get(i);
if (b.t > blm) { //if the bullet is past its expiry
bullets.remove(i);
i--;
} else {
if (svx((b.x)) > 0 && svx(b.x) < width && svy((b.y)) > 0
&& svy(b.y) < height) { // if bullet is not off screen
b.draw(canvas); // draw the bullet
}
}
}
}


I tried searching for solutions and references but I have no luck. I'm guessing that the lag has something to do with the Array and the Bullets or Classes that I've loaded? I'm not sure!

• Though this seems not the reason for weak FPS, after fixing the problem, you could further optimize it by using a linked list, or deleting the bullet like this: bullets[i] = bullets[bullets.length-1]; bullets.remove (bullets.length-1);, as otherwise all bullets after the one deleted need to be shifted left. – Markus von Broady Oct 28 '12 at 12:55
• We need to see b.update(...), Mike. Cheers for posting the main loop. – Engineer Oct 28 '12 at 12:57

Sounds like you're not cleaning up your bullets. They can't stay in the world forever, because everything that exists in the world requires processor time and consumes memory, also.

So you really need to keep track of projectiles that will just "expire" after a while (in most games we just do an alpha fade to prevent it from looking jarring). The simplest way to do that is just to have an "age" value on each bullet object that tracks the time in seconds/milliseconds/nanoseconds since the object was created. Each age value starts out at zero. Then on each game loop update, you're running through every entity to process it anyway, so you just look at the ones that are bullets and say

for (Entity entity : entities)
{
//...stuff to do wtih other entity types
if (entity instanceof Bullet) //or eg. if (entity.category == "bullet")
{

if (bullet.age >= EXPIRY_AGE)
{
//make sure bullet gets removed from list after we exit this foreach loop
}
else
{
bullet.age += howeverManyTimeUnitsHavePassedSinceLastUpdate;
}
}
}


This requires you to know how much time passed since the last step. If you're using a fixed timestep, that's easy -- it's whatever value your fixed timestep period is (1/fps). If not, then you may need to calculate time deltas.

• I actually have that. :( in the bullet I set a variable t that keep tracks of its life time length. Once t is greater than the expiry time, it is removed from the array. Do i need to do something else to the bullet? Because I really dont know where the lag is caused. Thanks anyway! :) – Mike Oct 28 '12 at 12:35
• @Mike, The slowdown is clearly related to the bullets, wouldn't you say? If that is so, then the only way that slowdown can present itself after an extended period is if your code still hasn't actually released all references to the bullets. Are you sure you do not have them in multiple lists, for instance? Another thing that can sometimes cause major slowdowns is when refs have been lost, but the runtime engine is still trying to access those properties and as such is spitting out huge amounts of error log messages because it has null refs (assuming debug logging is enabled on device). – Engineer Oct 28 '12 at 12:37
• What do you mean by released all references to the bullets? I can post the code for the bullet if it can help! – Mike Oct 28 '12 at 12:45
• @Mike, Garbage collection (GC). The Garbage Collector isn't going to release these guys unless there are exactly zero references to each one, remaining in your code after a few minutes. That may be having an impact. But I'm not too sure. To me, given your evidence, it sounds as if the bullets simply continue to stick around. More code can only help, post as much as you can, including game loop as the problem may be there. – Engineer Oct 28 '12 at 12:48
• I don't have enough reputation, sorry! but you have helped! Thank you so much Nick! :) – Mike Oct 28 '12 at 13:11

Step 1

Try at other devices + OS versions

On some devices that have auto-frame rate, this sets the maximum frame rate, not a constant frame rate. Actual frame rate will vary according to lighting conditions.

Because

The actual frame rate is dependent on the certain device(hardware) and OS version. It seemed that HTC Desire has a higher FPS than the HTC Desire z. Moreover, Android 2.2.1 has better frame rate control method than Android 2.3.3 does.

Step 2

If not solved then, check any problem at your algorithm or try to improve your algorithm.

• Are you cleaning up your bullets?
• Is there other codes that requires much processor time?
• Is there other codes that consumes much memory?
• I have used a thread that calls a function 30 times a second which keeps it at a constant rate. I am still checking step 2! Thank you though! – Mike Oct 28 '12 at 12:48
• @Mike, I have added a reference. This may help you for further debugging regarding Frame Rate – Md Mahbubur Rahman Oct 28 '12 at 12:50