2017-10-18 11 views
0

괜찮습니다. 그래서 저는 보드 게임을하고 있습니다. 첫 번째 'while 루프'는 게임이 종료되었는지 확인하고, 'while 루프'는 사용자 입력을 기다리는 것으로 가정합니다 (squareSelector 및 rooSelector가 내 마우스 목록이며 'k'및 's'는 청취자가 반환 함) 그러나 'while 루프'는 프로그램을 중단시키고 청취자가 작동하지 못하도록 차단합니다. 이것에 관해서는 스윙이 싱글 쓰레드이기 때문에 whileloop이 활성화되어있는 동안 내 리스너가 작동하지 않는다는 것을 알았습니다. 그러나 nullpointers를 피하기 위해 입력을 기다려야합니다. 해결 방법에 대한 아이디어가 있으십니까?while 루프를 사용하면 청취자가 작동하지 않습니다.

gameloop을 (다른 접근 방식으로, 또는 어떻게 입력 내 루프 대기를 만들기 위해)

while(currentPlayer.haveIWon() == false){ 
     //wait for input 
     while(!inputIsDone){ 
      System.out.println("waiting for move"); 
      System.out.println(squareSelector.isDone() + " " + rooSelector.isDone()) ; 
      checkInput() ; 
      if(squareSelector.isDone() && rooSelector.isDone()){ 
       inputIsDone = true ; 
      } 
     } 
     //update board 
     currentPlayer.performMove(k, s); 
     rooSelector.setDone(false); 
     squareSelector.setDone(false); 
     inputIsDone = false ; 
     //currentPlayer.setInput(false); 
     //repaint 
     Main.getState().getComponent().repaint(); 

    } 
    //display winnner thing 

checkInput 방법

public void checkInput(){ 
    if(rooSelector.getSelected() != null){ 
     k = rooSelector.getSelected() ; 
    } 
    if(squareSelector.getSelected() != null){ 
     s = squareSelector.getSelected() ; 
    } 
} 

당신이 무슨 일이 일어나고 있는지 이해하기 위해 더 많은 코드가 필요한 경우 에 나를 알려주고 더 추가 할 것입니다.

+0

[이벤트 발송 스레드] (https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html)를 차단해서는 안됩니다. - 문제는 루프가 EDT가 입력 이벤트를 처리하지 못하게하는 것입니다. 게임 루프 (필요한 경우)는 자체 스레드 (예 : [SwingWorker] (https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html))를 통해 실행해야합니다. – Thomas

+0

cheking input 현명한 루핑에는 기아에 의한 다른 스레드를 죽이는 것을 방지하는 방법이 포함되어 있습니다 : Thread.yield() 또는 Thread.sleep (1) – Doleron

+0

일반적으로 UI (즉, 애니메이션 없음) 또는 월드 (즉 "실시간"이 아닌) 게임 루프가 거의 필요하지 않습니다. NPE를 방지하기 위해 NPE를 방지해야한다고 말하면서 루프의 진정한 필요성보다는 설계 결함이나 코딩 오류를 나타냅니다. – Thomas

답변

0

스윙은 단일 스레드입니다. 디자인 때문에 GUI와 관련된 모든 것은 스윙 스레드 (이벤트 발송 스레드라고도 함)에서 수행되어야합니다. 그것은 기본적으로 한 가지를합니다 : 이벤트 대기열을보고 무언가가 있다면 처리하고, 그렇지 않으면 잠을 자게됩니다. 모든 마우스 이동, 키 누름, 다시 그리기 등은 실제로 이벤트 대기열의 이벤트입니다.

게임이 GUI 이벤트에만 반응하고 길게 작동하지 않는 경우에는 특별한 것을 사용할 필요가 없습니다. 당신은 while없이 당신의 논리를 쓸 수 있습니다. 그래서 그것은 막히지 않을 것이고, 사건들에만 반응 할 것입니다. 그러나이 가능성은 전적으로 구현하려는 것에 달려 있습니다.

오랫동안 스레드를 차단하는 조작이 있으면 별도의 스레드를 사용해야합니다. 이렇게하면 다른 스레드가 수행하는 작업이 GUI에 영향을 미치지 않지만 한 스레드에서 다른 스레드로 데이터를 보내거나 다른 스레드에서 무언가를 호출하는 데 매우 신중해야합니다.