Java, таймер обратного отсчета для 15 головоломок? Помогите мне понять таймеры, пожалуйста - PullRequest
0 голосов
/ 29 октября 2019

Прежде чем я начну, я хочу объяснить, что я смотрел на многие другие вопросы, подобные этому, и на множество видео в сети, но ни один из них не помогает мне понять, как работает таймер или как я собираюсь создать его для себя, надеюсь,никто не думает, что это ненужный пост.

Я не понимаю, например, для чего используется задержка, я хотел бы узнать все о таймерах и как они используются.

Так что я 'Я создал 15 головоломок, игра завершена, но я хотел добавить еще одну функцию.

Таймер, который отображается на JLabel. Особенности:

  1. Таймер отсчитывает от 5 до 10 минут.
  2. Требуемый формат для таймера "мм: сс".
  3. Как только первая кнопка нажатапри нажатии таймер начинает обратный отсчет.
  4. Если решить до того, как таймер истечет, вы выиграете, в противном случае вы проиграете.
  5. Если вы нажмете кнопку «Новая игра», она сбрасывается на 5 или 10 минут. .
  6. И обратный отсчет начинается снова, как только вы нажимаете первую кнопку в игре.

Мне бы очень хотелось, если бы вы могли объяснить, для чего используются параметры и какой таймер Iследует использовать для моего случая. Также я использую java swing.

Вот моя игра, если вам интересно:

class GameLogic extends JFrame implements ActionListener {

private JPanel grid = new JPanel();
private JPanel overHead = new JPanel();
private JButton newGameButton = new JButton("NEW GAME");
private JButton[][] buttons = new JButton[4][4];
private JButton[][] winPattern = new JButton[4][4];
private JButton button0 = new JButton("");
private JLabel timerLabel = new JLabel("TIMER");
private int emptyIndex;
private int sourceIndex;
private int sourceRow;
private int sourceCol;
private int blankRow;
private int blankCol;
private int movesCounter = 0;
private JLabel movesLabel = new JLabel("MOVES");

public GameLogic() {
    setLayout(new BorderLayout());
    add(overHead, BorderLayout.NORTH);
    overHead.setLayout(new BorderLayout());
    overHead.add(newGameButton, BorderLayout.WEST);
    overHead.add(movesLabel, BorderLayout.EAST);
    overHead.add(timerLabel, BorderLayout.CENTER);
    movesLabel.setFont(new Font("Street Cred", Font.PLAIN, 20));
    newGameButton.setPreferredSize(new Dimension(100, 50));
    newGameButton.setFont(new Font("Street Cred", Font.PLAIN, 13));
    overHead.setBorder(new EmptyBorder(50, 50, 10, 50));
    grid.setBorder(new EmptyBorder(50, 50, 50, 50));
    newGameButton.addActionListener(this);
    add(grid, BorderLayout.CENTER);
    setBackground(Color.RED);
    grid.setLayout(new GridLayout(4, 4));
    try {
        GraphicsEnvironment ge =
                GraphicsEnvironment.getLocalGraphicsEnvironment();
        ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("street cred.ttf")));
    } catch (IOException | FontFormatException e) {
        //Handle exception
    }
    int i = 1;
    for (int row = 0; row < buttons.length; row++) {
        for (int col = 0; col < buttons.length; col++) {
            if (row == 3 && col == 3) {
                buttons[row][col] = button0;
                grid.add(buttons[row][col]);
                buttons[row][col].setBackground(Color.WHITE);
                buttons[row][col].setName("button0");
                winPattern[row][col] = button0;
            } else {
                buttons[row][col] = new JButton(i + "");
                grid.add(buttons[row][col]);
                buttons[row][col].addActionListener(this);
                buttons[row][col].setBackground(Color.RED);
                buttons[row][col].setName("button" + i);
                buttons[row][col].setFont(new Font("Street Cred", Font.PLAIN, 40));
                winPattern[row][col] = buttons[row][col];
                i++;
            }
        }
    }

    do {
        shuffle();
    } while (!isSolvable());
    try {
        setIconImage(ImageIO.read(new File("C:\\Users\\Allan\\Documents\\Nackademin\\OOP\\test2\\icon.png")));
    } catch (IOException e) {
        e.printStackTrace();
    }
    movesLabel.setText("<html>MOVES<br><html>" + "----- " + movesCounter + " -----");
    setTitle("PUZZLE GAME");
    setCursor(new Cursor(Cursor.HAND_CURSOR));
    setResizable(false);
    setLocation(500, 200);
    setSize(600, 600);
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public boolean isSolvable() {
    int inv_counter = 0;
    int[] values = new int[16];
    // Lägger alla komponenters nummer i en int array
    for (int i = 0; i < grid.getComponents().length; i++) {
        if (grid.getComponents()[i] == button0) {
            values[i] = 0;
        } else {
            JButton temp = (JButton) grid.getComponents()[i];
            values[i] = Integer.parseInt(temp.getText());
        }

    }

    for (int i = 0; i < values.length - 1; i++) {
        for (int j = i + 1; j < values.length; j++) {
            if (values[i] < values[j]) {
                inv_counter++;
            }
        }
    }

    return inv_counter % 2 == 0;
}


