《Java 2D游戏编程入门》—— 1.5 创建一个主动渲染的窗口

    xiaoxiao2024-08-07  106

    本节书摘来异步社区《Java 2D游戏编程入门》一书中的第1章,第1.5节,作者:【美】Timothy Wright(莱特),更多章节内容可以访问云栖社区“异步社区”公众号查看。

    1.5 创建一个主动渲染的窗口

    可以使用主动渲染,将渲染代码从事件分派线程移动到定制游戏线程。Windows类和Canvas类是两个可用的类,它们允许创建一个BufferStrategy。通过添加画布,我们可以访问缓冲策略,并且强迫画布的大小与所要求的大小完全一致,就像Hello World应用程序中的JPanel示例一样。

    由于渲染循环为应用程序完成了所有的绘制,因此可以在JFrame上设置setIgnoreRepaint()标志。调用Canvas.createBufferStrategy(),传入想要缓冲的数目,然后调用Canvas.getBufferStrategy()创建主动渲染所需的缓冲。由于应用程序正在处理绘制,因此这里不需要响应重绘方法。Component.setIgnoreRepaint()方法负责忽略额外的绘制消息。

    如果在窗口布局之前创建了BufferStrategy的话,将会有一个奇怪的错误发生:

    Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Component must have a valid peer``` 调用pack()方法可以解决这个问题。如果抛出了前面的异常,要注意,在尝试创建BufferStrategy 之前,确保Component是可见的或者已经包装了。 游戏循环现在执行渲染,就像之前的小节中所讨论的那样。使用getDrawGraphics()、contentsLost()、show()和dispose()方法,渲染循环控制了应用程序绘图。一旦图形对象变得可用,并且之前的屏幕已经清除了,就可以渲染场景了。ActiveRenderingExample代码可以在javagames.render包中找到。

    package javagames.render;import java.awt.*;import java.awt.event.*;import java.awt.image.*;import javax.swing.*;import javagames.util.*;public class ActiveRenderingExample extends JFrame implements Runnable {  private FrameRate frameRate;   private BufferStrategy bs;  private volatile boolean running;  private Thread gameThread;  public ActiveRenderingExample() {    frameRate = new FrameRate();  }  protected void createAndShowGUI() {    Canvas canvas = new Canvas();    canvas.setSize( 320, 240 );    canvas.setBackground( Color.BLACK );    canvas.setIgnoreRepaint( true );    getContentPane().add( canvas );    setTitle( "Active Rendering" );    setIgnoreRepaint( true );    pack();    setVisible( true );    canvas.createBufferStrategy( 2 );    bs = canvas.getBufferStrategy();    gameThread = new Thread( this );    gameThread.start();  }  public void run() {    running = true;    frameRate.initialize();    while( running ) {      gameLoop();    }}public void gameLoop() {  do {    do {      Graphics g = null;      try {        g = bs.getDrawGraphics();        g.clearRect( 0, 0, getWidth(), getHeight() );        render( g );      } finally {        if( g != null ) {          g.dispose();        }      }    } while( bs.contentsRestored() );    bs.show();  } while( bs.contentsLost() );}private void render( Graphics g ) {  frameRate.calculate();  g.setColor( Color.GREEN );  g.drawString( frameRate.getFrameRate(), 30, 30 );}protected void onWindowClosing() {  try {    running = false;    gameThread.join();  } catch( InterruptedException e ) {    e.printStackTrace();  }  System.exit( 0 );}public static void main( String[] args ) {    final ActiveRenderingExample app = new ActiveRenderingExample();    app.addWindowListener( new WindowAdapter() {      public void windowClosing( WindowEvent e ) {        app.onWindowClosing();      }    });    SwingUtilities.invokeLater( new Runnable() {      public void run() {        app.createAndShowGUI();      }    });  }}`

    相关资源:Java 游戏编程开发教程中文高清完整版PDF
    最新回复(0)