2014-02-28 4 views
1

현재 2D 회전 기반 전략 게임을 진행 중입니다. 개발중인이 단계에서 나는 다양한 종류의 인공 지능을 테스트하고 있습니다.JPanel에서 그래픽을 빠르게 업데이트하는 방법

AI는 일반적으로 mouseClicked 함수에 의해 호출되는 gameLoop라는 함수에 x 및 y 변수를 전송하여 게임과 상호 작용합니다. 이를 통해 사용자는 직접 게임과 상호 작용하게하는 인간 사용자를 직접 에뮬레이트 할 수 있습니다. 다음은 내 코드의 개요입니다.

paintComponent() { 
    drawTiles(); 
    drawUnits(); 
    if(unitSelected && gameState == DISP_MOVE) 
     drawMoveSpots(); 
} 

gameLoop(int x, int y) { 
    // various logic based 
    // on the values of x and y 
    // logic may set unitSelected to true or false 
    // may also change gameState bteween normal and displayMoveSpots 
    repaint(); 
} 

내 문제는 AI가 다시 칠하기보다 빠르게 코드를 실행한다는 사실에서 기인합니다. 이런 일이 생기면 gameLoop 내부의 로직이 재 페인트보다 빠르게 변수를 변경하기 때문에 NullPointerException 및 ConcurrentModificationException과 같은 다양한 오류가 발생하기 시작합니다. AI가 gameLoop을 호출하는 빈도를 수동으로 지연 시키거나 2 명의 사람 만 재생하면 오류가 사라집니다.

Java 문서를 연구하고 읽었을 때, 재 페인트가 즉시 반환되고 Java가 실제 다시 그리기를 정당화 할 충분한 호출이 있다고 결정할 때까지 모든 그래픽 호출이 EventQueue에 저장된다는 것을 알고 있습니다. 내가 지금까지 찾을 수 있었던 유일한 해결책은 gameLoop에서 발생하는 로직 코드를 익명의 runnable 클래스에 넣고 SwingUtilities.invokeAndWait을 사용하여 코드를 호출하는 것입니다. 그러나 이것은 실제 사람과의 상호 작용을 유발하기 때문에 유효한 해결책은 아닙니다. 클릭하여 버그 아웃. GameLoop의 논리 섹션/다시 칠하기 (한 번에 하나씩 만 실행할 수 있음)에 상호 배타를 제공하기 위해 잠금을 사용하는 방법을 고려해 봤지만 Java 그래픽을 처리 할 때 좋은 방법인지 여부는 확실하지 않습니다.

이 시점에서 나는 내 문제를 완화하기 위해 내가 할 수있는 것에 대한 제안을합니다.

감사합니다.

+1

Canvas와 bufferstrategy의 작업처럼 들립니다. 이렇게하면 논리와 코드를 같은 스레드에서 사용할 수 있습니다. – Nikki

+0

정확히 모르겠지만'Graphics' 변수에 정보를 저장하려고 할 수 있습니다. 자동으로'repaint()'를 호출하고 일정한 간격으로 그래픽을 업데이트하는 동안 ur 코드가 지속적으로 변경되도록하십시오. – Astrobleme

+0

@ambigram_maker * ".. 그래픽 변수에 정보 저장을 시도하십시오."* 또는 Java 가상 머신이 전달한'Grphics' 객체 인 경우 ** 그렇게하지 마십시오. ** Graphics' 인스턴스는 한 페인트에서 다음 페인트로 일시적입니다. 우리는 결코 그것에 대한 참조를 유지하려고 시도해서는 안됩니다. * "자동으로 repaint()를 호출하고 일정한 간격으로 그래픽을 업데이트하는 동안 ur 코드를 지속적으로 변경하도록하십시오."* .. 뭐라구? –

답변

1

내 조언은 당신이 너무 자주 칠되지 않습니다함으로써 스윙 타이머

import javax.swing.Timer; 

    public static void main(String[] args) { 
          /*this is 1 sec/ 1000ms*/ 
    Timer aiTimer = new Timer(1000, new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      //move AI 
      //repaint 
     } 
    }); 
    aiTimer.start(); 

} 

를 사용한다는 것입니다. 희망이 도움이됩니다!

관련 문제