Java--GUI界面的猜数游戏

一.设计目标.

   一个简单的猜数游戏系统,通过GUI界面设计来和用于进行一个简单的游戏交互。游戏会随机生成一个0-100的数字,在用户猜数字的过程中会相应的提示所输入的数字太大或者太小,在猜中时会提示恭喜语句并给出分数并记录在txt文件中。其中,分数为百分制,分数设置为时间50分,每过一秒扣除1分,最低为0分;次数50分,猜错一次扣除一分,最低为0分。文件中记录时间,次数以及成绩。

二.功能简介图

三.运行结果截图

四.代码

/**
 * 游戏界面的 Java Swing 应用程序。
 * 允许用户猜测随机生成的数字,记录猜测次数和时间,计算并展示得分,保存分数记录到文件,并展示历史分数记录。
 * 游戏还包括弹出对话框,显示猜中时的得分和当前分数排名。
 */

// 导入 Java Swing 和其他必要的包
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.Scanner;

/**
 * 猜数游戏的图形用户界面类
 */
//继承自JFrame
public class GuessingGameGUI extends JFrame {
    // 存储随机生成的数字
    private int randomNumber;
    // 记录玩家猜测次数
    private int attempts;
    // 记录游戏开始时间
    private long startTime;

    // 输入猜测的文本框
    private JTextField guessField;
    // 猜测按钮
    private JButton guessButton;
    // 显示猜测结果的标签
    private JLabel resultLabel;
    // 显示历史分数记录的文本区域
    private JTextArea scoreArea;

    // 分数记录文件路径
    private static final String SCORE_FILE = "scores.txt";

