您的位置:首页 > 编程语言 > Java开发

JAVA图形操作中FPS的计算(附带随机生成乱数球体用例)

2007-10-17 11:19 399 查看
 FPS:即帧 /秒(frames per second)的缩写,也称为帧速率。是指1秒钟时间里刷新的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次。如果具体到手机上就是指每秒钟能够 播放(或者录制)多少格画面。同时越高的帧速率可以得到更流畅、更逼真的动画。每秒钟帧数(fps)越多,所显示的动作就会越流畅。

在绝大多数图形程序中(以游戏类为典型),执行效率都以FPS作为评估标准。

由于目前JAVA方面缺少相关用例,故完成功能如下图(在本机测试中,最大fps设定为500,实际达到FPS效率在IDE中280左右,单独运行380左右,受系统配置等因素影响):

代码如下:

(请变更文件后缀为jar)



FPS相关操作代码如下:


package org.test;




import java.text.DecimalFormat;






/** *//**


 * <p>Title: LoonFramework</p>


 * <p>Description:</p>


 * <p>Copyright: Copyright (c) 2007</p>


 * <p>Company: LoonFramework</p>


 * @author chenpeng  


 * @email:ceponline@yahoo.com.cn 


 * @version 0.1


 */




public class FPSListen ...{


    //设定动画的FPS桢数,此数值越高,动画速度越快。


    public static final int FPS = 500;  




    // 换算为运行周期


    public static final long PERIOD = (long) (1.0 / FPS * 1000000000); // 单位: ns(纳秒)




    // FPS最大间隔时间,换算为1s = 10^9ns


    public static long FPS_MAX_INTERVAL = 1000000000L; // 单位: ns


    


    // 实际的FPS数值


    private double nowFPS = 0.0;


    


    // FPS累计用间距时间


    private long interval = 0L; // in ns


    private long time;




    //运行桢累计


    private long frameCount = 0;


    


    //格式化小数位数


    private DecimalFormat df = new DecimalFormat("0.0");


 


    //开启opengl




    public void opengl()...{


        System.setProperty("sun.java2d.opengl", "True");


        System.setProperty("sun.java2d.translaccel", "True");


    }


    




    




    /** *//**


     * 制造FPS数据


     * 


     */




    public void makeFPS() ...{


        frameCount++;


        interval += PERIOD;




        //当实际间隔符合时间时。




        if (interval >= FPS_MAX_INTERVAL) ...{


            //nanoTime()返回最准确的可用系统计时器的当前值,以毫微秒为单位


            long timeNow = System.nanoTime();


            // 获得到目前为止的时间距离


            long realTime = timeNow - time; // 单位: ns




            //换算为实际的fps数值


            nowFPS = ((double) frameCount / realTime) * FPS_MAX_INTERVAL;


            //变更数值


            frameCount = 0L;


            interval = 0L;


            time = timeNow;


        }


    }




    public long getFrameCount() ...{


        return frameCount;


    }




    public void setFrameCount(long frameCount) ...{


        this.frameCount = frameCount;


    }




    public long getInterval() ...{


        return interval;


    }




    public void setInterval(long interval) ...{


        this.interval = interval;


    }




    public double getNowFPS() ...{


        return nowFPS;


    }




    public void setNowFPS(double nowFPS) ...{


        this.nowFPS = nowFPS;


    }




    public long getTime() ...{


        return time;


    }




    public void setTime(long time) ...{


        this.time = time;


    }




    public String getFPS()...{


        return df.format(nowFPS);


    }




}





球体类代码如下:


package org.test;




import java.awt.Color;


import java.awt.Graphics;






/** *//**


 * <p>Title: LoonFramework</p>


 * <p>Description:</p>


 * <p>Copyright: Copyright (c) 2007</p>


 * <p>Company: LoonFramework</p>


 * @author chenpeng  


 * @email:ceponline@yahoo.com.cn 


 * @version 0.1


 */




public class Ball ...{


        private static final int SIZE = 10;


        private int x, y;


        protected int vx, vy;






        public Ball(int x, int y, int vx, int vy) ...{


            this.x = x;


            this.y = y;


            this.vx = vx;


            this.vy = vy;


        }






        public void move() ...{


            x += vx;


            y += vy;




            if (x < 0 || x > BallPanel.WIDTH - SIZE) ...{


                vx = -vx;


            }




            if (y < 0 || y > BallPanel.HEIGHT - SIZE) ...{


                vy = -vy;


            }


        }






        public void draw(Graphics g) ...{


            g.setColor(Color.RED);


            g.fillOval(x, y, SIZE, SIZE);


        }


    




}





FPS及球体处理用代码如下:


package org.test;




import java.awt.Color;


import java.awt.Dimension;


import java.awt.Frame;


import java.awt.Graphics;


import java.awt.Image;


import java.awt.Panel;


