Java中的createBufferStrategy问题

时间:2014-09-02 04:49:42

标签: java

我对java很新,但我怀疑我的问题是由与this post

相同的原因引起的

因为这让我觉得我在将组件添加到容器之前尝试渲染,所以我只需要帮助找出发生这种情况的方法。我评论了抛出IllegalStateException的行。

public void run() {
    init();
    long lastTime = System.nanoTime();
    final double amountOfTicks = 60D;
    double ns = 1000000000/amountOfTicks;
    double delta = 0;
    long now = System.nanoTime();

while(running)
{
    delta += (now - lastTime)/ns;
    lastTime = now;
    if(delta >= 1)
    {
        tick();
        delta--;
    }
    render(); //ISSUE HERE AND
}
stop();
}

public void tick() {
    player.tick();
}

public void render() {
    BufferStrategy bs = this.getBufferStrategy();
    if(bs == null)
    {
        createBufferStrategy(3); //ISSUE HERE, TOO
        return;
    }
    Graphics g = bs.getDrawGraphics();
    //RENDER HERE
    //g.fillRect(0, 0, 1200, 600);

player.render(g);
//END RENDER
g.dispose();
bs.show();
}
public static void main(String[] args)
{
    Game game = new Game();
    game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
    game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
    game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
    Gui go = new Gui();

game.start();
//Program seems to continue running after ESC
}

错误消息

Exception in thread "Thread-0" java.lang.IllegalStateException: Component must have a valid peer
    at java.awt.Component$FlipBufferStrategy.createBuffers(Unknown Source)
    at java.awt.Component$FlipBufferStrategy.<init>(Unknown Source)
    at java.awt.Component$FlipSubRegionBufferStrategy.<init>(Unknown Source)
    at java.awt.Component.createBufferStrategy(Unknown Source)
    at java.awt.Canvas.createBufferStrategy(Unknown Source)
    at java.awt.Component.createBufferStrategy(Unknown Source)
    at java.awt.Canvas.createBufferStrategy(Unknown Source)
    at msa.devillegame.main.Game.render(Game.java:81)
    at msa.devillegame.main.Game.run(Game.java:68)
    at java.lang.Thread.run(Unknown Source)

2 个答案:

答案 0 :(得分:1)

我设置了像这样的自定义渲染

public class FrameTest { //not a subclass from frame

    public static void main(String[] args) {
        //FIXME look at SwingUtilities invokeLater
        new FrameTest().createAndShow(); //because it's just a starter
    }

    private JFrame frame;
    private BufferStrategy bufferStrategy;
    private Rectangle screenBounds;
    private GraphicsDevice myScreen;
    private boolean isRunning = false;

    private void createAndShow() {
    try {
        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
        myScreen = env.getDefaultScreenDevice(); //maybe select a certain device
        GraphicsConfiguration gConf = myScreen.getDefaultConfiguration(); //maybe setup a different configuration
        screenBounds = gConf.getBounds();

        frame = new JFrame(gConf);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setUndecorated(true);
        frame.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                super.keyPressed(e);
                goExit();
            }

        });
        frame.setVisible(true);
        myScreen.setFullScreenWindow(frame);

        bufferStrategy = null;
        BufferCapabilities bcaps = gConf.getBufferCapabilities();
        int amountBuffer = 0;
        if (bcaps.isMultiBufferAvailable() ){               
            amountBuffer = 3;
        }else {
            amountBuffer = 2;
        }
        frame.createBufferStrategy(amountBuffer, bcaps);
        bufferStrategy = frame.getBufferStrategy();

        isRunning = true;
        startRendering(); //starts a render loop

        startUniverse(); //starts the physic calculations

        System.out.println("created a buffer with "+amountBuffer+" pages");

    } catch (HeadlessException e) {
    } catch (AWTException e) {
    }

}

    //this is an example caluclation
    private double xpos = 0;
    private double ypos = 0;
    private double xCenter = 0;
    private double yCenter = 0;
    private double radius = 100;
    private double dAngle = 0;
    private double angle = (2d * Math.PI / 360d);


    private void startUniverse() {
        Runnable r = new Runnable() {

            @Override
            public void run() {

                while(isRunning){
                    //this is the example calculation
                    xCenter = screenBounds.getCenterX();
                    yCenter = screenBounds.getCenterY();                    
                    dAngle = dAngle + angle;                    
                    xpos = xCenter + radius*(Math.sin(dAngle) );
                    ypos = yCenter + radius*(Math.cos(dAngle) );

                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t = new Thread(r); //create and...
        t.setDaemon(true);
        t.start(); //...start the thread
    }

    //this method starts the rendering thread
    //look at the full screen tutorial 
    private void startRendering() {
        Runnable r = new Runnable() {

            @Override
            public void run() {

                while(isRunning){ //an endless loop

                    Graphics g = null;
                    try {
                        g = bufferStrategy.getDrawGraphics();
                        render(g); //render the graphics
                    } finally {
                        if (g != null){
                            g.dispose(); //IMPORTANT - dispose the graphics - MemeoryLeak
                        }
                    }
                    bufferStrategy.show(); //bring it to the front

                    //i strongly recommend to let the render thread sleep a little 
                    //this reduces cpu power - without it it uses 
                    //one of my cpus for 100% (having 8 cpus this means 12.5%)
                    //but when it sleeps 10ms my cpu is down to 1% !!!
                    //try {
                    //  Thread.sleep(10);
                    //} catch (InterruptedException e) {
                    //}
                }
            }
        };

        Thread t = new Thread(r);
        t.setDaemon(true);
        t.start();
    }

    //the render method draws the calculated stuff
    protected void render(Graphics g) {

        //fist, fill with white
        g.setColor(Color.WHITE);
        int x = 0;
        int y = 0;
        int width = screenBounds.width;
        int height = screenBounds.width;
        g.fillRect(x, y, width, height);

        //xpos and ypos was calulated in the other thread       
        g.setColor(Color.BLACK);
        int x_a = (int)xpos;
        int y_a = (int)ypos;
        int x_b = (int)xCenter;
        int y_b = (int)yCenter;

        g.drawLine(x_a, y_a, x_b, y_b);
    }

    //simple method to quit
    protected void goExit() {
        isRunning = false;
        frame.setVisible(false);
        frame.dispose();
        myScreen.setFullScreenWindow(null);     
    }

}

将本教程作为帮助表...

答案 1 :(得分:0)

问题在于,当您尝试创建Game时,BufferStrategy对象不属于窗口。

Game构造函数中,您需要添加

frame.add(this)

将其添加到窗口并为createBufferStrategy()方法提供对等