【发布时间】:2015-05-15 10:30:34
【问题描述】:
我制作了一个很像扫雷游戏的 GUI 游戏,尽管逻辑要少得多。基本上,用户点击一个空间,看看下面是否有金子,如果没有,它会显示一个 X。如果有,它会显示一个金子。我想让游戏重新启动,一旦用户找到 10 个金币,所有数据都会重置。但是,我的do while 循环没有成功。我已经注释掉了导致我出现问题的代码部分。每次我用我注释掉的东西运行程序时,当我单击第一个按钮时,它就会卡住并且不会继续运行。否则,注释掉的东西,它应该如何工作。
问题:如何让我的程序在用户发现 10 个金币后重新启动并重置数据值?另外,为什么我设置的 12x12 按钮网格与我设置 2D 按钮阵列的方式不成比例?
当我将 do while 注释掉时,游戏的外观如下:
public class NuggetPanel extends JPanel {
// variable declaration
boolean restartGame = false;
JButton[][] buttons = new JButton[12][12];
JButton restart = new JButton("You win! Click to restart game");
int count = 0;
int goldFound = 0;
JLabel clickCount = new JLabel("Number of digs: " + count);
JLabel goldCount = new JLabel("Gold found: " + goldFound);
// sets up the panel
public NuggetPanel() {
setLayout(new GridLayout(12, 12, 2, 2));
JPanel LabelPane = new JPanel();
//creates 2D array of buttons
for (int i = 0; i < buttons.length; i++) {
for (int j = 0; j < buttons[i].length; j++) {
buttons[i][j] = new JButton("");
buttons[i][j].addActionListener(new buttonListener());
add(buttons[i][j]);
}
}
//adds components
LabelPane.add(clickCount);
LabelPane.add(goldCount);
LabelPane.add(restart);
add(LabelPane);
restart.setVisible(false);
}
// button is clicked
private class buttonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// do{
// finds which button was clicked
JButton buttonClicked = (JButton) e.getSource();
restartGame = false;
restart.setVisible(false);
// sets up gold array
Boolean[] randomGold = new Boolean[144];
// fills gold array with 10 true elements
for (int i = 0; i < randomGold.length; i++) {
randomGold[i] = false;
// sets 10 indexes in the array to true
if (i == 10 || i == 20 || i == 30 || i == 40 || i == 50 || i == 60 || i == 70 || i == 80 || i == 90 || i == 100) {
randomGold[i] = true;
}
}
// randomizes gold array
Collections.shuffle(Arrays.asList(randomGold));
// iterates through button array
for (int i = 0; i < buttons.length; i++) {
for (int j = 0; j < buttons[i].length; j++) {
if (buttonClicked == buttons[i][j]) {
// if there is a gold under the square, shows gold icon
if (randomGold[i] == true) {
buttons[i][j].setIcon(new ImageIcon("./src/Gold.jpg"));
buttons[i][j].removeActionListener(this);
goldFound++;
count++;
clickCount.setText("Number of digs: " + count);
goldCount.setText("Gold found: " + goldFound + " ");
}
// if there is no gold under the square, shows X
else {
buttons[i][j].removeActionListener(this);
buttons[i][j].setIcon(new ImageIcon("./src/Missed.png"));
count++;
clickCount.setText("Number of digs: " + count);
goldCount.setText("Gold found: " + goldFound);
}
// if (goldFound == 10) {
// restart.setVisible(true);
// }
//
// if (buttonClicked == restart) {
// count = 0;
// goldFound = 0;
// clickCount.setText("Number of digs: " + count);
// for (int x = 0; i < buttons.length; i++)
// {
// for(int y = 0; j < buttons[i].length; j++)
// {
// buttons[x][y].setIcon(null);
// }
// }
// restartGame = true;
// }
j = buttons[i].length - 1;
i = buttons.length - 1;
}
}
}
// } while(restartGame = true);
}
}
}
【问题讨论】:
-
影响按钮大小的因素有很多,首先是按钮自己的
margin,其次是包含LabelPane。GridLayout为所有组件提供相同数量的空间。考虑将您的按钮添加到它们自己的JPanel(使用GridLayout),然后使用BorderLayout将两个面板组合到您的NuggetPanel上 -
你的边做边想对于线性控制台程序来说是可以的,但完全违背了事件驱动的 GUI 编程的规则。相反,您会希望由某个东西(通常是模型类)保存游戏状态,并且如果按下重新启动按钮,您会希望重新设置该状态。
-
我将如何在
for循环中执行此操作? -
在游戏开始前随机化你的数据
-
那么把Buttons放在一个GridLayout中,把Components放在一个普通的旧JPanel中?然后将这两个都放在 NuggetPanel 中,并将 NuggetPanel 的布局设置为 BorderLayout?
标签: java swing user-interface button graphics