上一篇我们介绍了最简答的Java窗口生成, 本篇我们介绍简单版本的游戏主控流程, 每个步骤之后都给出了完整可运行的程序。
使用画布和线程
使用画布Canvas 和线程Thread, 唯一要注意的是frame.add(game);
,该行用于增加Canvas。
import java.awt.Canvas;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private static final int WIDTH = 160;
private static final int HEIGHT = 120;
private static final int SCALE = 4;
public Game() {
Dimension size = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);
this.setSize(size);
this.setPreferredSize(size);
this.setMaximumSize(size);
this.setMinimumSize(size);
}
public static void main(String[] args) {
Game game = new Game();
JFrame frame = new JFrame("Game step1");
frame.add(game);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
@Override
public void run() {
}
}
增加主控变量和方法
增加主控变量
private boolean running = false;
增加主控启动方法 startGame
public void startGame(){
if(this.running){
return;
}
this.running=true;
}
- 增加主控结束方法 stopGame
public void stopGame(){
this.running=false;
}
- 在
run
方法中增加主控循环, 在主控结束时, 游戏引用通过System.exit(0);
退出应用
while(running){
}
System.exit(0);
- 在
main
方法调用startGame
game.startGame();
此时完整的版本如下,
import java.awt.Canvas;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private static final int WIDTH = 160;
private static final int HEIGHT = 120;
private static final int SCALE = 4;
private boolean running = false;
public Game() {
Dimension size = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);
this.setSize(size);
this.setPreferredSize(size);
this.setMaximumSize(size);
this.setMinimumSize(size);
}
public static void main(String[] args) {
Game game = new Game();
JFrame frame = new JFrame("Game step1");
frame.add(game);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
game.startGame();
}
public void startGame(){
if(this.running){
return;
}
this.running=true;
}
public void stopGame(){
this.running=false;
}
@Override
public void run() {
while(running){
}
System.exit(0);
}
}
让主控线程运行起来
窗口还是那个窗口,有点枯燥吗? 接下来我们来一些看得见的干活。
增加主控线程变量
private Thread gameThread;
在startGame 中增加游戏线程的初始化和启动
this.gameThread = new Thread(this);
this.gameThread.start();
- 在stopGame 中增加游戏线程的正常结束逻辑, 其中异常的处理我们会在将来增加合适的处理
try{
this.gameThread.join();
}catch(Exception e){
e.printStackTrace();
}
- 在主控循环中增加信息的输出
while(running){
System.out.println("tick() method");
System.out.println("render() method");
}
完整的版本如下,
import java.awt.Canvas;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private static final int WIDTH = 160;
private static final int HEIGHT = 120;
private static final int SCALE = 4;
private boolean running = false;
private Thread gameThread;
public Game() {
Dimension size = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);
this.setSize(size);
this.setPreferredSize(size);
this.setMaximumSize(size);
this.setMinimumSize(size);
}
public static void main(String[] args) {
Game game = new Game();
JFrame frame = new JFrame("Game step1");
frame.add(game);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
game.startGame();
}
public void startGame(){
if(this.running){
return;
}
this.running=true;
this.gameThread = new Thread(this);
this.gameThread.start();
}
public void stopGame(){
this.running=false;
try{
this.gameThread.join();
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while(running){
System.out.println("tick() method");
System.out.println("render() method");
}
System.exit(0);
}
}
窗口还是那个窗口, 但我们在应用的控制台窗口看到了循环的信息输出。 这就是我们游戏逻辑和界面的主要入口点,也是我下篇要介绍的内容,渲染(render).