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

简介:
 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:[email]ceponline@yahoo.com.cn[/email] 
* @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:[email]ceponline@yahoo.com.cn[/email] 
* @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:[email]ceponline@yahoo.com.cn[/email]
* @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);
                        }
                });
        }

}

本文转自 cping 51CTO博客,原文链接: http://blog.51cto.com/cping1982/116709
相关文章
|
1天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
1月前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
64 2
|
1月前
|
分布式计算 Java MaxCompute
ODPS MR节点跑graph连通分量计算代码报错java heap space如何解决
任务启动命令:jar -resources odps-graph-connect-family-2.0-SNAPSHOT.jar -classpath ./odps-graph-connect-family-2.0-SNAPSHOT.jar ConnectFamily 若是设置参数该如何设置
|
2月前
|
机器学习/深度学习 算法 搜索推荐
让星星⭐月亮告诉你,Java冒泡排序及其时间复杂度计算
冒泡排序是一种简单的排序算法,通过多次遍历数组,每次比较相邻元素并交换位置,将较小的元素逐步移至数组前端。第一轮结束后,最小值会位于首位;第二轮则将次小值置于第二位,依此类推。经过 (n-1) 轮遍历后,数组完成排序。冒泡排序的时间复杂度为 O(n²),在最优情况下(已排序数组)时间复杂度为 O(n)。示例代码展示了如何实现冒泡排序。
64 1
|
2月前
|
分布式计算 资源调度 Hadoop
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
118 3
|
1月前
|
Java API Apache
java集合的组内平均值怎么计算
通过本文的介绍,我们了解了在Java中计算集合的组内平均值的几种方法。每种方法都有其优缺点,具体选择哪种方法应根据实际需求和场景决定。无论是使用传统的循环方法,还是利用Java 8的Stream API,亦或是使用第三方库(如Apache Commons Collections和Guava),都可以有效地计算集合的组内平均值。希望本文对您理解和实现Java中的集合平均值计算有所帮助。
40 0
|
2月前
|
消息中间件 Java Kafka
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
61 1
|
4月前
|
Rust JavaScript Java
简单对比Java、Python、Go、Rust等常见语言计算斐波拉契数的性能
简单对比Java、Python、Go、Rust等常见语言计算斐波拉契数的性能
|
5月前
|
搜索推荐 Java 大数据
Java中的数据流处理与流式计算实现
Java中的数据流处理与流式计算实现
|
5月前
|
并行计算 Java 大数据
Java中的高效并行计算与多线程编程技术
Java中的高效并行计算与多线程编程技术