2011-09-28 113 views
7

我正在製作遊戲內存,當你選擇兩張牌時,如果它們匹配,則保留它們,否則將它們還原。如果你還記得你已經選擇的牌,你可以更好地猜測下兩張牌。我有問題repaint()方法不立即重新繪製。如何調用Java GUI的即時更新? (與Thread.sleep()衝突)

當我翻轉第二張牌時,無論結果如何,我希望在丟棄或翻轉它們之前將兩張牌正面向上翻轉。我通過撥打sleep()來完成此操作。

當然,如果我將它們翻過來的卡右側向上等待一秒鐘,然後再根據它們的值repaint(),有用的小Java將只重繪一次(我錯過C!)。

基本上我想強制在我sleep()之前調用更新。我已經閱讀了一些其他線程,基本上說最好的方法是創建兩個線程來保持你的邏輯和圖形分離,然後你可以使用你的邏輯並保持你的GUI更新,但是我在第一年的第一學期CS當然我也希望保持在課程的水平上(儘管我花了相當多的時間來研究夏季Web開發和C編碼)。

因爲我知道StackOverflow上的幫助人員很喜歡閱讀代碼,下面是我在下面提到的程序的一部分。類HitArea是卡對象,而cards[]數組包含的數量爲HitArea(我沒有得到重命名HitArea類)。 activeCard1activeCard2HitArea我用來跟蹤用戶的兩個選擇的實例,空白構造函數是一個保留的「不可見」HitArea,儘管我稍後將它更改爲null。最後,cards.flip()反轉一個toggle布爾值,它確定卡是否正面朝上。

public void respond(HitArea choice) 
{ 
    if(choice.inGame) 
    { 
     if(activeCard1.value == 0 && activeCard1.value == 0) 
      activeCard1 = choice; 
     else if((!(activeCard1.value == 0) && activeCard2.value == 0) && (activeCard1.id != choice.id)) 
     { 
      activeCard2 = choice; 
      check(); 
     } 

    } 
} 
public void check() 
{ 
    update(); 
    pause(250); 
    if(activeCard2.value == activeCard1.value) 
    { 
     score += 2; 
     activeCard1.inGame = false; 
     activeCard2.inGame = false; 
    } 
    activeCard1.flip(); 
    activeCard2.flip(); 
    activeCard1 = new HitArea(); 
    activeCard2 = new HitArea(); 
} 
public void pause(int milliseconds) 
{ 
    try{ 
     Thread.currentThread().sleep(milliseconds); 
    } 
    catch(InterruptedException e){ 
     System.out.println("Exception: " + e); 
    } 
} 

public void mousePressed(MouseEvent e) 
{ 
    int x = e.getX(); 
    int y = e.getY(); 

    for (int i = 0; i < cardNum; i++) 
     if(cards[i].boundsCheck(x, y)) 
     { 
      repaint(); 
      cards[i].flip(); 
      respond(cards[i]); 
     } 
} 

我毫不懷疑在我的代碼中有一些問題,所以隨時指出它們。我認爲我的基本結構是可以的,我寧願不爲這個項目創建多個線程(記住,它是基本的!)。

回答

14

不要在主Swing線程EDT上調用Thread.sleep(...)。 Ever。而是使用擺動計時器。

考慮使用JLabels來顯示圖像,然後通過簡單地更換ImageIcons來「翻轉」卡片。當第二張卡被翻轉時,如果沒有匹配,則啓動一個不重複的Swing Timer,並延遲xxxx ms,並在Timer的ActionListener的actionCommand方法中將它恢復爲默認的ImageIcon。

的javax.swing.Timer中的教程可以在這裏找到:How to use Swing Timers

編輯:
關於你提到的有關使用g.drawString評論:它現在更容易,因爲所有你需要做的就是換了你JLabel的文字。但後來,如果您決定升級程序以顯示圖像,那麼您已經完成了設置。

編輯2:
關於你結交新的ActionListener類問題:我會用一個匿名內部類此。例如:

int delayTime = 2 * 1000; 
    javax.swing.Timer myTimer = new Timer(delayTime, new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // TODO: put in the code you want called in xxx mSecs. 
    } 
    }); 
    myTimer.setRepeats(false); 
    myTimer.start(); 
+3

我會大膽並傾斜「永遠」。 :) – fireshadow52

+0

我只是顯示一些g.drawString(...)文本,沒有圖像。這同樣適用嗎? –

+0

謝謝,完成了。 :) –