Java JButton ActionListener双人游戏
我正在尝试用JavaSwing创建一个两人游戏 我有一个Java JButton ActionListener双人游戏,java,swing,jbutton,Java,Swing,Jbutton,我正在尝试用JavaSwing创建一个两人游戏 我有一个JButton 我的想法是在点击JButton时切换到另一个播放器。当玩家一点击JButton时,轮到玩家二了;当玩家点击两下时,轮到玩家一了 但是我的代码到目前为止不允许程序等待玩家2的点击。当玩家一键点击时,玩家二被认为已经点击 我如何让程序等待玩家2的点击来解决这个问题 boolean game = true; final boolean p1 = false; final boolean p2 = false; ... while
JButton
我的想法是在点击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;
}
});
}
}
你为什么不禁用未轮到的玩家的按钮,然后在轮到该玩家时启用,并禁用对手的按钮
button.setEnabled(false);
假设你有两个不同的按钮
祝你好运 为什么不禁用未轮到的玩家的
JButton
,然后在该玩家轮到时启用,并禁用对手的按钮
button.setEnabled(false);
假设你有两个不同的按钮
祝你好运 我建议改为使用。有关使用它们的信息,请参阅Java教程中的一节 我建议改为使用。有关使用它们的信息,请参阅Java教程中的一节
当玩家一键点击时,玩家二被认为已经点击
这是因为您使用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);
}
当玩家一键点击时,玩家二被认为已经点击
这是因为您使用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);
}
因为您正在编写Swing,所以不要执行
while(true)
循环,因为这样会阻塞事件线程EDT。相反,你应该使用摆动计时器,或者更可能在你的情况下,因为我猜你在玩基于回合的游戏(如果错误,请纠正我),使动作取决于事件。使用后者,而不是交换ActionListener,您只需通过单个字段更改程序状态,并根据此状态更改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();
}
});
}
}
因为您正在编写Swing,所以不要执行
while(true)
循环,因为这样会阻塞事件线程EDT。相反,你应该使用摆动计时器,或者更可能在你的情况下,因为我猜你在玩基于回合的游戏(如果错误,请纠正我),使动作取决于事件。使用后者,而不是交换ActionListener,您只需通过单个字段更改程序状态,并根据此状态更改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();
}
});
}
}
为什么不使用两个布尔变量,而只使用一个,比如:
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);
}
});
}
}
一个变量可以为您实现这一点,而不是使用两个不同的变量
希望这能有所帮助。
关于为什么不使用两个布尔变量,而只使用一个,例如:
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);
}
});
}
}
一个变量可以为您实现这一点,而不是使用两个不同的变量
希望这能有所帮助。
关于您确定要在(true)循环时永久使用原始海报的
?这些都行不通。与其交换侦听器,为什么不通过一个字段简单地更改程序状态,并根据此状态更改ActionListener的行为。您是对的,如果它在主线程中运行,那么一段时间(true)循环是不好的。可以在单独的线程中运行它。对于实现一个游戏,我认为有一段时间(真的)循环来保持游戏运行是正常的。但如果游戏取决于用户的输入并等待用户的输入,那么他当然不需要while(true)循环。您确定要使原始海报永久使用while(true)
循环吗?这些都行不通。与其交换侦听器,为什么不通过一个字段简单地更改程序状态,并根据此状态更改ActionListener的行为。您是对的,如果它在主线程中运行,那么一段时间(true)循环是不好的。可以在单独的线程中运行它。对于实现一个游戏,我认为有一段时间(真的)循环来保持游戏运行是正常的。但如果游戏取决于用户的输入并等待用户的输入,那么他当然不需要一段时间(真)循环。请注意,p1
和p2
是最终的,这排除了后续的更改。请注意,p1
和p2
是最终的,这排除了后续的更改。