本节书摘来异步社区《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>