import java.awt.event.WindowAdapter;


import java.awt.event.WindowEvent;


import java.awt.image.BufferedImage;


import java.util.Random;








/** *//**


 * <p>


 * Title: LoonFramework


 * </p>


 * <p>


 * Description:以JAVA获取FPS用演示程序及随机生成乱数球体。(更优化代码内置于loonframework-game框架中)


 * </p>


 * <p>


 * Copyright: Copyright (c) 2007


 * </p>


 * <p>


 * Company: LoonFramework


 * </p>


 * 


 * @author chenpeng


 * @email:ceponline@yahoo.com.cn


 * @version 0.1


 */




public class BallPanel extends Panel implements Runnable ...{






    /** *//**


     * 


     */


    private static final long serialVersionUID = 1L;




    public static final int WIDTH = 360;




    public static final int HEIGHT = 360;




    // 设定最大球体数量


    private static final int NUM_BALLS = 50;




    // 定义球体数组


    private Ball[] ball;




    // 运行状态


    private volatile boolean running = false;




    private Thread gameLoop;




    // 缓存用图形


    private Graphics bg;




    private Image screen = null;




    // 生成随机数


    private Random rand;




    // fps监听


    private FPSListen fps = null;






    public BallPanel() ...{


        setPreferredSize(new Dimension(WIDTH, HEIGHT));


        screen = new BufferedImage(WIDTH, HEIGHT, 1);


        bg = screen.getGraphics();


        fps = new FPSListen();


        //fps.opengl();


        // 以当前毫秒生成随机数


        rand = new Random(System.currentTimeMillis());


        ball = new Ball[NUM_BALLS];


        // 初始化球体参数




        for (int i = 0; i < NUM_BALLS; i++) ...{


            int x = rand.nextInt(WIDTH);


            int y = rand.nextInt(HEIGHT);


            int vx = rand.nextInt(10);


            int vy = rand.nextInt(10);


            ball[i] = new Ball(x, y, vx, vy);


        }


    }




    // 加入Notify




    public void addNotify() ...{


        super.addNotify();


        // 判断循环条件是否成立




        if (gameLoop == null || !running) ...{


            gameLoop = new Thread(this);


            gameLoop.start();


        }


    }






    /** *//**


     * 进行线程运作。


     */




    public void run() ...{


        long beforeTime, afterTime, timeDiff, sleepTime;


        long overSleepTime = 0L;


        int noDelays = 0;


        // 获得精确纳秒时间


        beforeTime = System.nanoTime();


        fps.setTime(beforeTime);


        running = true;




        while (running) ...{


            gameUpdate();


            repaint();


            afterTime = System.nanoTime();


            timeDiff = afterTime - beforeTime;


            // 换算间隔时间


            sleepTime = (FPSListen.PERIOD - timeDiff) - overSleepTime;




            if (sleepTime > 0) ...{


                // 制造延迟




                try ...{


                    Thread.sleep(sleepTime / 1000000L); // nano->ms




                } catch (InterruptedException e) ...{


                }


                // 获得延迟时间


                overSleepTime = (System.nanoTime() - afterTime) - sleepTime;




            } else ...{


                // 重新计算


                overSleepTime = 0L;


                // 判断noDelays值




                if (++noDelays >= 16) ...{


                    Thread.yield(); // 令线程让步


                    noDelays = 0;


                }


            }




            // 重新获得beforeTime


            beforeTime = System.nanoTime();




            // 制造FPS结果


            fps.makeFPS();


        }




    }






    /** *//**


     * 变更球体轨迹


     * 


     */




    private void gameUpdate() ...{




        for (int i = 0; i < NUM_BALLS; i++) ...{


            ball[i].move();


        }


    }






    /** *//**


     * 变更图形


     */




    public void update(Graphics g) ...{


        paint(g);


    }






    /** *//**


     * 显示图形


     */




    public void paint(Graphics g) ...{




        // 设定背景为白色,并清空图形


        bg.setColor(Color.WHITE);


        bg.fillRect(0, 0, WIDTH, HEIGHT);




        // FPS数值显示


        bg.setColor(Color.BLUE);


        bg.drawString("FPS: " + fps.getFPS(), 4, 16);




        // 分别绘制相应球体




        for (int i = 0; i < NUM_BALLS; i++) ...{


            ball[i].draw(bg);


        }


        g.drawImage(screen, 0, 0, this);


        g.dispose();


    }






    public static void main(String[] args) ...{




        Frame frm = new Frame();


        frm.setTitle("Java FPS速度测试(由Loonframework框架提供)");


        frm.setSize(WIDTH, HEIGHT+20);


        frm.setResizable(false);


        frm.add(new BallPanel());


        frm.setVisible(true);




        frm.addWindowListener(new WindowAdapter()...{




            public void windowClosing(WindowEvent e)...{


                System.exit(0);


            }


        });


    }




}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