【发布时间】:2015-02-18 20:34:56
【问题描述】:
我有一个基本上是游戏的 java 程序。它有一个名为 'World' 的类。 “World”类有一个方法'levelChanger()',还有另一个方法'makeColorArray()'。
public class World {
private BufferedImage map, map1, map2, map3;
private Color[][] colorArray;
public World(int scrWd, int scrHi) {
try {
map1 = ImageIO.read(new File("map1.png"));
map2 = ImageIO.read(new File("map2.png"));
map3 = ImageIO.read(new File("map3.png"));
} catch (IOException e) {
e.printStackTrace();
}
map = map1;
makeColorArray();
}
private void makeColorArray() {
colorArray = new Color[mapHi][mapWd]; // resetting the color-array
for(int i = 0; i < mapHi; i++) {
for(int j = 0; j < mapWd; j++) {
colorArray[i][j] = new Color(map.getRGB(j, i));
}
}
}
//color-array used by paint to paint the world
public void paint(Graphics2D g2d, float camX, float camY) {
for(int i = 0; i < mapHi; i++) {
for(int j = 0; j < mapWd; j++) {
if(colorArray[i][j].getRed() == 38 && colorArray[i][j].getGreen() == 127 && colorArray[i][j].getBlue() == 0) {
//draw Image 1
}
else if(colorArray[i][j].getRed() == 255 && colorArray[i][j].getGreen() == 0 && colorArray[i][j].getBlue() == 0) {
//draw Image 2
}
}
}
}
public void levelChanger(Player player, Enemies enemies) {
if(player.getRec().intersects(checkPoint[0])) {
map = map2;
//calls the color-array maker
makeColorArray();
}
else if(player.getRec().intersects(checkPoint[1])) {
map = map3;
makeColorArray();
}
}
public void update(Player player, Enemies enemies) {
levelChanger(player, enemies);
}
}
makeColorArray() 方法创建一个“颜色”类型的二维数组。此数组存储来自 PNG 图像的颜色对象。 JPanel 的paint() 方法使用此数组在屏幕上绘制世界。
levelChanger() 方法用于在某些代码为真时更改游戏的关卡(阶段)。它是调用makeColorArray()方法在改变游戏关卡时重新制作颜色数组的方法。
问题是我有一个在线程上运行的游戏循环。现在,像JPanel这样的swing组件的绘制是由java在不同的后台线程上完成的。当游戏关卡改变时,颜色数组对象被重新制作。现在,就像我之前所说的,paint() 方法使用颜色数组对象在屏幕上绘制世界。有时,当根据游戏逻辑重新制作颜色数组对象并将其成员设置为空时,背景线程(未完成绘制)仍在使用颜色数组对象。这仅在某些时候会导致 空指针异常。显然是竞争条件。
我想知道如何阻止我的游戏线程重置颜色数组,直到背景摆动线程完成绘画。
【问题讨论】:
-
最好的解决方案是不使用多线程。将主循环替换为
javax.swing.Timer或使用SwingUtilities.invokeAndWait。 -
@Banthar 这是解决问题的简单方法,但并不是所有情况下的最佳解决方案。如果更新代码需要很长时间来处理,那么将其移动到 EDT 会阻止以响应及时的方式处理真实的 UI 事件。
标签: java multithreading swing thread-safety