我有这个非常简单的数字猜谜游戏,它几乎完成,但我有一些问题



我想知道是否有人可以看看我的代码,这是工作,所以你可以复制它并测试它。我的问题是,当底部的条数到结束时,它应该结束游戏,然后重新开始。但我认为我错过了一些代码或我的代码只是没有正确地写做我想做的事情。谁能检查一下,看看我哪里出错了?

这是带有所有GUI和main()的游戏屏幕:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
public class GameScreen {
    public static void main(String[] args) throws InterruptedException {
        final ProgressBar progressBar = new ProgressBar() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(0, 30);
            }
        };
        final JFrame game = new JFrame();
        final JButton playButton, guessButton;
        final JPanel topPanel, gamePanel, rangePanel, guessPanel;
        final JTextArea gameStatus;
        final GuessingGame gameNumbers;
        final JLabel rangeLabel = new JLabel("Range: ");
        final JTextField playerName = new JTextField("", 20);
        final JTextField guessInput = new JTextField("", 20);
        gameStatus = new JTextArea(10, 20);
        JScrollPane scroll = new JScrollPane(gameStatus);
        gameNumbers = new GuessingGame();
        playButton = new JButton("Play");
        guessButton = new JButton("Guess");
topPanel = new JPanel();
        topPanel.setBackground(Color.yellow);
        topPanel.add(new JLabel("Player: "));
        topPanel.add(playerName);
        topPanel.add(playButton);
        rangePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        rangePanel.add(rangeLabel, BorderLayout.CENTER);
        guessPanel = new JPanel();
        guessPanel.add(new JLabel("Guess: "));
        guessPanel.add(guessInput);
        guessPanel.add(guessButton);
        gamePanel = new JPanel(new BorderLayout());
        gamePanel.add(rangePanel, BorderLayout.NORTH);
        gamePanel.add(guessPanel);
        game.setTitle("Guessing Game");
        game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        game.add(topPanel, BorderLayout.NORTH);
        game.add(scroll, BorderLayout.EAST);
        game.add(gamePanel, BorderLayout.CENTER);
        game.add(progressBar, BorderLayout.SOUTH);
        gameStatus.setFocusable(false);
        guessButton.setEnabled(false);
        guessInput.setEnabled(false);
        final Timer gameTimer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                if (progressBar.getRunStatus() == false){
                    System.out.println("YAY");
                    guessButton.setEnabled(false);
                    guessInput.setEnabled(false);
                    playButton.setEnabled(true);
                    playerName.setEnabled(true);
                }
            }
        });
        playButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (playerName.getText().equals("")) {
                    JOptionPane.showMessageDialog(gamePanel, "Invalid Player Name");
                } else {
                    progressBar.repaint();
                    progressBar.StartTimer();
                    progressBar.setBackground(Color.gray);
                    gameNumbers.play();
                    gameStatus.append("Game Started!n");
                    rangeLabel.setText(gameNumbers.toString());
                    guessButton.setEnabled(true);
                    guessInput.setEnabled(true);
                    playButton.setEnabled(false);
                    playerName.setEnabled(false);
                    gameTimer.start();
}
            }
        });
        guessButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int playerGuess = Integer.parseInt(guessInput.getText());
                if (gameNumbers.isGuessCorrect(playerGuess)) {
                    gameStatus.append("Game Over!n");
                    guessButton.setEnabled(false);
                    guessInput.setEnabled(false);
                    playButton.setEnabled(true);
                    playerName.setEnabled(true);
                    JOptionPane.showMessageDialog(gamePanel, "" + playerName.getText() + " wins!");
                }
                if (gameNumbers.isGuessAlmostCorrect(playerGuess)) {
                    gameStatus.append("very close!n");
                    guessInput.requestFocus();
                }
                if (gameNumbers.isGuessLarger(playerGuess)) {
                    gameStatus.append("try something smaller...n");
                    guessInput.requestFocus();
                }
                if (gameNumbers.isGuessSmaller(playerGuess)) {
                    gameStatus.append("try something larger...n");
                    guessInput.requestFocus();
                }
            }
        });
        game.pack();
        game.setVisible(true); 
    }
;
}
这是我的progressBar类:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.Timer;
class ProgressBar extends JPanel {
    public int minValue, maxValue;
    private int currentValue;
    public boolean running;
    private ArrayList<Rectangle> rects = new ArrayList<>();
    private int removeValue = 0;
    public ProgressBar() {
        setMaxValue();
        minValue = 0;
        this.running = true;
        currentValue = maxValue;
        this.setBackground(Color.green);
    }
    public void StartTimer() {
        setMaxValue();
        Timer progressBarCountDownTimer = new Timer(1000, new ActionListener() {
            int count = getMaxValue();
            @Override
            public void actionPerformed(ActionEvent ae) {
                if (getValue() == 0) {
                    setRunStatus(false);
                    ((Timer) ae.getSource()).stop();
                    System.out.println("YAY");
                    ;
                } else {
                    count--;
                    System.out.println(getValue());
                    setValue(count);
                }
                setValue(count);
            }
        });
        progressBarCountDownTimer.start();
    }
@Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        rects.clear();
        int rectWidths = getWidth() / getMaxValue();
        int startingX = 0;
        for (int i = 0; i < (getMaxValue() - removeValue); i++) {
            rects.add(new Rectangle(startingX, 0, rectWidths, getHeight()));
            startingX += rectWidths;
        }
        for (Rectangle r : rects) {
            g2d.setColor(Color.green);
            g2d.fillRect(r.x, r.y, r.width, r.height);
        }
    }
    public int getValue() {
        return currentValue;
    }
    public void setRunStatus(boolean running) {
        this.running = running;
    }
    public boolean getRunStatus() {
        if (this.running == true) {
            return true;
        } else {
            return false;
        }
    }
    public void setValue(int value) {
        int rem = value - currentValue;
        removeValue -= rem;
        currentValue = value;
        repaint();
    }
    public int getMaxValue() {
        return maxValue;
    }
    public void setMaxValue() {
        maxValue = RandomValues.integer(5, 20);
    }
}

这是我的猜谜游戏课():

public class GuessingGame {
    int minRange, maxRange, secretNumber;
    RandomValues randomValue;
    public GuessingGame() {
        randomValue = new RandomValues();
    }
    public int getMinRange() {
        return minRange;
    }
    public int getMaxRange() {
        return maxRange;
    }
    public void setMinRange() {
        this.minRange = randomValue.integer(1, 10);
    }
    public void setMaxRange() {
        this.maxRange = randomValue.integer(80, 100);
    }
    public int getSecretNumber() {
        return secretNumber;
    }
    public void setSecretNumber() {
         this.secretNumber = randomValue.integer(minRange, maxRange);
    }   
    public void play() {
        setMinRange();
        setMaxRange();
        setSecretNumber();
    }
    public boolean isGuessCorrect(int guess) {
        if (guess == this.secretNumber) {
            return true;
        } else {
            return false;
        }
    }
    public boolean isGuessAlmostCorrect(int guess) {
        if (guess >= this.secretNumber - 5 & guess <= this.secretNumber + 5 & guess != this.secretNumber) {
            return true;
        } else {
            return false;
        }
    }
    public boolean isGuessSmaller(int guess) {
        if (guess < this.secretNumber) {
            return true;
        } else {
            return false;
        }
    }
    public boolean isGuessLarger(int guess) {
        if (guess > this.secretNumber) {
            return true;
        } else {
            return false;
        }
    }
    @Override
    public String toString() {
        return String.format("Range: %d to %d answer: %d", getMinRange(), getMaxRange(), getSecretNumber());
    }
}

最后,这是一个简单的RandomValues类用于获取随机数

import java.util.Random;

public class RandomValues {
    public static int integer(int min, int max) {
        Random randomNum = new Random();
        int randomValue = randomNum.nextInt(max - min + 1) + min;
        return randomValue;
    }
}

我很抱歉,如果这是有点太长,但如果你做复制和粘贴它,它确实工作和加载它只是倒计时计时器部分只是似乎不想工作的方式,我想要它…如果有人能帮助我,我会永远爱他们:)

在您的gameTimerprogressBar.getRunStatus() == false时,您需要停止定时器…((Timer)ae.getSource()).stop();

现在…老实说,我不会麻烦的。

我会使用ChangeListenerPropetyListener之类的东西来提供来自ProgressBar的回调机制,其他类可以注册。这意味着反馈变得更加被动,而不是你目前正在经历的这种主动的"ping"过程。

基本上,这意味着您将为其他对象提供一种方法,以便在进度条状态更改时注册对通知感兴趣,并根据需要对该通知做出反应。

ProgressBar#paintComponent是…坦率地说……奇怪…

尝试画一个矩形来表示可用宽度的百分比,而不是…

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    int x = 0;
    int y = 0;
    int width = Math.round(getWidth() * (((float)getValue() / (float)getMaxValue())));
    g2d.setColor(Color.GREEN);
    g2d.fillRect(x, y, width, getHeight());
//            rects.clear();
//            int rectWidths = getWidth() / getMaxValue();
//            int startingX = 0;
//
//            for (int i = 0; i < (getMaxValue() - removeValue); i++) {
//                rects.add(new Rectangle(startingX, 0, rectWidths, getHeight()));
//                startingX += rectWidths;
//            }
//
//            for (Rectangle r : rects) {
//                g2d.setColor(Color.green);
//                g2d.fillRect(r.x, r.y, r.width, r.height);
//            }
}

我认为其中一个问题是你没有正确地停止你的计时器,而是让它们无意识地运行。

例如,在ProgressBar中,您总是在每次调用StartTimer时创建一个新的计时器。如果getValue()返回0,您尝试通过调用((Timer) ae.getSource()).stop();来停止它。我认为它不起作用,因为你有一个竞争条件,这个值实际上可能变成负值。所以stop永远不会被触发。

我建议将progressBarCountDownTimer存储为类的属性,并确保在启动新计时器之前正确停止它。我认为这更健壮。

相关内容

  • 没有找到相关文章

最新更新