2014-09-02 56 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()方法的同行