0
votes

So I'm trying to program a handheld electronic game, called Lights Out Cube, in Java using Eclipse Oxygen.2, and I decided to include a timer so that the player knows how much time was required by him to finish the game. When the player clicks on a button called "Start/Reset"(I change its text to "Reset" after clicking it once), which is where I activate the timer, the game starts. After every click I check if player has finished the game, and if he does, I stop the timer. If he wishes to play again, I want the timer to restart. Please help me out here:

//here i have a function called checkIfWinning() which does the checking; if there is a winner, the following code is executed to stop the timer
            timer.cancel();
            timer.purge();
//timer is a publicly declared java.util.Timer
//this is a code snippet for btnStart with "time" recording the time in seconds 
time=0;
timer.schedule(new TimerTask()
            {
                @Override
                    public void run() 
                    {
                            time++;
                            int hours = (int) time / 3600;
                            int remainder = (int) time - hours * 3600;
                            int mins = remainder / 60;
                            remainder = remainder - mins * 60;
                            int secs = remainder;
                            timeTaken.setText(String.format("%02d:%02d:%02d",hours,mins,secs));
                    }

            }, 1000,1000);

Is there anyway this can be done? Or will I have to remove the timer entirely?

2
You can just cancel your current TimerTask and then submit a new one. To be able to cancel it, you need to keep a reference to the task somewhere. See also the alternative approach of using a ScheduledExecutorService instead, which is similar to the Timer but more flexible.Hulk
Perhaps I'm missing something very obvious, but why do you need this Timer at all? Can't you just record the time the user starts, and the time they finish, and subtract one from the other?DaveyDaveDave

2 Answers

1
votes

You can't reset when the TimerTask object will be activated, but in your specific case, you can reset the game time count without removing and recreating the timer.

Since your timer is fired every second, all you have to do is reset the time variable you are using, when the user clicks the reset button.

I am editing this answer based on Hulks and your comments:

  1. Hulk is right, and you should use AtomicInteger for your time count. If you keep the timer running, there could be a bug some times where the value will not reset.

  2. You can have an AtomicBoolean flag that lets the TimerTask know if the player is playing or not.

Here is a code example:

AtomicInteger time = new AtomicInteger();
//whenever you want to reset it:
time.set(0);

AtomicBoolean isPlaying = new AtomicBoolean();

//when user clicks "start":
isPlaying.set(true);
//when user wins or clicks "reset"
isPlaying.set(false);

//your timer task will look something like this:
public void run() {
    if (isPlaying.get()) {
        int currentTime = time.incrementAndGet();
        int hours = (int) currentTime / 3600;
        int remainder = (int) currentTime - hours * 3600;
        int mins = remainder / 60;
        remainder = remainder - mins * 60;
        int secs = remainder;
        timeTaken.setText(String.format("%02d:%02d:%02d",hours,mins,secs));
    }
}
0
votes

This might be clear.

  1. You can't reset or pause the Timer in Java, but the functionality can be achieved by not running the Timer based on a boolean check.

  2. As previously said by Hulk and Lev.M, AtomicInteger can be used in need of thread safety.

  3. Whole logic in run() can be simplified using TimeUnit for converting seconds to the specified format,

    time+=1000;
    System.out.println(String.format("%02d:%02d:%02d", TimeUnit.SECONDS.toHours(time), TimeUnit.SECONDS.toMinutes(time), time%60));
    

import java.util.Timer;
import java.util.TimerTask;

public class Game
{
    private static int time = 0;
    private static Timer t = new Timer();
    private static Game g;
    private static boolean ispaused = false;

    public static void main(String[] args)
    {
        t.schedule(new TimerTask() {
            public void run()
            {
                if(ispaused)
                {
                    return;
                }
                time++;
                System.out.println(String.format("%02d:%02d:%02d", TimeUnit.SECONDS.toHours(time), TimeUnit.SECONDS.toMinutes(time), time%60));
            }
        }, 1000, 1000);

        g = new Game();

        try
        {
            System.out.println("Starting first game");

            g.startGame(); Thread.sleep(5000); g.endGame();

            System.out.println("Starting second game.");

            g.startGame(); Thread.sleep(5000); g.endGame();
        }
        catch(Exception e)
        {}
    }

    private void startGame()
    {
        time = 0;
        ispaused = false;
        System.out.println("Game Started");
    }

    private void endGame()
    {
        time = 0;
        ispaused = true;
        System.out.println("Game ended");
    }
};