游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4732|回复: 0

JAVA图形程序中获得FPS桢数

[复制链接]

10

主题

18

帖子

28

积分

注册会员

Rank: 2

积分
28
发表于 2007-10-17 18:54:00 | 显示全部楼层 |阅读模式
FPS:即帧 /秒(frames per second)的缩写,也称为帧速率。是指1秒钟时间里刷新的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次。如果具体到手机上就是指每秒钟能够播放(或者录制)多少格画面。同时越高的帧速率可以得到更流畅、更逼真的动画。每秒钟帧数(fps)越多,所显示的动作就会越流畅。

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

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

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 = 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.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.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);
            }
        });
    }

}

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-20 12:02

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表