为什么在使用createBufferStrategy(3)时会抛出illegalArgumentException?

时间:2014-12-22 02:17:04

标签: java swing illegalargumentexception

我开始使用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();
    }
}

我不确定问题是什么,但是非常令人沮丧,在问题解决之前我无法继续。谢谢大家的帮助!

1 个答案:

答案 0 :(得分:1)

经过一些研究,我发现了你的代码可能适合我的原因,但不适合你。我使用Direct 3D进行渲染,并且您正在使用OpenGL。

D3D课程也使用this code创建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 version of that class没有:

@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画布没有&#34;#34;他的正确尺寸。它的大小为0x0,但稍后会更新为634x449(在游戏循环的大约3次迭代后)。