Android测量每秒帧数Frames Per Second (FPS)的方法
程序员文章站
2023-12-01 19:53:16
本文实例讲述了android测量每秒帧数frames per second (fps)的方法。分享给大家供大家参考。具体如下:
mainthread.java:...
本文实例讲述了android测量每秒帧数frames per second (fps)的方法。分享给大家供大家参考。具体如下:
mainthread.java:
package net.obviam.droidz; import java.text.decimalformat; import android.graphics.canvas; import android.util.log; import android.view.surfaceholder; /** * @author impaler * * the main thread which contains the game loop. the thread must have access to * the surface view and holder to trigger events every game tick. */ public class mainthread extends thread { private static final string tag = mainthread.class.getsimplename(); // 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; // stuff for stats */ private decimalformat df = new decimalformat("0.##"); // 2 dp // we'll be reading the stats every second private final static int stat_interval = 1000; //ms // the average will be calculated by storing // the last n fpss private final static int fps_history_nr = 10; // last time the status was stored private long laststatusstore = 0; // the status time counter private long statusintervaltimer = 0l; // 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; // surface holder that can access the physical surface private surfaceholder surfaceholder; // the actual view that handles inputs // and draws to the surface private maingamepanel gamepanel; // flag to hold game state private boolean running; public void setrunning(boolean running) { this.running = running; } public mainthread(surfaceholder surfaceholder, maingamepanel gamepanel) { super(); this.surfaceholder = surfaceholder; this.gamepanel = gamepanel; } @override public void run() { canvas canvas; log.d(tag, "starting game loop"); // initialise timing elements for stat gathering inittimingelements(); 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; while (running) { canvas = null; // try locking the canvas for exclusive pixel editing // in the surface try { canvas = this.surfaceholder.lockcanvas(); synchronized (surfaceholder) { begintime = system.currenttimemillis(); framesskipped = 0; // resetting the frames skipped // update game state this.gamepanel.update(); // render state to the screen // draws the canvas on the panel this.gamepanel.render(canvas); // 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++; } if (framesskipped > 0) { log.d(tag, "skipped:" + framesskipped); } // for statistics framesskippedperstatcycle += framesskipped; // calling the routine to store the gathered statistics storestats(); } } finally { // in case of an exception the surface is not left in // an inconsistent state if (canvas != null) { surfaceholder.unlockcanvasandpost(canvas); } } // end finally } } /** * the statistics - it is called every cycle, it checks if time since last * store is greater than the statistics gathering period (1 sec) and if so * it calculates the fps for the last period and stores it. * * it tracks the number of frames per period. the number of frames since * the start of the period are summed up and the calculation takes part * only if the next period and the frame count is reset to 0. */ private void storestats() { framecountperstatcycle++; totalframecount++; // check the actual time statusintervaltimer += (system.currenttimemillis() - statusintervaltimer); if (statusintervaltimer >= laststatusstore + stat_interval) { // calculate the actual frames pers status check interval double actualfps = (double)(framecountperstatcycle / (stat_interval / 1000)); //stores the latest fps in the array fpsstore[(int) statscount % fps_history_nr] = actualfps; // increase the number of times statistics was calculated statscount++; double totalfps = 0.0; // sum up the stored fps values for (int i = 0; i < fps_history_nr; i++) { totalfps += fpsstore[i]; } // obtain the average if (statscount < fps_history_nr) { // in case of the first 10 triggers averagefps = totalfps / statscount; } else { averagefps = totalfps / fps_history_nr; } // saving the number of total frames skipped totalframesskipped += framesskippedperstatcycle; // resetting the counters after a status record (1 sec) framesskippedperstatcycle = 0; statusintervaltimer = 0; framecountperstatcycle = 0; statusintervaltimer = system.currenttimemillis(); laststatusstore = statusintervaltimer; // log.d(tag, "average fps:" + df.format(averagefps)); gamepanel.setavgfps("fps: " + df.format(averagefps)); } } private void inittimingelements() { // initialise timing elements fpsstore = new double[fps_history_nr]; for (int i = 0; i < fps_history_nr; i++) { fpsstore[i] = 0.0; } log.d(tag + ".inittimingelements()", "timing elements for stats initialised"); } }
希望本文所述对大家的java程序设计有所帮助。