2014-09-02 78 views
0

我在java的相当新的,但我怀疑我的问题是由同样的原因造成的this post麻烦与createBufferStrategy在Java中

因为这让我觉得我试图呈现在我的组件添加到容器,我只需要帮助搞清楚发生了什么。我评论了抛出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) 
+0

组件必须有一个有效的对弹出时你不显示你的组件。这意味着:您的组件不会出现在前面!创建并显示你的框架和组件FIRST和你的缓冲区/ bufferstragey SECOND - 然后渲染! – 2014-09-02 05:24:01

+0

当我遵循它们发生的顺序时,在main调用Gui()时,框架首先发生,但在此之后,我无法确定何时调用bufferStrategy。 – user3750325 2014-09-02 05:39:31

+0

你不能通过简单的说出来创建Bufferstrategy!你必须询问系统是否支持缓冲策略......然后,创建一个支持的缓冲策略...... – 2014-09-02 06:07:50

回答

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);  
    } 

} 

阅读本教程为帮助表...

+0

告诉我,如果你可以使用这种方法创建一个缓冲区......那么我们可以进一步研究你的问题与渲染.. – 2014-09-02 06:54:00

+0

好的,我复制并粘贴了该块,并将其放入我的渲染方法中,并注释了曾经存在的内容。它似乎工作正常。没有错误,并且我得到了持续不断的控制台消息流,说“明天创建了一个2页的缓冲区” – user3750325 2014-09-02 15:12:28

+0

,我可以复制/粘贴整个方法来向您展示如何使用缓冲区,对不起,我没有这里的资源,可以帮助你进一步明天 – 2014-09-02 19:41:20

0

的问题是你Game当您尝试创建BufferStrategy时,对象不是窗口的一部分。

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

frame.add(this) 

将它添加到窗口,给createBufferStrategy()方法的同行