本节书摘来异步社区《java 2d游戏编程入门》一书中的第1章,第1.2节,作者:【美】timothy wright(莱特),更多章节内容可以访问云栖社区“异步社区”公众号查看。
图1.1所示的hello world应用程序是第一个游戏窗口的示例。helloworldapp位于javagames.render包中。除了清除和重新绘制背景,这个窗口中不再渲染其他内容。helloworldapp扩展了jframe类,这是java的swing库中一个顶级的窗口组件。这个应用程序包含一个framerate对象,该对象用来测量应用程序的帧速率。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLjNGZkZmMhBTZwQmM4IGMkVDMjhDNzYGZhZ2M5gjY3E2YlVzNhVDNk9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
由于swing库不是线程安全的,因此你应该总是在swing事件线程上创建并展示一个jframe。然而,该程序的main()方法并不是在事件线程上调用的,因此,必须要使用swingutilities类来启动游戏窗口。通过使用swingutilities类,我们在相同的线程上创建了gui组件。在使用swing组件进行渲染的时候,遵从java对于线程的规则是很重要的,因为忽略这些规则可能会导致不确定的行为,而这些行为是很难调试的。
我知道有的程序员会针对要在整个站点上部署的应用程序注释掉swingutilities代码,以测试是否真的需要swingutilities类来启动游戏窗口。每过几天,一些人就会报告应用程序在刚启动的时候崩溃。注意,我从来不会做这种事情,但这种做法似乎确实管用。
package javagames.render;
import java.awt.*;
import javax.swing.*;
import javagames.util.*;
public class helloworldapp extends jframe {
private framerate framerate;
public helloworldapp() {
framerate = new framerate();
}
protected void createandshowgui() {
gamepanel gamepanel = new gamepanel();
gamepanel.setbackground( color.black );
gamepanel.setpreferredsize( new dimension( 320, 240 ) );
getcontentpane().add( gamepanel );
setdefaultcloseoperation( exit_on_close );
settitle( "hello world!" );
pack();
framerate.initialize();
setvisible( true );
private class gamepanel extends jpanel {
public void paint( graphics g ) {
super.paint( g );
onpaint( g );
}
protected void onpaint( graphics g ) {
framerate.calculate();
g.setcolor( color.white );
g.drawstring( framerate.getframerate(), 30, 30 );
repaint();
public static void main( string[] args ) {
final helloworldapp app = new helloworldapp();
swingutilities.invokelater( new runnable() {
public void run() {
app.createandshowgui();
}
});
}<code>`</code>