11

My game runs well on most phones (56 FPS), but others run the game at ~25 FPS. In my game I have 3 particle systems and as far as I can tell the problem comes from here. My question: Is it a good idea to stop spawning particles if I detect FPS lower than, let's say 30? An if the FPS is higher just run normally. I'm not sure if this can cause any problems. Is there any other solution?

4 Answers4

3

I can think of several things you can do to help alleviate this problem.

You could use your method to detect the fps and then drop the particle systems if necessary. However, you don't have to poll it every second - you could do it once every ten seconds or so. If you do have a low frame rate, then you know the phone is going to suffer every now and then, so then you dont need to poll any more - you can lower the particles and stop polling.

Or, you could use the polling method with several "levels" of particle effects, so if it cant handle the top level, drop the the next level of complexity, and so on.

Also, you could even allow the user to manually adjust the particle effects, ie in an option menu allow them to switch them to a low setting or something.

Perhaps you could also profile devies on runtime, ie how many cores, graphics chip etc and adjust accordingly.

Make sure your particles are optimized etc, so you dont have unecessary texture sizes when they could be smaller etc, but i'm sure you've probably done this!

Davos555
  • 1,974
  • 15
  • 23
  • Thank you for your answer, the particles are optimized, the "several levels" cannot be implemented because I cannot adjust how many particles are spawned after creation, but I am going to try the last method you described, probably checking for GPU, and GL version. –  Jul 16 '12 at 11:07
1

I would suggest you run all graphical features of your game, when it can be rendered at 30+ frames a second. If you see a frame rate under 30, you should switch off non-vital graphics eg. particles.

Luke Taylor
  • 9,481
  • 13
  • 41
  • 73
  • That is exactly what I wrote in the description, so it doesn't help me. Have you tried this method? Is it a good idea? Because for getting the FPS I have to register the counter to the engine, and then check every second if conditions are satisfied. –  Jul 16 '12 at 08:36
  • Sure it's a good idea. Believe me, I would prefer a game with no special graphic effects than a game that has a bad FPS. You could check if the phone is first or second generation, if it's first, then don't display the special graphics (since it will most probably cause a low FPS). If it is a second generation phone, then display special graphics. There are other methods that you could use as well to see if the phone can produce the desired FPS, you could have some kind of calibration. – Luke Taylor Jul 16 '12 at 12:57
0

try to set "android:theme="@style/Theme.NoBackground" for your activity in manifest. it's switch off system background redering.

don't forger to create theme.xml:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <style name="Theme.NoBackground" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
</style>
</resources>
Andrew F
  • 1,712
  • 2
  • 15
  • 24
  • 1
    I think what you are saying is applicable for apps. I don't see how this is related to Andengine. –  Jul 12 '12 at 13:30
0

Try skipping frames if frame rate gets lower, but dont skip too much frames otherwise it will result in poor user experience. Below is the code to determine whether thread executes on time, if not it will skip frames (not more than 5):

// desired fps
private final static int    MAX_FPS = 50;
// maximum number of frames to be skipped
private final static int    MAX_FRAME_SKIPS = 5;
// the frame period
private final static int    FRAME_PERIOD = 1000 / MAX_FPS;
// number of frames skipped since the game started
private long totalFramesSkipped         = 0l;
// number of frames skipped in a store cycle (1 sec)
private long framesSkippedPerStatCycle  = 0l;

// number of rendered frames in an interval
private int frameCountPerStatCycle = 0;
private long totalFrameCount = 0l;
// the last FPS values
private double  fpsStore[];
// the number of times the stat has been read
private long    statsCount = 0;
// the average FPS since the game started
private double  averageFps = 0.0;

    long beginTime;     // the time when the cycle begun
    long timeDiff;      // the time it took for the cycle to execute
    int sleepTime;      // ms to sleep (<0 if we're behind)
    int framesSkipped;  // number of frames being skipped 

    sleepTime = 0;
                beginTime = System.currentTimeMillis();
                framesSkipped = 0;  // resetting the frames skipped
                // calculate how long did the cycle take
                timeDiff = System.currentTimeMillis() - beginTime;
                // calculate sleep time
                sleepTime = (int)(FRAME_PERIOD - timeDiff);

                if (sleepTime > 0) {
                    // if sleepTime > 0 we're OK
                    try {
                        // send the thread to sleep for a short period
                        // very useful for battery saving
                        Thread.sleep(sleepTime);
                    } catch (InterruptedException e) {}
                }

                while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
                    // we need to catch up
                    this.gamePanel.update(); // update without rendering
                    sleepTime += FRAME_PERIOD;  // add frame period to check if in next frame
                    framesSkipped++;
                }

Let me know if this works.

Adnan Zahid
  • 573
  • 1
  • 10
  • 38
  • 1
    This is not how Andengine works, and calling Thread.sleep will block the UI resulting in a bad user experience. –  Jul 22 '12 at 10:07