Swing - таймер не останавливается, когда игра на память заканчивается - PullRequest
0 голосов
/ 13 октября 2018

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

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.*;
import java.util.Collections;
import java.util.Calendar;
import java.time.*;

public class MemoryGame extends JToggleButton implements ActionListener {

private Timer cdTimer;
private Timer swTimer;

private int count = 0;
private long start;
private long begin = Calendar.getInstance().getTimeInMillis();

private JToggleButton[] buttons;
private JToggleButton last;
private JLabel time;
//private String[] commandID = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"};
ArrayList<ImageIcon> iconList = new ArrayList();
ArrayList<JToggleButton> retireButton = new ArrayList();
ImageIcon icon = new ImageIcon("MemoryGame.png");


public MemoryGame() {
    JFrame jfrm = new JFrame("Memory Game");

    jfrm.setSize(1000, 1000);

    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    jfrm.setIconImage(icon.getImage());

    time = new JLabel("Elapsed time is 00:00:00");

    GridLayout layout = new GridLayout(3,4);

    JPanel gamePanel = new JPanel();
    gamePanel.setLayout(layout);

    createIcons();

    buttons = new JToggleButton[12];

    for(int i = 0; i < buttons.length; i++) {
        JToggleButton btn = new JToggleButton(icon);

        buttons[i] = btn;

        //buttons[i].setActionCommand(commandID[i]);

        buttons[i].addActionListener(this);

        gamePanel.add(buttons[i]);   
    }

    //Collections.shuffle(Arrays.asList(buttons));
    //Collections.shuffle(iconList);

    jfrm.add(gamePanel, BorderLayout.CENTER);
    time.setHorizontalAlignment(JLabel.CENTER);
    time.setVerticalAlignment(JLabel.CENTER);
    jfrm.add(time, BorderLayout.NORTH);

    jfrm.setLocationRelativeTo(null);

    jfrm.setVisible(true);
}

public void actionPerformed(ActionEvent e){

    timerStart();

    JToggleButton btn = (JToggleButton)e.getSource();

    setIcon(btn);
    if(last == null){
        last = btn;
        return;
    }

    matching(btn, last);

    last = null;

}

public void updateTime(){
    long temp = Calendar.getInstance().getTimeInMillis();
    time.setText("Elapsed time is " + formatTime((long) (temp - begin)) + "-"+retireButton.size());
}

public static String formatTime(long ms){
    long millis = ms % 1000;
    long x = ms / 1000;
    long seconds = x % 60;
    x /= 60;
    long minutes = x % 60;
    x /= 60;
    long hours = x % 24;

    return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}

private void timerStart(){
    ActionListener timerAL = new ActionListener(){
        public void actionPerformed(ActionEvent e){
            updateTime();
        }
    };
    swTimer = new Timer(1000, timerAL);
    swTimer.start();
}

private void timerStop(){
    if(retireButton.size() == 12){
        long stop = Calendar.getInstance().getTimeInMillis();
        time.setText("Elapsed time is " + formatTime((long)(stop-begin)));
        swTimer.stop();
    }
}
private void setIcon(JToggleButton btn) {
    if(btn == buttons[0] || btn == buttons[1])
        btn.setIcon(iconList.get(0)); 

    else if(btn == buttons[2] || btn == buttons[3])
        btn.setIcon(iconList.get(1));

    else if(btn == buttons[4] || btn == buttons[5])
        btn.setIcon(iconList.get(2));

    else if(btn == buttons[6] || btn == buttons[7])
        btn.setIcon(iconList.get(3));

    else if(btn == buttons[8] || btn == buttons[9])
        btn.setIcon(iconList.get(4));

    else if(btn == buttons[10] || btn == buttons[11])
        btn.setIcon(iconList.get(5));
}

private void matching(JToggleButton btn, JToggleButton btn2){
    if(btn.isSelected()){
        if(btn2.isSelected()){
            buttonDisable(btn, btn2);
            if(!btn.getIcon().toString().equals(btn2.getIcon().toString())){
                startTime(1, btn, btn2);
            }
            else {
                retirePair(btn, btn2);
                timerStop();
                buttonEnable(btn, btn2);
            }
        }
    }   
}

private void startTime(int countPassed, JToggleButton btn, JToggleButton btn2){
    ActionListener action = new ActionListener(){
        public void actionPerformed(ActionEvent e){
            if(count == 0){
                cdTimer.stop();
                unflipPair(btn, btn2);
                buttonEnable(btn, btn2);
            }
            else
                count--;
            }

    };
    cdTimer = new Timer(500, action);
    cdTimer.start();
    count = countPassed;
}

private void buttonEnable(JToggleButton btn, JToggleButton btn2){
    if(retireButton.isEmpty()){
        for(int i = 0; i < buttons.length; i++){
            if(buttons[i] != btn && buttons[i] != btn2)
                buttons[i].setEnabled(true);
        }
    }    
    else{
        for(int i = 0; i < buttons.length; i++){
            for(int j = 0; j < retireButton.size(); j++){        
                if(buttons[i] != btn && buttons[i] != btn2 && buttons[i] != retireButton.get(j))
                    buttons[i].setEnabled(true);
            }   
        }
    }
}

private void buttonDisable(JToggleButton btn, JToggleButton btn2){
    for(int i = 0; i < buttons.length; i++){
        if(buttons[i] != btn && buttons[i] != btn2)
            buttons[i].setEnabled(false);
    }
}
private void unflipPair(JToggleButton btn, JToggleButton btn2){
    btn.setIcon(icon);
    btn2.setIcon(icon);
    btn.setEnabled(true);
    btn2.setEnabled(true);
    btn.setSelected(false);
    btn2.setSelected(false);
}

private void retirePair(JToggleButton btn, JToggleButton btn2){
    btn.setEnabled(false);
    btn2.setEnabled(false);
    btn.setSelected(true);
    btn2.setSelected(true);
    retireButton.add(btn);
    retireButton.add(btn2);
}

private void createIcons(){
    ImageIcon icon1 = new ImageIcon("1.png");
    ImageIcon icon2 = new ImageIcon("2.png");
    ImageIcon icon3 = new ImageIcon("3.png");
    ImageIcon icon4 = new ImageIcon("4.png");
    ImageIcon icon5 = new ImageIcon("5.png");
    ImageIcon icon6 = new ImageIcon("6.png");

    iconList.add(icon1);
    iconList.add(icon2);
    iconList.add(icon3);
    iconList.add(icon4);
    iconList.add(icon5);
    iconList.add(icon6);
}

Итак, я создал массив списков кнопок вывода.Условие, которое я установил для остановки таймера, состоит в том, что если список массивов размера кнопок удаления достигает 12 (что является общим количеством кнопок в игре), таймер останавливается;однако, это только продолжает идти.Я не то, что я делаю неправильно.Пожалуйста, помогите спасибо.

1 Ответ

0 голосов
/ 13 октября 2018

Вот проблема, которую я вижу - вы создаете лот экземпляров Timer, вы помещаете их в переменную swTimer, но пытаетесь остановить только последний, пока все остальные продолжаютзапустить.Одно из возможных решений - прежде чем создавать новый экземпляр Timer, посмотрите, запущен ли он в данный момент, и если это так, остановите его.

Например,

private void timerStart() {
    ActionListener timerAL = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            updateTime();
        }
    };
    // check if swTimer is not null and is currently running
    if (swTimer != null && swTimer.isRunning()) {
        swTimer.stop(); // !! if so STOP it!
    }
    swTimer = new Timer(1000, timerAL);
    swTimer.start();
}

Но сказав это, выдействительно нужно создать все эти новые экземпляры Timer?Не сработает ли один экземпляр, запущенный, когда нажата первая кнопка, и остановлен только после окончания игры?

Побочные проблемы (не связанные с рассматриваемой проблемой):

  • Это не принадлежит: MemoryGame extends JToggleButton.Игра определенно не является JToggleButton, и поэтому вам не нужно, чтобы класс расширял этот класс.
  • Ваша игровая логика запутана, ее сложно проверить, и она может быть немного неработоспособна.Лучше всего отделить логику от графического интерфейса пользователя, чтобы вы могли независимо протестировать ее с помощью батареи тестов, отличных от графического интерфейса, чтобы убедиться, что она работает правильно.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...