2012-01-01 167 views
1

我想用Java Swing創建一個雙人遊戲。我有一個JButtonJButton ActionListener雙人遊戲

我的想法是在點擊JButton時切換到另一位玩家。當玩家點擊JButton時,它變成了玩家兩輪;當玩家兩次點擊時,它變成了玩家輪到。

但是我的代碼到目前爲止不允許程序等待玩家2的點擊。當玩家一擊時,玩家二被認爲已經點擊了。

如何通過讓程序等待玩家2的點擊來解決這個問題?

boolean game = true; 
final boolean p1 = false; 
final boolean p2 = false; 
... 
while (game) { 
    p1 = true; 
    while (p1) { 
     enterMoveButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       doSomething(); 
       p1 = false; 
       p2 = true; 
      } 
     }); 
    } 
    while (p2) { 
     enterMoveButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       doSomething(); 
       p2 = false; 
       p1 = true; 
      } 
     }); 
    } 
} 
+0

請注意'p1'和'p2'是最終的,這將排除後續更改。 – trashgod 2012-01-01 15:39:35

回答

2

你爲什麼不禁止誰沒有輪到自己當球員得到輪到他和禁用對手的按鈕後使玩家的JButton

button.setEnabled(false); 

假設你有兩個不同的按鈕

祝你好運!

1

當玩家點擊,玩家二是認爲也已經點擊

這是因爲你使用addActionListener方法。當你調用這個方法時,它不會取代以前的方法。它只是添加另一個監聽器到按鈕點擊。當它被點擊時,它會執行添加到按鈕的所有偵聽器。

您可以通過定義兩個的ActionListeners解決這個問題:

ActionListener a1 = new ActionListener(){ 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     doSomething(); 
     p1 = false; 
     p2 = true; 

    } 
}; 

ActionListener a2 = new ActionListener(){ 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     doSomething(); 
     p2 = false; 
     p1 = true; 
    } 
}; 


while(game){ 
    p1 = true; 
    while(p1){ 
     enterMoveButton.removeActionListener(a2); 
     enterMoveButton.addActionListener(a1); 
    } 
    while(p2){ 
     enterMoveButton.removeActionListener(a1); 
     enterMoveButton.addActionListener(a2); 
    } 
+0

你確定要延續原來的海報使用'while(true)'循環嗎?這些行不通。而不是交換監聽器,爲什麼不簡單地通過一個字段來改變程序狀態,並且根據這個狀態來改變ActionListener的行爲。 – 2012-01-01 04:00:48

+0

如果它在主線程中運行,那麼你說得對(真的)循環很糟糕。可以讓它在單獨的線程中運行。爲了實現一個遊戲,我認爲有一段時間(真)循環來保持遊戲運行是正常的。 但是,如果是遊戲是取決於和等待用戶的輸入,那麼他當然不需要一段時間(真)循環。 – evanwong 2012-01-01 05:37:00

2

既然你編碼鞦韆,不做while (true)循環,你會阻止事件線程,該EDT。相反,你應該使用Swing Timer,或者更有可能使用Swing Timer,因爲我猜你正在玩基於回合的遊戲(如果錯誤請糾正我),根據事件做出動作。使用後者,而不是交換ActionListeners,只需通過單個字段更改程序狀態,並根據此狀態更改ActionListener的行爲。

有關後者的示例,請參閱下面的代碼。該計劃的狀態保持在playerIndex int變量:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class ToggleGame extends JPanel { 
    public static final String[] PLAYERS = {"Player 1", "Player 2"}; 

    // turnIndex is either 0 or 1, depending on whose turn it is. 
    private int turnIndex = 0; 
    private JButton turnButton = new JButton(PLAYERS[turnIndex]); 

    public ToggleGame() { 
     add(new JLabel("Turn:")); 
     add(turnButton); 
     setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); 

     turnButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent evt) { 
      turnBtnAction(evt); 
     } 
     }); 
    } 

    private void turnBtnAction(ActionEvent evt) { 
     turnIndex++; // next player 
     turnIndex %= PLAYERS.length; // mod 2 
     turnButton.setText(PLAYERS[turnIndex]); 

     doSomething(turnIndex); 
    } 

    private void doSomething(int index) { 
     String msg = "It is now " + PLAYERS[index] + "'s turn!"; 
     String title = "Whose Turn Is It?"; 
     JOptionPane.showMessageDialog(this, msg , title, JOptionPane.INFORMATION_MESSAGE); 
    } 

    private static void createAndShowGui() { 
     ToggleGame mainPanel = new ToggleGame(); 

     JFrame frame = new JFrame("ToggleGame"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
1

爲什麼不而不是使用兩個布爾變量,你只能使用一個喜歡說:

boolean myturn = true; // at the start for Player 1 it's true. 

@Override 
public void actionPerformed(ActionEvent arg0) 
{ 
    if (myturn == true) 
    { 
     doSomething(); // Do whatever Player1 is suppose to do at his turn. 
         // Now since myturn will be false after this, so Player1 
         // won't be able to move till Player 2 takes his turn. 
     myturn = false; 
    } 
    else if (myturn == false) 
    { 
     doThisInstead(); // Do whatever Player2 is suppose to do at his turn. 
         // Here again myturn will will change to true, now Player2 
         // won't be able to move till Player1 makes his next move. 
     myturn = true; 
    } 
} 

這裏是代碼,以解釋什麼,我只是說:

import javax.swing.*; 
import java.awt.event.*; 

public class ButtonTest extends JFrame implements ActionListener 
{ 
    private JPanel panel; 
    private JButton button; 
    private JLabel label; 
    private String player1 = "I am player one."; 
    private String player2 = "I am player two."; 
    private boolean myturn = true; 

    public ButtonTest() 
    { 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    panel = new JPanel(); 
    button = new JButton(player1); 
    label = new JLabel(player1); 
    button.addActionListener(this); 

    panel.add(label); 
    panel.add(button); 

    setContentPane(panel); 
    pack(); 
    } 

    public void actionPerformed(ActionEvent ae) 
    { 
    if (myturn == true) 
    { 
     button.setText(player2); 
     label.setText(player2); 
     myturn = false; 
    } 
    else if (myturn == false) 
    { 
     button.setText(player1); 
     label.setText(player1); 
     myturn = true; 
    } 
    } 

    public static void main(String... args) 
    { 
    SwingUtilities.invokeLater(new Runnable() 
    { 
     public void run() 
     { 
     new ButtonTest().setVisible(true); 
     } 
    }); 
    } 
} 

單個變量可以爲你做,而不是使用兩個不同的。

希望這可能有助於某種方式。 Regards