Licznik czasu

0

Witam, potrzebuję wykonać i zaimplementować do gry licznik czasu, aby zliczał mi od 60s do 0 (wyświetlał na bieżąco na ekranie) i po osiągnięcia 0s przerywał grę.
Ściągnąłem jakąś funkcję z Internetu i przerobiłem do swoich potrzeb:

private void liczCzas () {
            Ustawienia.startTime = System.currentTimeMillis();
            long currTime = Ustawienia.startTime;

            while (currTime - Ustawienia.startTime < Ustawienia.GAME_TIME) {
                long elapsedTime = System.currentTimeMillis() - currTime;
                //licz czas gry - może się przydać w ograniczeniach czasowych 
                //w tej demonstracji nie wykorzystane
                currTime += elapsedTime;
                Ustawienia.actualTime = 60-((currTime-Ustawienia.startTime)/1000);
                repaint();
                
                try {
            Thread.sleep(80);
          } catch (InterruptedException ex) {System.out.println("Wyjątek: "+ex);      }
                }

Gdy dodaję linijkę wywołania funkcji i uruchamiam grę, to przez 60s nic się nie dzieje, a po tym czasie uruchamia się gra i na ekranie widzę napis: POZOSTAŁY CZAS: 0.0s.
Czyli widać, że licznik sam w sobie dobrze działa, ale w złym miejscu jest wywoływany.

Jest jakieś inne rozwiązanie?
Stworzyć nową klasę dla licznika i potem wywołać obiekt tej klasy w oknie gry?
Proszę o pomoc.

1
MartinTcV napisał(a):

Jest jakieś inne rozwiązanie?

Jest milion innych rozwiązań, z czego około 90% będzie na pewno lepszych:) 60s pętla w pętli nie należy do tych najlepszych:)

3

Chyba najprościej, to wykorzystać Timer.

0

Jakieś podpowiedzi jak to wykonać, bo jestem niemal zielony?

0

Timer jest z pakietu javax.swing.

        Timer timer = Timer(1000,new ActionListener()
        {
            int time = 60;
            public void actionPerformed(ActionEvent ae)
            {
                System.out.println("Pozostały czas w sekundach: "+time);
                if (time == 0)
                {
                    System.exit(0);
                }
                time--;
            }
        });
        timer.setInitialDelay(0);
        timer.start();
0

Stworzyłem w klasie, której używam metodę liczCzas(), wrzuciłem tam zamieszczony przez Ciebie wyżej kod i po kliknięciu buttona Nowa Gra wywołuję tę metodę oraz metodę nowaGra, gra się resetuje, ale nie zlicza mi czasu i nie wypisuje w konsoli. Co robię źle?

0

Takie coś masz?

private void liczCzas () {
 Timer timer = Timer(1000,new ActionListener()
        {
            int time = 60;
            public void actionPerformed(ActionEvent ae)
            {
                System.out.println("Pozostały czas w sekundach: "+time);
                if (time == 0)
                {
                    System.exit(0);
                }
                time--;
            }
        });
        timer.setInitialDelay(0);
        timer.start();
}
0

Dokładnie tak.

1

A jak uruchamiasz grę? Masz otwartą konsolę?

0

Używam NetBeans i konsola jest w tle, tam się nic nie wyświetla.

1

To znaczy, że nie uruchamiasz timera. Pokaż kod, który Twoim zdaniem uruchamia timer.

0
    public Gra(int szerokosc, int wysokosc) {
        setSize(szerokosc,wysokosc);
        setLayout(null);
        
        addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent me)
            {
                if (me.getX()>=860 && me.getX()<=1000 && me.getY()>=525 && me.getY()<=555)
                {
                    int odp = JOptionPane.showConfirmDialog(null, "Czy na pewno chcesz rozpocząć nową grę?");
                    if (odp==JOptionPane.YES_OPTION)
                    {
                        gStatus.nowaGra();
                        repaint();
                        liczCzas();
                    }
                }
            }
            });
    }

    protected void paintComponent(Graphics gs){
        ....
    }

            private void liczCzas () {
            Timer licznik = Timer(1000, new ActionListener() {
                int time=60;
                @Override
                public void actionPerformed(ActionEvent e) {
                System.out.println("Pozostały czas w sekundach: "+time);
                if (time == 0)
                {
                    System.exit(0);
                }
                time--;
                }
                
            });
            licznik.setInitialDelay(0);
            licznik.start();
    
        }

    private Timer Timer(int i, ActionListener actionListener) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

Coś takiego mam, nie wiem co jest nie tak, że nie liczy.

1

Sorry,

            private void liczCzas () {
            Timer licznik = new Timer(1000, new ActionListener() {
                int time=60;
                @Override
                public void actionPerformed(ActionEvent e) {
                System.out.println("Pozostały czas w sekundach: "+time);
                if (time == 0)
                {
                    System.exit(0);
                }
                time--;
                }
 
            });
            licznik.setInitialDelay(0);
            licznik.start();

a kod

    private Timer Timer(int i, ActionListener actionListener) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

usuń.
Poza tym, ja chyba źle zrozumiałem zwrot przerywał grę. Uznałem, że przerywać grę znaczy kończyć program. Jeśli jest inaczej, to wiersz

System.exit(0);

trzeba będzie czymś zastąpić.

0

No tak, z tym się już pobawię jak stopniowo będę rozwijał grę. Dzięki wielkie za pomoc, działa w 100%.

Jeszcze jedna kwestia. Chciałbym wyświetlać ten czas za pomocą metody paint, jak mogę przesłać wartość zmiennej time, aby wyświetlić jej wartość wykorzystując metodę drawString?

1

Zrób ze zmiennej time pole w klasie z oknem graficznym.

    private int time;
...

            private void liczCzas () {
            Timer licznik = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                repaint();
                if (time == 0)
                {
                    //koniec gry;
                }
                time--;
                }
 
            });
            time = 60;
            licznik.setInitialDelay(0);
            licznik.start();

A w metodzie paintComponent dopisz

g.drawString(""+time,...);
0

Dzięki wielkie, działa tak jak trzeba. Dodałem jeszcze do metody painComponent

g.clearRect(...);

i jest miodzio.
Pozdrawiam!

1 użytkowników online, w tym zalogowanych: 0, gości: 1