我开始使用Java创建一个游戏。在我的 render(( 方法中,我有一个缓冲区策略,有三个缓冲区。但是,当我运行它时,我收到此错误。
Exception in thread "Thread-1" java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1016)
at sun.java2d.opengl.CGLGraphicsConfig.createCompatibleImage(CGLGraphicsConfig.java:200)
at java.awt.GraphicsConfiguration.createCompatibleImage(GraphicsConfiguration.java:178)
at sun.awt.image.SunVolatileImage.getBackupImage(SunVolatileImage.java:236)
at sun.awt.image.VolatileSurfaceManager.getBackupSurface(VolatileSurfaceManager.java:263)
at sun.awt.image.VolatileSurfaceManager.initialize(VolatileSurfaceManager.java:126)
at sun.awt.image.SunVolatileImage.<init>(SunVolatileImage.java:88)
at sun.awt.image.SunVolatileImage.<init>(SunVolatileImage.java:98)
at sun.awt.image.SunVolatileImage.<init>(SunVolatileImage.java:109)
at sun.java2d.opengl.CGLGraphicsConfig.createBackBufferImage(CGLGraphicsConfig.java:356)
at sun.lwawt.LWCanvasPeer.createBuffers(LWCanvasPeer.java:62)
at java.awt.Component$FlipBufferStrategy.createBuffers(Component.java:4016)
at java.awt.Component$FlipBufferStrategy.<init>(Component.java:3956)
at java.awt.Component$FlipSubRegionBufferStrategy.<init>(Component.java:4479)
at java.awt.Component.createBufferStrategy(Component.java:3833)
at java.awt.Canvas.createBufferStrategy(Canvas.java:194)
at java.awt.Component.createBufferStrategy(Component.java:3756)
at java.awt.Canvas.createBufferStrategy(Canvas.java:169)
at com.game.framework.Game.render(Game.java:79)
at com.game.framework.Game.run(Game.java:58)
at java.lang.Thread.run(Thread.java:744)
下面是使用 render(( 方法的完整类:
package com.game.framework;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 2956560507546666478L;
private Thread thread;
private boolean running = false;
public static final int WIDTH = 640, HEIGHT = WIDTH / 12 * 9;
public Game() {
new Window(WIDTH, HEIGHT, "UNKNOWN", this);
}
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();
}
}
public void run() {
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int frames = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
tick();
delta--;
}
if (running)
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println("FPS: " + frames);
frames = 0;
}
}
stop();
}
private void tick() { }
private void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
}
public static void main(String args[]) {
new Game();
}
}
这是我游戏中的另一个类:
package com.game.framework;
import java.awt.Canvas;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Window extends Canvas {
private static final long serialVersionUID = 70937078350109973L;
public Window (int width, int height, String title, Game game) {
JFrame frame = new JFrame(title);
frame.setPreferredSize(new Dimension(width, height));
frame.setMaximumSize(new Dimension(width, height));
frame.setMinimumSize(new Dimension(width, height));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
frame.add(game);
game.start();
}
}
我不确定问题是什么,但这非常令人沮丧,在问题解决之前我无法继续。谢谢大家的帮助!
经过一些研究,我发现了您的代码对我有用但不适合您的可能原因。我正在使用Direct 3D进行渲染,而您使用的是OpenGL。
D3D 类也使用此代码来创建BufferStrategy
:
public VolatileImage createBackBuffer(WComponentPeer peer) {
Component target = (Component)peer.getTarget();
// it is possible for the component to have size 0x0, adjust it to
// be at least 1x1 to avoid IAE
int w = Math.max(1, target.getWidth());
int h = Math.max(1, target.getHeight());
return new SunVolatileImage(target, w, h, Boolean.TRUE);
}
如您所见,它将宽度和高度设置为至少1
以避免IllegalArgumentException
。
该类的 OpenGL 版本不会:
@Override
public VolatileImage createBackBufferImage(Component target,
long backBuffer) {
return new SunVolatileImage(target,
target.getWidth(), target.getHeight(),
Boolean.TRUE);
}
因此,如果您仍然想使用 OpenGl,那么您需要绕过短时间,其中 Canvas 的大小尚未设置**(即宽度和高度0
(自行设置:
private void render() {
if (getWidth() == 0 || getHeight() == 0) {
return;
}
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
}
** 似乎有很短的时间,Game
画布没有"具有"正确的尺寸。它的大小在那里0x0
,但稍后会更新为634x449
(在游戏循环大约 3 次迭代后(。