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

Java方块点击游戏求助:实现随机方块生成与1分钟计时功能

Java方块点击游戏问题修复方案

核心问题梳理

  1. 无法触发随机方块更新:randomiz()是实例方法,但main方法为静态上下文,无法直接调用;且即使调用,也未将随机生成的位置/大小同步到按钮组件上。
  2. 积分无法累加:按钮点击监听器内重新定义了局部points变量,覆盖了类成员变量,导致每次点击都重置为1。
  3. 缺少计时结束逻辑:未实现1分钟倒计时功能,无法触发游戏结束流程。

修复后的完整代码

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

public class Main {
    int boxSize;
    int boxPosY;
    int boxPosX;
    int points = 0;
    boolean isGameRunning = false;
    Timer gameTimer;
    JLabel timeLabel;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Main::new); // 确保Swing组件在事件调度线程初始化
    }

    public Main() {
        // 创建主窗口
        JFrame frame = new JFrame("方块点击游戏");
        frame.setSize(500, 550); // 预留时间标签空间
        frame.setLayout(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 创建组件
        JButton startButton = new JButton("点击开始");
        JButton pointButton = new JButton("");
        pointButton.setVisible(false);
        JLabel pointLabel = new JLabel();
        timeLabel = new JLabel("剩余时间: 60秒");

        // 设置组件位置和样式
        startButton.setBounds(175, 200, 150, 50);
        pointButton.setBounds(100, 100, 100, 100);
        pointLabel.setBounds(0, 0, 200, 50);
        pointLabel.setFont(new Font("Arial", Font.PLAIN, 32));
        pointLabel.setForeground(Color.BLUE);
        timeLabel.setBounds(300, 0, 200, 50);
        timeLabel.setFont(new Font("Arial", Font.PLAIN, 24));
        timeLabel.setForeground(Color.RED);

        // 添加组件到窗口
        frame.add(startButton);
        frame.add(pointButton);
        frame.add(pointLabel);
        frame.add(timeLabel);

        // 开始按钮事件
        startButton.addActionListener(e -> {
            startButton.setVisible(false);
            pointButton.setVisible(true);
            points = 0;
            pointLabel.setText("得分: " + points);
            startGameTimer(); // 启动计时器
            randomiz(); // 生成第一个随机方块
            updateButtonPosition(pointButton);
        });

        // 方块点击事件
        pointButton.addActionListener(e -> {
            if (isGameRunning) {
                points++;
                pointLabel.setText("得分: " + points);
                randomiz();
                updateButtonPosition(pointButton);
            }
        });

        frame.setVisible(true);
    }

    // 生成随机方块的位置和大小(确保不超出窗口)
    public void randomiz() {
        boxSize = (int)(Math.random() * 100) + 30; // 最小30px,避免方块过小
        // 计算最大可放置位置,确保方块完全在窗口内
        boxPosX = (int)(Math.random() * (500 - boxSize));
        boxPosY = (int)(Math.random() * (500 - boxSize - 50)); // 预留时间标签的高度
    }

    // 更新按钮的位置和大小
    private void updateButtonPosition(JButton button) {
        button.setBounds(boxPosX, boxPosY, boxSize, boxSize);
    }

    // 启动1分钟游戏计时器
    private void startGameTimer() {
        isGameRunning = true;
        int remainingTime = 60;
        gameTimer = new Timer(1000, e -> {
            remainingTime--;
            timeLabel.setText("剩余时间: " + remainingTime + "秒");
            if (remainingTime <= 0) {
                gameTimer.stop();
                isGameRunning = false;
                JOptionPane.showMessageDialog(null, "游戏结束!最终得分: " + points);
            }
        });
        gameTimer.start();
    }
}

关键修复说明

  • Swing线程安全:使用SwingUtilities.invokeLater初始化界面,符合Swing线程规范。
  • 随机方块边界控制:在randomiz()中计算位置时,确保方块不会超出窗口范围,避免部分区域不可见。
  • 积分逻辑修正:直接操作类成员变量points,实现正确累加。
  • 计时器实现:使用javax.swing.Timer(Swing专用计时器,避免线程阻塞),每秒更新剩余时间,到期后弹出结束提示并终止游戏。
  • 实例化重构:将main方法改为启动事件调度线程并创建Main实例,解决静态上下文无法调用实例方法的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:06:20