2013-01-20 109 views
0

我正在创建游戏画布,但出于某种原因,我无法使其正常工作。我得到一个InvalidStateException,我没有得到什么导致它的线索。任何人都可以点亮一下吗?为什么我的画布不工作?

我的主入口点......

public class GameTemplate { 

    public static void main(String[] args) { 
     new GameFrame(); 
    } 

} 

我JFrame的子类...

import java.awt.Dimension; 

import javax.swing.JFrame; 

public class GameFrame extends JFrame { 


    public static final short WIDTH = 1024; 
    public static final short HEIGHT = WIDTH/16 * 9; 
    public static final Dimension size = new Dimension(WIDTH, HEIGHT); 

    public GameFrame() { 
     super("Game Frame"); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setSize(size); 
     this.setLocationRelativeTo(null); 
     this.setResizable(false); 
     GameCanvas canvas = new GameCanvas(size); 
     this.add(canvas); 
     canvas.start(); 
     this.setVisible(true); 
    } 

} 

我的画布子......

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.image.BufferStrategy; 

public class GameCanvas extends Canvas implements Runnable { 

    private boolean isRunning = false; 
    private Thread thread = null; 

    private BufferStrategy bs = null; 
    private Graphics g; 
    private Graphics2D g2d; 

    public GameCanvas(Dimension size) { 
     this.setSize(size); 
     this.setVisible(true); 
    } 

    public synchronized void start() { 
     isRunning = true; 
     thread = new Thread(this); 
     thread.start(); 
    } 

    public synchronized void stop() { 
     isRunning = false; 
     try { 
      thread.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void run() { 
     while (isRunning) { 
      update(); 
      draw(); 
      render(); 
      try { 
       Thread.sleep(10); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    private void update() { 

    } 

    private void render() { 
     bs = this.getBufferStrategy(); 
     if (bs == null) { 
      this.createBufferStrategy(3); 
      return; 
     } 
     bs.show(); 
    } 

    private void draw() { 
     if (bs != null) { 
      g = bs.getDrawGraphics(); 
      g2d = (Graphics2D) g; 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
      g.setColor(Color.BLACK); 
      g.drawRect(0, 0, WIDTH, HEIGHT); 
     } 
    } 

} 

错误...

Exception in thread "Thread-1" 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 GameCanvas.render(GameCanvas.java:63) 
at GameCanvas.run(GameCanvas.java:47) 
at java.lang.Thread.run(Unknown Source) 
+4

1)不要将Swing(例如'JFrame')和AWT(例如'Canvas')组件混合在一起而没有充分的原因。在这种情况下,您可能会渲染图像并将其显示在标签中,或者扩展'JPanel'并覆盖'paintComponent(Graphics)'2)为了更好地帮助您,请发布[SSCCE](http://sscce.org /)。 3)'Thread.sleep(10);'不要阻塞EDT(事件调度线程) - 当这种情况发生时GUI将“冻结”。而不是调用'Thread.sleep(n)'实现一个Swing'Timer'来重复任务。有关更多详细信息,请参见[Swing中的并发](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。 –

+0

谢谢,我会研究摆动的并发性。如果不应该将Canvas添加到JFrame中,还有什么可以添加Canvas? –

+1

*“还有什么可以添加画布到..”*忘记“画布”!使用'JPanel' **来代替**。 –

回答

0

在框架初始化,你的情况:

public GameCanvas(Dimension size) {...} 

您需要调用方法 “frame.addNotify()”,例如:

public GameCanvas(Dimension size) { 
    this.setSize(size); 
    this.setVisible(true); 
    this.addNotify(); 
} 

再后来了你的代码,你想包括代码:

@Override 
public void addNotify() { 
    super.addNotify(); 
} 

这只是通知帧,你希望这个类使用缓冲区。你在做什么是试图让帧使用缓冲区来创建一个图形类型缓冲策略,当帧不知道哪个组件的缓冲区用于请求的任务。

1
java.lang.IllegalStateException: Component must have a valid peer 

这可能是因为您打电话时createBufferStrategy()组件必须已隐藏。

UPDATE:

至于建议的@Andrew,你是在默认BufferStrategy.As我们可以看到混合light and heavy weight components.Rely,Canvas是不显示的,直到你把它添加到Frame

+0

这没有意义,但因为我在构造函数中将Canvas可见性设置为true,并且在异常之后的游戏循环 –

+0

@JohnPringle期间创建了缓冲策略,所以应用程序停止或继续? –

+0

@JohnPringle看到我的更新。 –