简单的FPS计数器

时间:2019-04-15 09:40:57

标签: java frame-rate

我正在用Java制作CUI游戏,并想在游戏中制作FPS计数器。谁能给我一个简单的FPS计数器的代码,该计数器会不断更新?

我尝试过

package Main;



public class Main {

    public static void main(String[] args) {

        double old_time = System.nanoTime();

        System.out.println("FPS: " + get_fps(old_time));

    }


    private double get_fps(double old_time) {
        double new_time = System.nanoTime();
        double delta =  - old_time;
        double fps = 1 / (delta * 1000);
        old_time = new_time;
        return fps;
    }



}

注意:输出应该像

FPS: FPS

1 个答案:

答案 0 :(得分:1)

即使您真的是刚开始,我想我也会在一个循环中分享一个非常基本的FPS计数器示例。我不确定“ CUI”游戏是什么,但这说明了基本的渲染/更新循环。为什么要下暴风雪?今天这里很冷。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.util.Arrays;
import java.util.Random;
import javax.swing.JFrame;

@SuppressWarnings("serial")
public class FpsDemo extends JFrame implements Runnable {
    // statics
    private final static int SCREENHEIGHT = 800;
    private final static int SCREENWIDTH = 1200;
    private final static int NOF_SNOWFLAKES = 1000;
    private final static int NOF_SPEEDS = 5;
    private final static int BACKGROUND = colour(0xB, 0x16, 0x2C);      
    private final static int WHITE = colour(0xFF, 0xFF, 0xFF);

    // for each snowflake [i], [i][0] = x coord, [i][1] = y coord and [i][2] = speed
    private final static int snow[][] = new int[NOF_SNOWFLAKES][3];

    // for each column, a height
    private final static int pile[] = new int[SCREENWIDTH];


    /* Code entry point */
    public static void main(String[] args) {
        new FpsDemo().run();
    }


    /* Instantiates an instance of this class */
    public FpsDemo() {
        super("My FPS Demo");
        setSize(SCREENWIDTH, SCREENHEIGHT);
        setVisible(true);
    }


    /* Contains the main loop */
    @Override
    public void run() {
        // setup an off-screen buffer to draw to
        BufferedImage screen = new BufferedImage(SCREENWIDTH, SCREENHEIGHT, BufferedImage.TYPE_INT_RGB);
        int[] screenData = ((DataBufferInt) screen.getRaster().getDataBuffer()).getData();
        Graphics gs = getGraphics();
        gs.setColor(Color.white);

        // prepare some colours
        int[] shades = new int[NOF_SPEEDS+1];
        for(int i=0; i<NOF_SPEEDS; i++) {
            int j = 50 + i * ((255-50)/NOF_SPEEDS);
            shades[NOF_SPEEDS-i] = colour(j, j, j);
        }

        // arrange our initial data
        Random random = new Random();
        Arrays.fill(pile, SCREENHEIGHT);
        for(int i=0; i<NOF_SNOWFLAKES; i++) {
            snow[i][0] = random.nextInt(SCREENWIDTH);
            snow[i][1] = random.nextInt(SCREENHEIGHT);
            snow[i][2] = random.nextInt(4) + 1;
        }

        // loop forever (well, until an ArrayOutOfBoundsException...)
        double fps = 0;
        int frameCount = 0;
        long startTime = System.nanoTime();
        int throttle = NOF_SPEEDS;
        while(true) {
            Arrays.fill(screenData, BACKGROUND);

            // For each pile
            for(int x=0; x<SCREENWIDTH; x++) {
                for(int y=pile[x], j=x+pile[x]*SCREENWIDTH; y<SCREENHEIGHT; y++, j+=SCREENWIDTH) {
                    screenData[j] = WHITE;
                }
            }

            // For each snow flake
            for(int i=0; i<NOF_SNOWFLAKES; i++) {
                // Render the snow flake to the off-screen buffer
                int j = snow[i][0]+(snow[i][1]*SCREENWIDTH);
                screenData[j] = shades[snow[i][2]];

                // Update for next render
                if(snow[i][2] < throttle) {
                    // check the next row down
                    if(snow[i][1]+1 < pile[ snow[i][0] ] && snow[i][1] < SCREENHEIGHT) {
                        snow[i][1]++;

                    // slide left
                    } else if(snow[i][0]>1 && snow[i][1]+1 < pile[ snow[i][0]-1 ] && snow[i][1] < SCREENHEIGHT) {
                        snow[i][1]++;
                        snow[i][0]--;

                    // slide right
                    } else if(snow[i][0]<SCREENWIDTH-1 && snow[i][1]+1 < pile[ snow[i][0]+1 ] && snow[i][1] < SCREENHEIGHT) {
                        snow[i][1]++;
                        snow[i][0]++;

                    // we hit the pile                      
                    } else {
                        pile[snow[i][0]]--;
                        snow[i][1] = random.nextInt(SCREENWIDTH);
                        snow[i][1] = 0;
                        snow[i][2] = random.nextInt(4) + 1;
                    }
                }
            }

            // Flip the image buffer across in one go.
            if (gs!=null) {
                gs.drawImage(screen, 0, 0, null);
            }

            // Select less snow flakes each loop so we get a parallax effect 
            throttle--;
            if(throttle == 0) {
                throttle = NOF_SPEEDS;
            }

            // Update FPS 
            frameCount++;
            long now = System.nanoTime();
            // has it been more than 1 second (1bn nanos)?
            long wallclock = now - startTime;
            if(wallclock > 1000000000) {
                fps = frameCount / (wallclock/1000000000);
                startTime = now;
                frameCount = 0;
                this.setTitle("FPS: " + fps);
            }

            // You could try calculating a delay to achieve a specific FPS
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    /* Convenience method to convert RGB values (in the range 0-255) into a single integer */
    private static int colour(int r, int g, int b) {
        return (r*65536) + (g*256) + b;
    }
}