JAVA: 为什么图像加载速度比应用程序慢,Window Frame?
JAVA: Why images is loaded slower than the app, Window Frame?
我正在使用图像为 Java 应用程序绘制背景,一个没有重复的大应用程序 属性。为此,我使用 bufferedImage 读取资源、图像,并将其绘制在 Canvas 中。好吧,它几乎可以正常工作。除了一件事,即使图像落后,应用程序仍然可以打开。
我的意思是,我希望看到应用程序和图像同时加载。但似乎图像只是在应用程序启动后才加载,足够长的时间可以看到 window 框架背景(灰色,因为我使用的是 Windows 10)。
所以我在 Canvas class 初始化后通过 setVisible(true);
尝试了我的解决方案。结果还是一样
又一个异常,不知道是不是跟图片有关。但是在我关闭应用程序后,控制台抛出了一个名为 'Closed' 的异常。就像在我关闭我的应用程序后,还有一部分我的编码 运行 并尝试读取图像。
这是我的代码:
App.class(此处主要class)
import engine.MouseAction;
import graphic.Game;
import graphic.Window;
public class App {
MouseAction mouse;
Game game;
Window window;
App() {
init();
setup();
window.launch();//It's just window.setVisible(true);
}
private void init() {
mouse = new MouseAction();
game = new Game();
window = new Window(game, mouse);
}
private void setup() {
mouse.setWindow(window);
game.start();
}
public static void main(String[] args) {
new App();
}
}
Game.class
package graphic;
import java.awt.Canvas;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import engine.Config;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = -545327428912119369L;
private Thread thread;
private boolean running = false;
public Game() {}
public synchronized void start() {
thread = new Thread(this);
thread.start();
running = true;
}
public synchronized void stop() {
try {
thread.join();
running = false;
} catch(Exception e) {
e.printStackTrace();
}
}
private void update() {
}
private void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics2D g = (Graphics2D) bs.getDrawGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON);
try {
BufferedImage bg = ImageIO.read(getClass().getResource("/assets/img/bg.jpg"));
g.drawImage(bg, 0, 0, Config.SOL_16x10_small.width, Config.SOL_16x10_small.height, this);
bg.flush();
} catch (IOException e) {
e.printStackTrace();
}
g.dispose();
bs.show();
}
public void run() {
long lastTime = System.nanoTime();
final double amountOfTick = 60.0;
double ns = 1000000000 / amountOfTick; //It's nano second
double delta = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
update();
delta--;
}
render();
}
stop();
}
}
那是 2 classes 我认为这与我的问题有关。这段代码确实加载了图片,但加载速度很慢。
问题出在你的游戏循环中。您尝试在游戏循环的每次迭代中将图像文件加载到内存中,就在您获得图形上下文以实际绘制它之前。
尝试预先将图像加载到内存中,然后在每次迭代时调用Graphics g的绘图方法进行渲染。
您可以在开始游戏循环之前在任何地方加载图像。
您也可以预先创建 bufferstrategy,然后在您的 render() 方法中简单地获取图形上下文,就像您已经这样做的那样。
最终保存 if(bs == null),但这不会产生任何明显的差异。
我正在使用图像为 Java 应用程序绘制背景,一个没有重复的大应用程序 属性。为此,我使用 bufferedImage 读取资源、图像,并将其绘制在 Canvas 中。好吧,它几乎可以正常工作。除了一件事,即使图像落后,应用程序仍然可以打开。
我的意思是,我希望看到应用程序和图像同时加载。但似乎图像只是在应用程序启动后才加载,足够长的时间可以看到 window 框架背景(灰色,因为我使用的是 Windows 10)。
所以我在 Canvas class 初始化后通过 setVisible(true);
尝试了我的解决方案。结果还是一样
又一个异常,不知道是不是跟图片有关。但是在我关闭应用程序后,控制台抛出了一个名为 'Closed' 的异常。就像在我关闭我的应用程序后,还有一部分我的编码 运行 并尝试读取图像。
这是我的代码:
App.class(此处主要class)
import engine.MouseAction;
import graphic.Game;
import graphic.Window;
public class App {
MouseAction mouse;
Game game;
Window window;
App() {
init();
setup();
window.launch();//It's just window.setVisible(true);
}
private void init() {
mouse = new MouseAction();
game = new Game();
window = new Window(game, mouse);
}
private void setup() {
mouse.setWindow(window);
game.start();
}
public static void main(String[] args) {
new App();
}
}
Game.class
package graphic;
import java.awt.Canvas;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import engine.Config;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = -545327428912119369L;
private Thread thread;
private boolean running = false;
public Game() {}
public synchronized void start() {
thread = new Thread(this);
thread.start();
running = true;
}
public synchronized void stop() {
try {
thread.join();
running = false;
} catch(Exception e) {
e.printStackTrace();
}
}
private void update() {
}
private void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics2D g = (Graphics2D) bs.getDrawGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON);
try {
BufferedImage bg = ImageIO.read(getClass().getResource("/assets/img/bg.jpg"));
g.drawImage(bg, 0, 0, Config.SOL_16x10_small.width, Config.SOL_16x10_small.height, this);
bg.flush();
} catch (IOException e) {
e.printStackTrace();
}
g.dispose();
bs.show();
}
public void run() {
long lastTime = System.nanoTime();
final double amountOfTick = 60.0;
double ns = 1000000000 / amountOfTick; //It's nano second
double delta = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
update();
delta--;
}
render();
}
stop();
}
}
那是 2 classes 我认为这与我的问题有关。这段代码确实加载了图片,但加载速度很慢。
问题出在你的游戏循环中。您尝试在游戏循环的每次迭代中将图像文件加载到内存中,就在您获得图形上下文以实际绘制它之前。
尝试预先将图像加载到内存中,然后在每次迭代时调用Graphics g的绘图方法进行渲染。
您可以在开始游戏循环之前在任何地方加载图像。
您也可以预先创建 bufferstrategy,然后在您的 render() 方法中简单地获取图形上下文,就像您已经这样做的那样。
最终保存 if(bs == null),但这不会产生任何明显的差异。