java - 在使用 JFrame 制作 ConnectFour 游戏时,如何使用 MouseListener 或 Painted Discs 来做条件(玩家 1 获胜等)?
问题描述
对于我的 ConnectFour 游戏(在 JFrame 上),我不知道如何使用鼠标侦听器或画盘来检查某个玩家是否连续完成了 4 个圆圈。
public class ConnectFour {
public static void main(String[] args) {
new ConnectFour();
}
public ConnectFour() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("ConnectFour");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GamePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum Player {
RED, BLUE, BLACK;
}
public class GamePane extends JPanel {
private BoardPane boardPane;
private JLabel label;
private Player player = null;
public GamePane() {
setLayout(new BorderLayout());
boardPane = new BoardPane();
add(boardPane);
label = new JLabel("...");
label.setHorizontalAlignment(JLabel.CENTER);
label.setForeground(Color.WHITE);
label.setOpaque(true);
label.setBorder(new EmptyBorder(10, 10, 10, 10));
add(label, BorderLayout.NORTH);
updatePlayer();
boardPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
updatePlayer();
}
});
}
protected void updatePlayer() {
String text = "...";
Color color = null;
if (player == null || player.equals(Player.BLUE)) {
player = Player.RED;
text = "Red";
color = Color.RED;
} else if (player.equals(Player.RED)) {
player = Player.BLUE;
text = "Blue";
color = Color.BLUE;
//} else if {
}
label.setText(text);
label.setBackground(color);
boardPane.setPlayer(player);
}
}
public class BoardPane extends JPanel {
private Player[][] board;
private Player player;
private int hoverColumn = -1;
public BoardPane() {
board = new Player[8][8];
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
board[row][col] = Player.BLACK;
}
}
MouseAdapter mouseHandler = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
hoverColumn = getColumnAt(e.getPoint());
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
hoverColumn = -1;
repaint();
}
@Override
public void mouseClicked(MouseEvent e) {
if (hoverColumn > -1) {
addPieceTo(hoverColumn);
repaint();
}
}
};
addMouseMotionListener(mouseHandler);
addMouseListener(mouseHandler);
}
public void addChangeListener(ChangeListener listener) {
listenerList.add(ChangeListener.class, listener);
}
public void removeChangeListener(ChangeListener listener) {
listenerList.add(ChangeListener.class, listener);
}
public void setPlayer(Player player) {
this.player = player;
}
protected void addPieceTo(int col) {
boolean added = false;
if (col >= 0 && col < board[0].length) {
for (int row = 0; row < board.length; row++) {
if (board[row][col] != Player.BLACK) {
if (row >= 0) {
board[row - 1][col] = player;
added = true;
}
break;
}
}
}
if (!added) {
if (board[0][col] == Player.BLACK) {
board[board.length - 1][col] = player;
added = true;
}
}
if (added) {
fireStateChanged();
}
repaint();
}
protected void fireStateChanged() {
ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
if (listeners != null && listeners.length > 0) {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(evt);
}
}
}
protected int getColumnAt(Point p) {
int size = Math.min(getWidth() - 1, getHeight() - 1);
int xOffset = (getWidth() - size) / 2;
int yOffset = (getHeight() - size) / 2;
int padding = getBoardPadding();
int diameter = (size - (padding * 2)) / 8;
int xPos = p.x - xOffset;
int column = xPos / diameter;
return Math.min(Math.max(0, column), board[0].length - 1);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(2000, 925);
}
protected int getBoardPadding() {
return 10;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
int size = Math.min(getWidth() - 1, getHeight() - 1);
int xOffset = (getWidth() - size) / 2;
int yOffset = (getHeight() - size) / 2;
g2d.fill(new RoundRectangle2D.Double(xOffset, yOffset, size, size, 20, 20));
int padding = getBoardPadding();
int diameter = (size - (padding * 2)) / 8;
for (int row = 0; row < board.length; row++) {
int yPos = (yOffset + padding) + (diameter * row);
for (int col = 0; col < board[row].length; col++) {
int xPos = (xOffset + padding) + (diameter * col);
switch (board[row][col]) {
case RED:
g2d.setColor(Color.RED);
break;
case BLUE:
g2d.setColor(Color.BLUE);
break;
default:
g2d.setColor(getBackground());
break;
}
g2d.fill(new Ellipse2D.Double(xPos, yPos, diameter, diameter));
}
}
if (hoverColumn > -1) {
int yPos = (yOffset + padding) + (diameter * 0);
int xPos = (xOffset + padding) + (diameter * hoverColumn);
if (player != null) {
switch (player) {
case RED:
g2d.setColor(Color.RED);
break;
case BLUE:
g2d.setColor(Color.BLUE);
break;
default:
g2d.setColor(getBackground());
break;
}
g2d.fill(new Ellipse2D.Double(xPos, yPos, diameter, diameter));
}
}
g2d.dispose();
}
}
}
棋盘显示良好,每当我点击一个圆圈时,它就会被填满,但我想要的是让程序能够识别玩家是否连续填满了 4 个圆圈。
解决方案
推荐阅读
- java - 如何处理viewpager2中edittext的焦点
- python-3.x - 如何使用我的使用量和量对成本的括号动态计算水费成本?
- apache-spark - 如何根据火花结构化流中的时间戳字段进行重复数据删除和保持最新?
- shopware - 我如何以 Shopware 6 的形式上传拖车图像
- java - 使用 JScrollPane 的正确方法是什么?
- java - 使用 java grpc 在 ServerInterceptor 中验证请求的方法
- python - 在 Python 中使用消息框时出现错误
- asp.net-core - 避免剃刀页面中代码重复的最简单方法
- database - Laravel 中的雄辩关系(7)
- node.js - 使用 Express/node 全局监听