天天看點

《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>