本节书摘来异步社区《Java 2D游戏编程入门》一书中的第1章,第1.5节,作者:【美】Timothy Wright(莱特),更多章节内容可以访问云栖社区“异步社区”公众号查看。
可以使用主动渲染,将渲染代码从事件分派线程移动到定制游戏线程。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