简体   繁体   English

某些手机​​的Andengine低FPS

[英]Andengine low FPS on certain phones

My game runs well on most phones (56 FPS), but others run the game at ~25 FPS. 我的游戏在大多数手机上运行良好(56 FPS),但其他游戏的运行速度约为25 FPS。 In my game I have 3 particle systems and as far as I can tell the problem comes from here. 在我的游戏中,我有3个粒子系统,据我所知,问题来自于此。 My question: Is it a good idea to stop spawning particles if I detect FPS lower than, let's say 30? 我的问题:如果我检测到FPS低于30,那么停止产生粒子是个好主意吗? An if the FPS is higher just run normally. 如果FPS更高,则只需正常运行。 I'm not sure if this can cause any problems. 我不确定这是否会导致任何问题。 Is there any other solution? 还有其他解决方案吗?

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. 您可以使用您的方法来检测fps,然后在必要时删除粒子系统。 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. 也许你也可以在运行时分析devies,即有多少内核,图形芯片等,并相应地进行调整。

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! 确保你的粒子被优化等,所以当它们可以更小等时你没有不必要的纹理尺寸,但我相信你可能已经做到了!

I would suggest you run all graphical features of your game, when it can be rendered at 30+ frames a second. 我建议你运行游戏的所有图形功能,当它可以每秒30帧以上渲染时。 If you see a frame rate under 30, you should switch off non-vital graphics eg. 如果您看到帧率低于30,则应关闭非重要图形,例如。 particles. 粒子。

try to set "android:theme="@style/Theme.NoBackground" for your activity in manifest. it's switch off system background redering. 尝试为清单中的活动设置“android:theme =”@ style / Theme.NoBackground“。它关闭了系统背景redering。

don't forger to create theme.xml: 不要伪造创建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>

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): 下面是确定线程是否按时执行的代码,如果没有,它将跳过帧(不超过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. 让我知道这个是否奏效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM