JButton ActionListener для двух игроков - PullRequest
1 голос
/ 01 января 2012

Я пытаюсь создать игру для двух игроков с помощью Java Swing.

У меня есть один JButton.

Моя идея состоит в том, чтобы переключиться на другого игрока при нажатии JButton. Когда игрок 1 нажимает JButton, он становится ходом игрока 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;
            }
        });
    }
}

Ответы [ 5 ]

3 голосов
/ 01 января 2012

Я бы предложил вместо этого использовать JToggleButton . Для получения информации об их использовании см. Как использовать кнопки, флажки и радиокнопки , раздел в . Учебник по Java.

2 голосов
/ 01 января 2012

Поскольку вы кодируете Swing, не выполняйте циклы while (true), поскольку вы заблокируете поток событий, EDT.Вместо этого вам следует либо использовать 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();
         }
      });
   }
}
2 голосов
/ 01 января 2012

Почему бы вам не отключить JButton игрока, у которого нет своего хода, а затем включить его, когда игрок получит свой ход, и отключить кнопку противника.

button.setEnabled(false);

Если у вас есть две разные кнопки

Удачи!

1 голос
/ 01 января 2012

Почему бы не использовать две логические переменные, вы используете только одну, например, скажем:

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);
      }
    });
  }
}

Одна переменная можетсделайте трюк за вас, вместо того, чтобы использовать два разных.

Надеюсь, что это может как-то помочь.Привет

1 голос
/ 01 января 2012

Когда игрок щелкает одним игроком, считается, что игрок два уже нажал

Это потому, что вы используете addActionListener.Когда вы вызываете этот метод, он не заменяет предыдущий.Просто добавьте еще одного слушателя к нажатию кнопки.При нажатии на нее запускаются все прослушиватели, добавленные к кнопке.

Вы можете решить эту проблему, определив два actionListener:

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);
    }
...