3
\$\begingroup\$

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);
        b.update(canvas); //updates physics 
        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!

Someone please help!

Thanks in advance! :)

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$ Oct 28, 2012 at 12:55
  • \$\begingroup\$ We need to see b.update(...), Mike. Cheers for posting the main loop. \$\endgroup\$
    – Engineer
    Oct 28, 2012 at 12:57

2 Answers 2

3
\$\begingroup\$

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.

\$\endgroup\$
9
  • \$\begingroup\$ 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! :) \$\endgroup\$
    – Mike
    Oct 28, 2012 at 12:35
  • \$\begingroup\$ @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). \$\endgroup\$
    – Engineer
    Oct 28, 2012 at 12:37
  • \$\begingroup\$ What do you mean by released all references to the bullets? I can post the code for the bullet if it can help! \$\endgroup\$
    – Mike
    Oct 28, 2012 at 12:45
  • \$\begingroup\$ @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. \$\endgroup\$
    – Engineer
    Oct 28, 2012 at 12:48
  • 2
    \$\begingroup\$ I don't have enough reputation, sorry! but you have helped! Thank you so much Nick! :) \$\endgroup\$
    – Mike
    Oct 28, 2012 at 13:11
0
\$\begingroup\$

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?
\$\endgroup\$
2
  • \$\begingroup\$ 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! \$\endgroup\$
    – Mike
    Oct 28, 2012 at 12:48
  • \$\begingroup\$ @Mike, I have added a reference. This may help you for further debugging regarding Frame Rate \$\endgroup\$ Oct 28, 2012 at 12:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .