我知道这可能是一个时间问题,但老实说,我没有足够的经验来解决具体问题,并找出解决方法。 基本上,它是一个Connect Four游戏,我现在正在学习事件监听器等基础知识。
package siena;
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ConnectFour {
public static int buttonPushed = -1;
public static void main (String[] args) throws java.lang.Exception {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
JFrame board = new JFrame("Connect Four", gc);
board.setResizable(false);
board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagLayout gridbag = new GridBagLayout();
board.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = 3;
JButton ng = new JButton("New Game");
c.anchor = c.NORTH;
c.fill = c.HORIZONTAL;
c.insets = new Insets(5, 5, 5, 5);
board.add(ng, c);
c.gridx = 1;
JButton eg = new JButton("Close");
c.gridy = 1;
c.gridwidth = 1;
final JButton add[] = new JButton[7];
ButtonClicker clickers[] = new ButtonClicker[9];
for (int i = 0; i < clickers.length; i++) {
clickers[i] = new ButtonClicker(i);
}
ng.addActionListener(clickers[0]);
eg.addActionListener(clickers[8]);
for(int i = 0; i < 7; i++) {
add[i] = new JButton("Drop token");
add[i].addActionListener(clickers[i + 1]);
c.gridx = i;
board.add(add[i], c);
}
JLabel slot[][] = new JLabel[7][6];
int slotStat[][] = new int[7][6];
c.ipadx = 0;
c.ipady = 0;
c.gridx = 0;
c.gridy = 2;
ImageIcon[] img = {new ImageIcon(ImageIO.read(new java.io.File("src/siena/gray.png"))), new ImageIcon(ImageIO.read(new java.io.File("src/siena/red.png"))), new ImageIcon(ImageIO.read(new java.io.File("src/siena/yellow.png")))};
JLabel n = new JLabel(img[0]);
for (int x = 0; x < 7; x++) {
for (int y = 0; y < 6; y++) {
slot[x][y] = new JLabel(n.getIcon());
slotStat[x][y] = 0;
board.add(slot[x][y], c);
c.gridy++;
}
c.gridx++;
c.gridy = 2;
}
c.gridx = 0;
c.gridy = 8;
c.gridwidth = 7;
c.anchor = c.CENTER;
Label info = new Label("It is the RED player's turn.");
info.setAlignment(info.CENTER);
board.add(info, c);
board.pack();
board.setVisible(true);
boolean isRedTurn = true;
int redCheck = 0;
int yellowCheck = 0;
while(buttonPushed != 9){
while(buttonPushed == -1);
switch(buttonPushed) {
case 0:
for (int x = 0; x < 7; x++) {
for (int y = 0; y < 6; y++) {
slotStat[x][y] = 0;
slot[x][y].setIcon(img[0]);
isRedTurn = true;
}
}
buttonPushed = -1;
break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7:
if (slotStat[buttonPushed - 1][0] != 0) {
info.setText("That column is full!");
info.wait(100, 50000);
buttonPushed = -1;
break;
} else {
for (int y = 0; y < 6; y++) {
if (y != 5 && slotStat[buttonPushed - 1][y + 1] == 0) {
//if we're not at the bottom and the slot below this one is empty
if (isRedTurn) slot[buttonPushed - 1][y].setIcon(img[1]);
else slot[buttonPushed - 1][y].setIcon(img[2]);
Thread.sleep(200);
slot[buttonPushed - 1][y].setIcon(img[0]);
} else {
//if we're at the bottom or the slot below this one is full
if (isRedTurn) {
slotStat[buttonPushed][y] = 1;
slot[buttonPushed][y].setIcon(img[1]);
redCheck++;
} else {
slotStat[buttonPushed][y] = 2;
slot[buttonPushed][y].setIcon(img[2]);
yellowCheck++;
}
isRedTurn = !isRedTurn;
}
}
}
buttonPushed = -1;
break;
}
}
}
}
ButtonPushed类只是扩展ActionListener的东西,所以我可以找出按下了什么按钮,它有一个“id”int属性,按下按钮被传递给连接四件中的buttonPushed int
答案 0 :(得分:1)
因此,总结一下这些评论,我使用的是一种在线性(非基于事件)程序中使用的结构。虽然循环在等待输入时不起作用,而不是使用一个大的静态主方法和稍微修改的ActionListener类,我应该使用输入事件来调用内部方法来修改内部数据,然后更新外部GUI (基于内部数据在其自己的类中,并使用自己的类方法)。
如果有人需要看一个例子,这是我迄今为止的工作。我仍然需要编辑其中一些(即程序如何结束,我需要添加一个win检测器),但GUI功能完备。
ConnectFour类:http://pastebin.com/yeGALQn7
ButtonClicker类:http://pastebin.com/Y2y0SfW9
CFBoard课程:http://pastebin.com/g9qqBmry
哦,而且,对于好奇的阅读,我有理由相信它只在调试模式下工作的原因是断点阻止输入与通过while()循环遍历的main()冲突因此,使其完全由事件驱动意味着这些冲突不再存在。
感谢大家的帮助,特别是@HovercraftFullOfEels!