    /**
     * 构造函数,初始化游戏界面
     */
    public GuessingGameGUI() {
        super("猜数游戏"); // 设置窗口标题为“猜数游戏”

        // 设置窗口关闭行为
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 当点击窗口关闭按钮时,退出程序
        // 设置窗口大小
        setSize(400, 300); // 设置窗口宽度为400像素,高度为300像素
        // 居中显示
        setLocationRelativeTo(null); // 将窗口居中显示
        // 设置布局为网格布局,5行1列
        setLayout(new GridLayout(5, 1)); // 使用网格布局管理器,将组件分为5行1列的网格

        // 初始化各组件
        guessField = new JTextField(); // 创建一个文本框用于输入猜测的数字
        guessButton = new JButton("猜!"); // 创建一个按钮,点击后执行猜数字操作
        resultLabel = new JLabel("欢迎来到猜数游戏!"); // 创建一个标签,用于显示游戏结果
        scoreArea = new JTextArea(); // 创建一个文本区域,用于显示游戏历史记录

        scoreArea.setRows(20); // 设置文本区域的行数为20
        scoreArea.setEditable(false); // 设置文本区域不可编辑
        JScrollPane scrollPane = new JScrollPane(scoreArea); // 创建一个滚动面板,将文本区域添加到滚动面板中

        guessField.setPreferredSize(new Dimension(200, 30)); // 设置文本框的首选尺寸为200x30像素
        guessButton.setPreferredSize(new Dimension(80, 30)); // 设置按钮的首选尺寸为80x30像素
        resultLabel.setPreferredSize(new Dimension(400, 30)); // 设置标签的首选尺寸为400x30像素
        scrollPane.setMinimumSize(new Dimension(400, 160)); // 设置滚动面板的最小尺寸为400x160像素

        // 添加各组件到界面中
        add(guessField); // 将文本框添加到窗口中
        add(guessButton); // 将按钮添加到窗口中
        add(resultLabel); // 将标签添加到窗口中
        add(scrollPane); // 将滚动面板添加到窗口中

        // 为按钮添加监听器
        guessButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                checkGuess(); // 当按钮被点击时,调用checkGuess方法进行猜数字操作
            }
        });

        // 为文本框添加监听器
        guessField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                checkGuess(); // 当文本框内容发生变化时,调用checkGuess方法进行猜数字操作
            }
        });

        // 初始化游戏状态和历史记录
        initializeGame(); // 调用initializeGame方法初始化游戏状态和历史记录
        updateScoreArea(); // 调用updateScoreArea方法更新游戏历史记录显示区域的内容
    }


    /**
     * 初始化游戏状态
     */
    private void initializeGame() {
        generateRandomNumber();
        updateResultLabel("欢迎来到猜数游戏!");
    }

    /**
     * 生成随机数
     */
    private void generateRandomNumber() {
        Random random = new Random();
        randomNumber = random.nextInt(100) + 1;
        attempts = 0;
        startTime = System.currentTimeMillis();
    }

    /**
     * 检查猜测
     */
    private void checkGuess() {
        try {
            int userGuess = Integer.parseInt(guessField.getText());
            attempts++;

            if (userGuess == randomNumber) {
                handleWin();
            } else {
                updateResultLabel(userGuess > randomNumber ? "太大了,再试试吧!" : "太小了,再试试吧!");
            }
            guessField.setText("");
        } catch (NumberFormatException ex) {
            updateResultLabel("请输入有效的整数!");
        }
    }

    /**
     * 处理猜测正确
     */
    private void handleWin() {
        long endTime = System.currentTimeMillis();
        long totalTime = endTime - startTime;
        double gameTimeInSeconds = totalTime / 1000.0;

        int score = calculateScore(attempts, gameTimeInSeconds);
        updateResultLabel(String.format("恭喜你猜对了!得分:%d", score));

        saveScore(attempts, gameTimeInSeconds, score);

        // 弹出对话框,包含当前分数排名
        String currentRanking = getCurrentRanking();
        JOptionPane.showMessageDialog(this, "恭喜你猜中!得分:" + score + "\n当前分数排名:\n" + currentRanking, "恭喜", JOptionPane.INFORMATION_MESSAGE);

        // 重新开始游戏并更新历史记录
        initializeGame();
        updateScoreArea();
    }

    /**
     * 计算得分
     */
    private int calculateScore(int attempts, double gameTimeInSeconds) {
        int maxTimeScore = 50;
        int maxAttemptsScore = 50;

        int timeScore = maxTimeScore - (int) Math.min(gameTimeInSeconds, maxTimeScore);
        int attemptsScore = maxAttemptsScore - Math.min(attempts, maxAttemptsScore);

        return Math.max(timeScore + attemptsScore, 0);
    }

    /**
     * 保存得分记录到文件
     */
    private void saveScore(int attempts, double gameTimeInSeconds, int score) {
        try {
            FileWriter fileWriter = new FileWriter(SCORE_FILE, true);
            PrintWriter printWriter = new PrintWriter(fileWriter);
            String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            printWriter.printf("[%s] 次数: %d, 时间: %.2f 秒, 得分: %d%n", timestamp, attempts, gameTimeInSeconds, score);
            printWriter.close();
        } catch (IOException e) {
            updateResultLabel("无法保存成绩到文件:" + e.getMessage());
        }
    }

    /**
     * 更新结果标签
     */
    private void updateResultLabel(String message) {
        resultLabel.setText(message);
    }

    /**
     * 更新历史分数记录区域
     */
    // 更新分数显示区域的方法
    private void updateScoreArea() {
        try {
            // 创建一个扫描器对象,用于读取分数文件
            Scanner scanner = new Scanner(new File(SCORE_FILE));
            // 创建一个字符串构建器对象,用于存储历史分数记录
            StringBuilder scores = new StringBuilder("历史分数记录:\n");

            // 当文件中还有内容时,循环执行以下操作
            while (scanner.hasNextLine()) {
                // 将文件中的每一行内容添加到字符串构建器中,并在每行后添加换行符
                scores.append(scanner.nextLine()).append("\n");
            }

            // 将字符串构建器中的分数信息转换为字符串,并设置为分数显示区域的文本
            scoreArea.setText(scores.toString());
        } catch (IOException e) {
            // 如果发生输入输出异常,调用更新结果标签方法,显示错误信息
            updateResultLabel("无法读取分数文件:" + e.getMessage());
        }
    }

    /**
     * 获取当前排名
     */
    private String getCurrentRanking() {
        // 创建一个字符串构建器对象,用于存储当前排名信息
        StringBuilder currentRanking = new StringBuilder();
        try {
            // 创建一个扫描器对象,用于读取分数文件
            Scanner scanner = new Scanner(new File(SCORE_FILE));
            // 当文件中还有内容时,循环执行以下操作
            while (scanner.hasNextLine()) {
                // 将文件中的每一行内容添加到字符串构建器中,并在每行后添加换行符
                currentRanking.append(scanner.nextLine()).append("\n");
            }
        } catch (IOException e) {
            // 如果发生输入输出异常,调用更新结果标签方法,显示错误信息
            updateResultLabel("无法读取分数文件:" + e.getMessage());
        }
        // 将字符串构建器中的当前排名信息转换为字符串,并返回
        return currentRanking.toString();
    }

    /**
     * 主方法,启动游戏
     */
    public static void main(String[] args) {
        // 在事件调度线程上创建并显示游戏界面
        SwingUtilities.invokeLater(() -> new GuessingGameGUI().setVisible(true));
    }
}