public boolean isSwappable(JButton button) {

    // för att hitta platsen på knappen man trycker och även den blanka platsen
    for (int row = 0; row < buttons.length; row++) {
        for (int col = 0; col < buttons.length; col++) {
            if (buttons[row][col] == button) {
                sourceRow = row;
                sourceCol = col;
            } else if (buttons[row][col] == button0) {
                blankRow = row;
                blankCol = col;
            }
        }
    }
    sourceIndex = (sourceRow * 4) + sourceCol;
    emptyIndex = (blankRow * 4) + blankCol;
    // om den är till höger
    if (sourceCol != 3 && sourceRow == blankRow && buttons[sourceRow][sourceCol + 1] == button0) {
        return true;
    }
    // om den är till vänster
    else if (sourceCol != 0 && sourceRow == blankRow && buttons[blankRow][sourceCol - 1] == button0) {
        return true;
    }
    //om den är nedanför
    else if (sourceRow != 0 && sourceCol == blankCol && buttons[sourceRow - 1][sourceCol] == button0) {
        return true;
    }
    //om den är ovanför
    else if (sourceRow != 3 && sourceCol == blankCol && buttons[sourceRow + 1][sourceCol] == button0) {
        return true;
    }
    return false;
}

public void swap(JButton source) {
    JButton tempButton = buttons[sourceRow][sourceCol];
    buttons[sourceRow][sourceCol] = buttons[blankRow][blankCol];
    buttons[blankRow][blankCol] = tempButton;
    grid.remove(button0);
    grid.remove(source);

    if (emptyIndex < sourceIndex) {
        grid.add(source, emptyIndex);
        grid.add(button0, sourceIndex);
    } else if (emptyIndex > sourceIndex) {
        grid.add(button0, sourceIndex);
        grid.add(source, emptyIndex);
    }
    revalidate();
    repaint();
}

public void shuffle() {
    Random random = new Random();

    //randomize positions for 2D array buttons
    for (int row = 0; row < buttons.length; row++) {
        for (int col = 0; col < buttons.length; col++) {
            int randomNumber = random.nextInt(16);
            int randomRow = randomNumber / 4;
            int randomCol = randomNumber % 4;
            JButton temp = buttons[row][col];
            buttons[row][col] = buttons[randomRow][randomCol];
            buttons[randomRow][randomCol] = temp;
        }
    }
    //remove all components from panel
    grid.removeAll();

    // add components with randomized position to panel
    for (int row = 0; row < buttons.length; row++) {
        for (int col = 0; col < buttons.length; col++) {
            grid.add(buttons[row][col]);
        }
    }
    revalidate();
    repaint();
}

public boolean isSolved() {
    int counter = 0;
    for (int row = 0; row < buttons.length; row++) {
        for (int col = 0; col < buttons.length; col++) {
            if (winPattern[row][col].getText().equals(buttons[row][col].getText())) {
                counter++;
            }
        }
    }
    if (counter == 16) {
        return true;
    } else {
        return false;
    }
}

public void moves() {
    movesCounter++;
    movesLabel.setText("<html>MOVES<br><html>" + "----- " + movesCounter + " -----");
}

public void timerCountDown() {
}

public void reset() {
    movesCounter = 0;
    movesLabel.setText("<html>MOVES<br><html>" + "----- " + movesCounter + " -----");
}

public void newGame() {
    do {
        shuffle();
        reset();
    } while (!isSolvable());
}

@Override
public void actionPerformed(ActionEvent e) {
    JButton source = (JButton) e.getSource();

    if (source == newGameButton) {
        newGame();
    } else if (isSwappable(source)) {
        swap(source);
        moves();
    }

    if (isSolved()) {
        JOptionPane.showMessageDialog(null, "YOU BEAT THE GAME!\nMoves: " + movesCounter + "\nTime: ");
        newGame();
    }
}
}

1 Ответ

0 голосов
/ 29 октября 2019

Вы можете использовать ScheduledExecutorService (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html)

. Они позволяют вам запускать задание (в вашем случае, таймер) в определенный момент и повторять задание после заданной задержки.

Чтобы создать свой ScheduledExecutorService:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

Затем вам нужно запустить задачу, включая задержку и период:

ScheduledFuture<?> handler = scheduler.scheduleAtFixedRate(yourTask, 0, 1, TimeUnit.SECONDS);

«yourTask» - это Runnable. используйте лямбду, такую ​​как () -> System.out.println("BEEP") или ссылку на метод, такую ​​как this::run, с методом запуска, который будет отображать на экране время. У вас может быть два поля minutes и seconds, изначально установленных на 5 и 0 (или 10 и 0 из вас хотят 10 минут * Вызывается метод 1018 * run`, затем отображается на экране правильное время:

private void run(){
    seconds--;
    if(seconds < 0) {
        minutes--;
        seconds = 59;
    }
    displayTimeOnScreen();

    if(minutes == 0 && seconds == 0) {
        handler.cancel(true);
    }
}

Вы можете использовать handler.cancel(true), чтобы остановитьзадание.

...