Home » Android » java – Andengine low FPS on certain phones

java – Andengine low FPS on certain phones

Posted by: admin May 14, 2020 Leave a comment

Questions:

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?

How to&Answers:

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!

Answer:

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.

Answer:

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>

Answer:

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.