五.不足之处

  可以继续丰富提示语的内容,第一次猜错和第三次猜错采用不同的鼓励语,在越来越接近生成的随机数时使用不同的评语。第一次直接命中和第十次命中采用不同的恭喜语句。

  系统可以进一步设计一个排行榜功能,按照分数从高到低的排行榜功能,并且可以实时更新排行榜。

  设计一个用户名输入栏,来记录来自不同用户的使用数据。

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,您想了解如何实现Java猜数字游戏的窗口化界面,是吗?那么我可以为您提供一些指导。 首先,您需要用Java编写猜数字游戏的逻辑代码,包括生成随机数字、接受用户的输入、比较用户输入和随机数字的大小关系等等。这部分代码可以在控制台中运行,但是为了实现窗口化界面,我们需要将其嵌入到Java图形用户界面(GUI)中。 Java GUI提供了许多组件来构建各种用户界面,例如JFrame、JPanel、JButton等等。您可以使用这些组件来创建一个包含猜数字游戏逻辑的窗口化界面。 以下是一个简单的窗口化猜数字游戏的示例代码: ```java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class GuessNumberGame extends JFrame implements ActionListener { private JTextField textField; private JTextArea textArea; private JButton button; private int randomNum; private int guessCount; public GuessNumberGame() { super("Guess Number Game"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 200); setLayout(new BorderLayout()); setLocationRelativeTo(null); JPanel inputPanel = new JPanel(); inputPanel.setLayout(new FlowLayout()); inputPanel.add(new JLabel("Enter your guess:")); textField = new JTextField(10); textField.addActionListener(this); inputPanel.add(textField); button = new JButton("Guess"); button.addActionListener(this); inputPanel.add(button); textArea = new JTextArea(); textArea.setEditable(false); add(inputPanel, BorderLayout.NORTH); add(new JScrollPane(textArea), BorderLayout.CENTER); randomNum = (int)(Math.random() * 100) + 1; guessCount = 0; } public void actionPerformed(ActionEvent e) { int guess = Integer.parseInt(textField.getText()); guessCount++; if (guess == randomNum) { textArea.append("Congratulations! You guessed the number in " + guessCount + " tries.\n"); textField.setEditable(false); button.setEnabled(false); } else if (guess < randomNum) { textArea.append("Too low, try again.\n"); } else { textArea.append("Too high, try again.\n"); } textField.setText(""); } public static void main(String[] args) { GuessNumberGame game = new GuessNumberGame(); game.setVisible(true); } } ``` 这段代码创建了一个继承自JFrame的GuessNumberGame类,该类实现了ActionListener接口以处理用户输入事件。在构造函数中,我们创建了一个包含输入框和按钮的JPanel,以及一个用于显示游戏信息的JTextArea。我们还使用Math.random()方法生成了一个1到100之间的随机数字,并将猜测次数初始化为0。 在actionPerformed()方法中,我们首先获取用户输入的整数,并增加猜测次数。然后,我们根据用户输入和随机数字的大小关系,在JTextArea中输出相应的信息。如果用户猜对了数字,我们禁用输入框和按钮,并显示游戏结束的信息。 最后,在main()方法中,我们创建了一个GuessNumberGame对象并将其显示出来。 希望这个示例代码能够帮助您实现Java猜数字游戏的窗口化界面!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值