我试图为我的作业构建一个简单的滚动骰子游戏。将有2名球员。在我的代码中,我尝试使用方法getSource()
,以便在启用播放器roll
JButton时,其他播放器的按钮将被禁用,但是当我运行游戏时,两个播放器都会被禁用按钮仍然启用。这是我的代码:
Die.java
import java.util.*;
public class Die
{
private final int MAX = 6;
private int die1;
Random rand = new Random();
//Constructor
public Die()
{
die1 = 1;
}// end Constructor
public int Roll()
{
die1 = rand.nextInt(MAX)+1;
return die1;
}
}
DisplaySixNumbersPanel.java
import java.awt.*;
import javax.swing.*;
public class DisplaySixNumbersPanel
{
public static void main(String[ ] args)
{
JFrame w1 = new JFrame("Six Numbers Game");
w1.setLayout(new GridLayout(1,2));
SixNumbersPanel2 player1 =new SixNumbersPanel2();
SixNumbersPanel2 player2 =new SixNumbersPanel2();
w1.add(player1);
w1.add(player2);
w1.setSize(540, 350);
w1.setVisible(true);
w1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} //end main
} //end class
SixNumbersPanel2.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class SixNumbersPanel2 extends JPanel implements ActionListener
{
private JTextField text1;
private boolean flag = false;
private boolean checkflag[] = {false,false,false,false,false,false,false};
private JLabel label;
private JLabel label1;
public JButton roll;
private JButton restartButton;
private JTextArea display;
private JTextField[] fields = new JTextField[7];
private Die dice = new Die();
private int key;
private int count;
private int count1;
private Player player1 = new Player();
private Player player2 = new Player();
private int check;
private int[] list = new int [7];
//private SixNumbersPanel2 player2panel;
public SixNumbersPanel2()
{
label= new JLabel ("A number between 1 to 6 wil appear");
label1 = new JLabel("once in each of the following textfields");
roll = new JButton("Roll dice");
restartButton = new JButton("Restart Game");
text1 = new JTextField(3);
display = new JTextArea(10,15);
add(label);
add(label1);
for(int i=1;i<7;i++)
{
fields[i] = new JTextField(3);
add(fields[i]);
}
add(roll);
add(text1);
add(display);
display.setEditable(false);
restartButton.setVisible(false);
add(restartButton);
restartButton.addActionListener(this);
roll.addActionListener(this);
}
public void restart()
{
display.setText("");
text1.setText("");
for(int i=1; i<7; i++)
{
fields[i].setText("");
}
count=0;
count1=0;
Arrays.fill(checkflag,false);
Arrays.fill(list,0);
flag = false;
restartButton.setVisible(false);
rollenable();
}
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == roll)
{
player2.rolldisable();
}
key=dice.Roll();
count++;
String toScreen= "Number of rolls: "+count;
display.setText(toScreen);
text1.setText(""+key);
check = player1.Check(list,key);
if(check < 0)
{
count1++;
for(int i=1;i<7;i++)
{
if(key == i)
{
list[i] = key;
checkflag[i]=true;
fields[i].setText(""+key);
if(checkflag[i] == true)
{
flag = true;
for(int a=1; a<7; a++)
{
if(checkflag[a]==false)
{
flag=false;
}
}
}
}
if(flag == true)
{
display.setText("Congratulation, you have \ntaken "+count+" rolls to get one of \neach number between 1 and 6");
rolldisable();
restartButton.setVisible(true);
}
}
}
if(event.getSource() == restartButton)
{
restart();
}
}
public void rollenable()
{
roll.setEnabled(true);
}
public void rolldisable()
{
roll.setEnabled(false);
}
public JButton getSubButton()
{
return this.roll;
}
}
Player.java
import java.util.*;
import javax.swing.*;
public class Player
{
private final int MAX = 100;
private Die play = new Die();
private boolean[] results = {false,false,false,false,false,false,false};
private int count;
private int key;
private boolean check = false;
//private JButton roll;
public Player()
{
count=0;
key=0;
}
public void Play()
{
for(int i=0;i<MAX;i++)
{
key=play.Roll();
System.out.print("\nNumber rolled: "+key);
count++;
for(int a=1;a<7;a++)
{
if(a==key)
{
results[a]=true;
System.out.print("\nSo far, you have rolled ");
if(results[a]==true)
{
check=true;
for(int k=1;k<7;k++)
{
if(results[k] ==true)
{
System.out.print(" "+k+" ");
}
if(results[k] == false)
check=false;
}
}
}
}
if(check==true)
{
System.out.print("\nCongratulations, you have taken "+count+" rolls to get one of each number between 1 and 6");
break;
}
}
}
public int Check(int []check,int key)
{
int check1= Arrays.binarySearch(check,key);
return check1;
}
//public JButton getButton()
//{
// JButton button = null;
//SixNumbersPanel2 roll = new SixNumbersPanel2();
//return roll.roll = button;
//}
public void rolldisable()
{
SixNumbersPanel2 dis = new SixNumbersPanel2();
dis.getSubButton().setEnabled(false);
}
}
同样使用restartButton
JButton,它不会重启整个游戏,但仅适用于点击它的玩家。任何关于如何重新启动整个GUI的建议都会很棒。
所有帮助将不胜感激。
答案 0 :(得分:1)
此...
public void rolldisable()
{
SixNumbersPanel2 dis = new SixNumbersPanel2();
dis.getSubButton().setEnabled(false);
}
是错误的,基本上你正在创建SixNumbersPanel2
的新实例,并试图改变它的状态,但它实际上并没有在屏幕上显示,也没有与屏幕上显示的内容有关。
这个解决方案并不简单。您需要的是某种模型/控制器,它可以在SixNumbersPanel2
的两个实例之间共享,并生成可以响应的适当状态事件。
你需要设计一些识别哪个玩家的方法,以便每个SixNumbersPanel2
知道它代表哪个玩家以及哪个玩家当前有效
为了实现所需的功能更改,您需要某种&#34; central&#34; hub,管理核心功能,当状态以某种有意义的方式发生变化时(如下一个玩家转向),可以生成通知/事件
从广义上讲,这些内容包括:
首先,我们需要从某种令牌开始,以区分玩家......
enum Player {
ONE, TWO;
}
接下来,我们需要某种&#34;模型&#34;,用于管理数据和核心功能
public interface SixNumbersModel {
public Player getCurrentTurn();
public Player nextTurn();
public int roll();
public boolean hasWon(Player player);
public Set<Integer> getPlayerResults(Player player);
public int getTurnsCount(Player player);
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
nb:你实际上可以拥有一个&#34;播放器模型&#34;管理结果,但我一直懒惰
我开始使用interface
的原因是模型的用户不应该关心模型是如何实现的(实现可能会将每个玩家的管理结果分成单个模型,但是SixNumbersModel
无法照顾)
public class DefaultSizeNumbersModel implements SixNumbersModel {
private List<ChangeListener> changeListeners;
private Die die = new Die();
private Player turn;
private Map<Player, Set<Integer>> results;
private Map<Player, Integer> turns;
public DefaultSizeNumbersModel() {
changeListeners = new ArrayList<>(2);
results = new HashMap<>();
results.put(Player.ONE, new HashSet<>(6));
results.put(Player.TWO, new HashSet<>(6));
turns = new HashMap<>(2);
turns.put(Player.ONE, 0);
turns.put(Player.TWO, 0);
setCurrentTurn(Player.ONE);
}
@Override
public Player getCurrentTurn() {
return turn;
}
protected void setCurrentTurn(Player player) {
turn = player;
}
@Override
public Player nextTurn() {
switch (getCurrentTurn()) {
case ONE:
setCurrentTurn(Player.TWO);
break;
case TWO:
setCurrentTurn(Player.ONE);
break;
default:
setCurrentTurn(Player.ONE);
break;
}
fireStateChanged();
return getCurrentTurn();
}
@Override
public int roll() {
incrementTurnCount(getCurrentTurn());
int result = die.Roll();
Set<Integer> playerResults = results.get(getCurrentTurn());
playerResults.add(result);
return result;
}
@Override
public boolean hasWon(Player player) {
Set<Integer> playerResults = results.get(getCurrentTurn());
return playerResults.size() == 5; // 0...5
}
@Override
public Set<Integer> getPlayerResults(Player player) {
Set<Integer> actualResults = results.get(player);
Set<Integer> copy = new HashSet<>(actualResults);
return copy;
}
@Override
public int getTurnsCount(Player player) {
return turns.get(player);
}
protected void setTurnsCount(Player player, int count) {
turns.put(player, count);
}
protected void incrementTurnCount(Player player) {
int count = getTurnsCount(player);
count++;
setTurnsCount(player, count);
}
@Override
public void addChangeListener(ChangeListener listener) {
changeListeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
changeListeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : changeListeners) {
listener.stateChanged(evt);
}
}
}
然后我们需要某种&#34;视图&#34; ...
public class SixNumbersPanel extends JPanel {
private Player player;
private SixNumbersModel model;
private JButton roll;
private JTextArea ta;
public SixNumbersPanel(Player player, SixNumbersModel model) {
this.player = player;
this.model = model;
model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
roll.setEnabled(player == model.getCurrentTurn());
}
});
roll = new JButton("Roll");
ta = new JTextArea(5, 10);
roll.setEnabled(player == model.getCurrentTurn());
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel(player.name()), gbc);
add(roll, gbc);
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(new JScrollPane(ta), gbc);
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = model.roll();
ta.append(Integer.toString(result) + "\n");
if (model.hasWon(player)) {
JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
}
model.nextTurn();
}
});
}
}
好吧,大概是基本的,但是,它只是一个按钮和一个文本区域。它会对状态发生变化时要通知的模型注册兴趣,并确保只有当它代表的玩家是当前玩家时才启用该按钮。
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test {
public static void main(String[] args) {
new Test();
}
enum Player {
ONE, TWO;
}
public interface SixNumbersModel {
public Player getCurrentTurn();
public Player nextTurn();
public int roll();
public boolean hasWon(Player player);
public Set<Integer> getPlayerResults(Player player);
public int getTurnsCount(Player player);
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
public class DefaultSizeNumbersModel implements SixNumbersModel {
private List<ChangeListener> changeListeners;
private Die die = new Die();
private Player turn;
private Map<Player, Set<Integer>> results;
private Map<Player, Integer> turns;
public DefaultSizeNumbersModel() {
changeListeners = new ArrayList<>(2);
results = new HashMap<>();
results.put(Player.ONE, new HashSet<>(6));
results.put(Player.TWO, new HashSet<>(6));
turns = new HashMap<>(2);
turns.put(Player.ONE, 0);
turns.put(Player.TWO, 0);
setCurrentTurn(Player.ONE);
}
@Override
public Player getCurrentTurn() {
return turn;
}
protected void setCurrentTurn(Player player) {
turn = player;
}
@Override
public Player nextTurn() {
switch (getCurrentTurn()) {
case ONE:
setCurrentTurn(Player.TWO);
break;
case TWO:
setCurrentTurn(Player.ONE);
break;
default:
setCurrentTurn(Player.ONE);
break;
}
fireStateChanged();
return getCurrentTurn();
}
@Override
public int roll() {
incrementTurnCount(getCurrentTurn());
int result = die.Roll();
Set<Integer> playerResults = results.get(getCurrentTurn());
playerResults.add(result);
return result;
}
@Override
public boolean hasWon(Player player) {
Set<Integer> playerResults = results.get(getCurrentTurn());
return playerResults.size() == 5; // 0...5
}
@Override
public Set<Integer> getPlayerResults(Player player) {
Set<Integer> actualResults = results.get(player);
Set<Integer> copy = new HashSet<>(actualResults);
return copy;
}
@Override
public int getTurnsCount(Player player) {
return turns.get(player);
}
protected void setTurnsCount(Player player, int count) {
turns.put(player, count);
}
protected void incrementTurnCount(Player player) {
int count = getTurnsCount(player);
count++;
setTurnsCount(player, count);
}
@Override
public void addChangeListener(ChangeListener listener) {
changeListeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
changeListeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : changeListeners) {
listener.stateChanged(evt);
}
}
}
public class Die {
private final int MAX = 6;
private int die1;
Random rand = new Random();
//Constructor
public Die() {
die1 = 1;
}// end Constructor
public int Roll() {
die1 = rand.nextInt(MAX) + 1;
return die1;
}
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Roll Six");
frame.setLayout(new GridLayout(2, 0));
SixNumbersModel model = new DefaultSizeNumbersModel();
SixNumbersPanel onePane = new SixNumbersPanel(Player.ONE, model);
SixNumbersPanel twoPane = new SixNumbersPanel(Player.TWO, model);
frame.add(onePane);
frame.add(twoPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SixNumbersPanel extends JPanel {
private Player player;
private SixNumbersModel model;
private JButton roll;
private JTextArea ta;
public SixNumbersPanel(Player player, SixNumbersModel model) {
this.player = player;
this.model = model;
model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
roll.setEnabled(player == model.getCurrentTurn());
}
});
roll = new JButton("Roll");
ta = new JTextArea(5, 10);
roll.setEnabled(player == model.getCurrentTurn());
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel(player.name()), gbc);
add(roll, gbc);
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(new JScrollPane(ta), gbc);
roll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = model.roll();
ta.append(Integer.toString(result) + "\n");
if (model.hasWon(player)) {
JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
}
model.nextTurn();
}
});
}
}
}