기본적으로 게임 인 자바 프로그램이 있습니다. 이 클래스에는 '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() 메소드는 '색상' 유형의 2D 배열을 만든다. 이 배열은 PNG 이미지의 Color 객체를 저장합니다. 이 배열은 JPanel의 paint() 메서드에서 화면에 세계를 칠하는 데 사용됩니다.
levelChanger() 메서드는 특정 코드 작업이 true 일 때 게임의 레벨 (스테이지)을 변경하는 데 사용됩니다. 이 makeColorArray() 메서드를 호출하여 게임 레벨을 변경하는 동안 색상 배열을 다시 만드는 방법입니다.
문제는 스레드에서 실행되는 게임 루프가 있다는 것입니다. 이제 JPanel과 같은 스윙 구성 요소의 페인팅은 Java에 의해 다른 배경 스레드에서 수행됩니다. 게임 레벨이 변경되면 색상 배열 객체가 다시 만들어집니다. 이제까지 말했던 것처럼, 색상 배열 객체는 paint() 메서드에 의해 화면에 세계를 칠하는 데 사용됩니다. 게임 논리에 따라 색상 배열 객체가 다시 만들어지고 해당 멤버가 null로 설정되면 배경 배열 스레드 (아직 완료되지 않은 그림)에서 색상 배열 객체가 사용되는 경우가 있습니다. 이로 인해 널 포인터 예외 가끔 발생합니다. 분명히 경쟁 조건.
백그라운드 스윙 스레드가 페인팅을 완료 할 때까지 게임 배열이 색상 배열을 재설정하지 못하게하려면 어떻게해야합니까?
Java 동시성 라이브러리를 살펴 보는 것이 좋습니다. http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html – dckuehn
최상의 솔루션은 다중 스레드를 사용하지 않는 것입니다. 메인 루프를'javax.swing.Timer'로 바꾸거나'SwingUtilities.invokeAndWait'를 사용하십시오. –
@Banthar는 문제에 대한 간단한 해결책이지만 모든 경우에있어서 최선은 아닙니다. 업데이트 코드가 처리하는 데 시간이 오래 걸리면 EDT로 이동하면 실제 UI 이벤트가 반응적이고시기 적절하게 처리되지 않습니다. – NESPowerGlove