天天看点

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

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

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

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

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

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

}<code>`</code>