java - 我第一次尝试玩 Java 游戏时,在读取图像时以 7 fps 结束?

标签 java javax.imageio frame-rate

最近我一直在尝试根据我在 CS 类(class)中获得的知识构建一个小游戏(2d,没什么大的)。在阅读了 Graphic 相关类的文档大约 2 周后,我遇到了这种情况: 我有一个以每秒 60 次游戏逻辑更新/60 帧运行的运行系统(该系统运行得非常好 :D)。作为第一个小测试,我想让图像在屏幕上移动。这就是代码(部分是我的,部分来自一些教程):

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Dimension;
import java.awt.Graphics;

import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;



import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = 1L;

public static final String NAME= "PokeCraft PRE-ALPHA";
public static final int HEIGHT=720;
public static final int WIDTH=HEIGHT*16/9;
public static final int SCALE=1;

private int fps=0;
private int tps=0;



private boolean running;
private int tickCount;
public void start(){
    running = true;
    new Thread(this).start();
}

public void stop(){
    running = false;

}

public void render(){
    BufferStrategy bufferStrategy =getBufferStrategy();
    if(bufferStrategy==null){
        this.createBufferStrategy(3);
        return;
    }

    /* render function */

      Graphics g = (Graphics) bufferStrategy.getDrawGraphics();
      g.clearRect(0, 0, super.getWidth(), super.getHeight());

      Image img = null;
      try{
          String imgPath = "data/MF.png";
          img = ImageIO.read(getClass().getResourceAsStream(imgPath));


      } catch(Exception e){
          System.out.println(e);
      }


        g.drawImage(img, tickCount, 0, null);
        Font font = new Font("Verdana",0,11);
        g.setFont(font);
        g.setColor(Color.RED);
        g.drawString(NAME+" / "+fps+" fps, "+tps+"tps", 5, 15);
      g.dispose();
      bufferStrategy.show();
}


public void run() {
    long lastTime= System.nanoTime();
    double unprocessed = 0;
    double nsPerTick = 1000000000.0/60.0;
    int frames = 0;
    int ticks = 0;
    long lastTimer1 = System.currentTimeMillis();

    while(running){
        long now = System.nanoTime();
        unprocessed += (now-lastTime)/nsPerTick;
        lastTime= now;
        boolean shouldRender= false;
        while(unprocessed >= 1){
            ticks++;
            tick();
            unprocessed -= 1;
            shouldRender = true;
        }
        if(shouldRender){
        frames++;
        render();
        }

        if(System.currentTimeMillis()-lastTimer1 > 1000){

            lastTimer1 += 1000;
            System.out.println(ticks+" ticks, "+frames + " fps");
            fps=frames;
            tps=ticks;
            ticks = 0;
            frames = 0;
        }
    }
}



public void tick(){
    tickCount++;
}

public static void main(String[] args){
    Game game= new Game();
    game.setPreferredSize(new Dimension(WIDTH*SCALE, HEIGHT*SCALE));
    game.setMinimumSize(new Dimension(WIDTH*SCALE, HEIGHT*SCALE));
    game.setMaximumSize(new Dimension(WIDTH*SCALE, HEIGHT*SCALE));



    JFrame frame = new JFrame(Game.NAME);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new BorderLayout());
    frame.add(game);
    frame.pack();
    frame.setResizable(true);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    game.start();
    }
}

ImageIO.read(...) 对性能的影响非常大(根据 VisualVM,每次运行大约需要 200 毫秒)。我该如何解决这个问题?

最佳答案

读取图像本身就是一项成本高昂的操作。

因此,您应该在开始游戏时读取图像一次,并将其保存在内存中以便稍后访问。

关于java - 我第一次尝试玩 Java 游戏时,在读取图像时以 7 fps 结束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13849320/

相关文章:

java - 使用pdfbox在java中将pdf文件转换为图像时缺少文本

java - 使用 Golang 中的类路径和库路径运行 Java 命令

java - 泛型 hell : Can I construct a TypeLiteral<Set<T>> using generics?

java - 无法初始化类 javax.imageio.ImageIO

java - 为什么 ImageIO.read() 太慢了?

python - 如何在OpenCV-Python中使用优化处理器性能?

c# - 使用 Matrox 命令捕获帧

java - 二维字符数组的格式化

java - SSL 证书链不完整

c++ - 最佳 fps 的 SFML 主循环