3.游戏设计
3.1 新启线程,不断重绘界面
3.1.1新建线程类
GameFrame新建一个私有内部类run(参考尚学堂推箱子,这里类名也就小写了),继承Thread
private class run extends Thread {
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
其中,repaint()会调用GameFrame的paint()函数【有时会调用update,之后会遇到bug,目前先重写paint()】
/**
* 重绘方法
*/
@Override
public void paint(Graphics g) {
super.paint(g);
}
在GameFrame构造方法中中调用该线程,该线程启动后,保证1ms重绘一次界面
/**
* 启动重绘线程
*/
new run().start();
当然,目前启动程序后,界面和昨天看起来没有任何变化。
3.1.2 游戏地图介绍
下面简单介绍一下,游戏地图的构成:
下图,是原版游戏的第一关:
我们将其编码为如下表格:
-
GameClosure 即表格中外围围墙,该区域限制角色移动
-
GameText 表示规则,本关中如BABA IS YOU FLAG等文字块
-
GamePeople 表示的其余角色,如baba、flag、rock
3.1.3 编写背景GameBackground
在level包下新建GameBackground类,用于绘制游戏背景;后续我们会在该包下建立GameClosure、GamePeople、GameText类,分别用于绘制游戏边界、游戏可控制角色以及文字块。
/**
* 游戏背景类
*/
public class GameBackground {
private static final int DEFAULT_WIDTH = 19 * 24;
private static final int DEFAULT_HEIGHT = 19 * 24;
public void draw(Graphics graphics) {
graphics.setColor(Color.BLACK); // 画笔为黑色,当然也可以设置其他颜色,后续也可以自己找背景图
graphics.fillRect(0,0,DEFAULT_WIDTH, DEFAULT_HEIGHT); // 绘制实心矩形
}
}
在GameFrame中,实例化GameBackground,并在paint()中调其draw()方法:
/**
* 最终游戏界面
*/
public class GameFrame extends JFrame {
private static final int DEFAULT_WIDTH = 19 * 24;
private static final int DEFAULT_HEIGHT = 19 * 24;
/**
*
*/
private GameBackground gameBackground;
public GameFrame() {
// 设置窗口大小
this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// 窗口名称
this.setTitle("baba is you");
// 设置关闭窗口即结束程序
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置窗口可见
this.setVisible(true);
// 设置窗口居中显示
this.setLocationRelativeTo(null);
gameBackground = new GameBackground();
/**
* 启动重绘线程
*/
new run().start();
}
private class run extends Thread {
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 重绘方法
*/
@Override
public void paint(Graphics g) {
super.paint(g);
gameBackground.draw(g);
}
}
运行结果如下图: