-3

我想知道是否有人可以查看我的代码,该代码正在运行,因此您可以复制并测试它。我的问题是当底部栏倒计时到结束时,它应该结束游戏,然后从头开始。但我认为我遗漏了一些代码,或者我的代码没有正确编写来做我想做的事情。任何人都可以查看它并查看我哪里出错了?

这是带有所有 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); 
    }
;
}

这是我的进度条类:

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;
    }
}

很抱歉,如果这有点太长了,但是如果您复制并粘贴它,它确实可以工作并加载它只是倒数计时器部分似乎不想按我想要的方式工作.. . 如果有人可以帮助我,我会永远爱他们 :)

4

2 回答 2

2

在你的gameTimer时候progressBar.getRunStatus() == false,你需要停止计时器......((Timer)ae.getSource()).stop();

现在……老实说,我不会打扰。

我会使用类似ChangeListeneror的东西PropetyListener来提供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);
//            }
}
于 2012-12-29T03:56:08.203 回答
1

我认为问题之一是您没有正确停止计时器,而是无意中继续运行。

例如,ProgressBar您总是在每次调用StartTimer. ((Timer) ae.getSource()).stop();如果返回 0 ,您尝试通过调用来停止它。getValue()我认为它不起作用,因为您有竞争条件并且该值实际上可能变为负数。所以永远不会触发停止。

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

于 2012-12-29T04:05:20.077 回答