2012-01-01 75 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