You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:检查并修复5x5按钮拼图游戏的颜色切换逻辑问题

修复25格拼图游戏的按钮颜色切换逻辑

你当前的拼图游戏实现中,点击按钮时自身会在浅灰色和红色间切换,但周围按钮只会被强制设为红色。需要优化的逻辑是:当周围按钮被被动触发(即被其他按钮的点击影响)时,如果当前已经是红色,就切换回浅灰色;如果是浅灰色,则切换为红色。

原代码问题分析

原代码处理周围按钮时,直接调用setForeground(Color.RED),没有判断按钮当前的颜色状态,导致被动触发时无法切换回原颜色。另外,每次点击都通过嵌套循环查找按钮的行列索引,效率较低。

修改方案

  1. 给每个按钮绑定对应的行列索引,避免每次点击都遍历数组查找
  2. 封装颜色切换逻辑,统一处理按钮颜色反转
  3. 修改周围按钮的触发逻辑,实现被动状态下的颜色切换

修改后的完整代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Frame extends JFrame {

    private static final long serialVersionUID = 1L;
    public JButton[][] Buttons = new JButton[5][5]; // 5x5 按钮数组

    public static void main(String[] args) {
        new Frame();
    }

    public Frame() {
        initGui();
    }

    // 检查所有按钮是否为红色
    public boolean allButtonsAreRed() {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                if (!Buttons[i][j].getForeground().equals(Color.RED)) {
                    return false;
                }
            }
        }
        return true;
    }

    public void initGui() {
        // 窗口设置
        setTitle("25格拼图");
        setSize(new Dimension(500, 500));
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // 窗口布局
        setLayout(new GridLayout(5, 5, 5, 5));

        JOptionPane.showMessageDialog(null, "任务:点击按钮,直到所有圆圈都变成红色!");

        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                JButton button = new JButton();

                // 按钮设置
                button.setBorderPainted(true);
                button.setContentAreaFilled(false);
                button.setOpaque(true);
                button.setBorder(new RoundedBorder(200));
                button.setForeground(Color.LIGHT_GRAY);

                // 给按钮绑定行列索引,避免点击时遍历查找
                button.putClientProperty("row", i);
                button.putClientProperty("col", j);

                Buttons[i][j] = button;
                add(Buttons[i][j]);

                // 按钮点击事件监听
                button.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        JButton clickedBtn = (JButton) e.getSource();

                        // 切换自身颜色
                        Color newColor = clickedBtn.getForeground().equals(Color.LIGHT_GRAY) ? Color.RED : Color.LIGHT_GRAY;
                        clickedBtn.setForeground(newColor);

                        // 从按钮属性中获取行列索引
                        int clickedRow = (int) clickedBtn.getClientProperty("row");
                        int clickedCol = (int) clickedBtn.getClientProperty("col");

                        // 处理上方按钮
                        if (clickedRow > 0) {
                            toggleButtonColor(Buttons[clickedRow - 1][clickedCol]);
                        }
                        // 处理左侧按钮
                        if (clickedCol > 0) {
                            toggleButtonColor(Buttons[clickedRow][clickedCol - 1]);
                        }
                        // 处理右侧按钮
                        if (clickedCol < 4) {
                            toggleButtonColor(Buttons[clickedRow][clickedCol + 1]);
                        }
                        // 处理下方按钮
                        if (clickedRow < 4) {
                            toggleButtonColor(Buttons[clickedRow + 1][clickedCol]);
                        }

                        // 检查是否全部变红,触发胜利提示
                        if (allButtonsAreRed()) {
                            JOptionPane.showMessageDialog(clickedBtn, "恭喜你,通关了!");
                            System.exit(0);
                        }
                    }
                });
            }
        }
        setVisible(true);
    }

    // 封装按钮颜色切换方法,复用逻辑
    private void toggleButtonColor(JButton button) {
        Color currentColor = button.getForeground();
        button.setForeground(currentColor.equals(Color.RED) ? Color.LIGHT_GRAY : Color.RED);
    }
}

// 圆角边框类(原代码引用但未实现,补充完整)
class RoundedBorder implements javax.swing.border.Border {
    private int radius;

    RoundedBorder(int radius) {
        this.radius = radius;
    }

    public Insets getBorderInsets(Component c) {
        return new Insets(this.radius+1, this.radius+1, this.radius+2, this.radius);
    }

    public boolean isBorderOpaque() {
        return true;
    }

    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        g.drawRoundRect(x, y, width-1, height-1, radius, radius);
    }
}

关键修改说明

  • 优化索引查找:通过putClientProperty给每个按钮存储行列值,点击时直接读取,替代嵌套循环查找,提升运行效率。
  • 统一切换逻辑:新增toggleButtonColor方法,将颜色反转逻辑封装,代码更简洁易维护。
  • 修复被动触发逻辑:周围按钮不再被强制设为红色,而是调用切换方法实现颜色反转,满足需求。
  • 补充缺失实现:原代码引用的RoundedBorder类未给出实现,这里补充完整,确保代码可直接运行。

内容的提问来源于stack exchange,提问作者Cxnim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:25:27