eoinzy
eoinzy

Reputation: 2242

Processing P5 - Timer issue with millis()

I am making a little game in Processing which is similar to those Guitar Hero style games and I am trying to do 2 things:

  1. When the game loads, stop the time from moving
  2. During the game, allow for Pause functionality

Now, I know I cant stop the time since the millis() returns the milliseconds since the application launched, so my timer will need to be millis() - millis() at the start to equal zero, so when the user presses START, they can obviously start at the start. The game reads a file at the start, similar to a subtitles file, that has the note to be played and the time in milliseconds that it should appear on screen.

My problem is, when I pause the game, the timer keeps going and when I unpause the game, all the notes get "bunched up" due to my logic, as you'll see from my code.

Can someone suggest a better algorithm than the one I'm using? Its late and I've been working on this all day and night. I think the problem is with the for() below:

public void draw()
{
    if (gameInProgress)
    {
        currentTimerValue = millis(); // Update the timer with the current milliseconds
        // Check to see if the note times falls between the current time, or since the last loop (difficult to match exact millisecond)
        for(int i=0 ; i<songNotes.length ; i++)
        {
             if( songNotes[i].getStartTime() > previousTimerValue && songNotes[i].getStartTime() <=currentTimerValue)
                notes.add(songNotes[i]);
        }

        noStroke();
        textFont(f,18);
        drawButtons();  //Draws coloured buttons relating to Button presses on the controller
        drawHighScoreBox(); // Draws high score box up top right
        drawLines();  // Draws the strings
        moveNotes();  // Moves the notes across from right to left
        //Now set the cutoff for oldest note to display
        previousTimerValue=currentTimerValue;  //Used everytime on the following loop
    }
    else
    {
        drawMenu(); // Draw the Main/Pause menu
    }
}

NOTE: The boolean gameInProgress is set below when the users presses the pause button, eg "P", and songNotes is an array of objects of type Note that I wrote myself. It has 2 member variables, noteToBePlayed and timeToBePlayed. The method getStartTime()returns timeToBePlayed which is a millisecond value.

Any help is appreciated. Thanks

Upvotes: 0

Views: 2282

Answers (2)

George Profenza
George Profenza

Reputation: 51867

How about having another integer to store time when you pause and use that to offset the game timer ?

So, in 'gameInProgress' mode you update currentTimerValue and previousTimerValue and in 'paused/menu' mode you update a pausedTimerValue, which you use to offset the 'currentTimerValue'. I hope this makes sense, it sounds more complicated in words, here's what I mean:

boolean gameInProgress = true;
int currentTimerValue,previousTimerValue,pausedTimerValue;
void setup(){

}
void draw(){
  if(gameInProgress){
    currentTimerValue = millis()-pausedTimerValue;
    println("currentTimerValue: " + currentTimerValue + " previousTimerValue: " + previousTimerValue);  
    previousTimerValue=currentTimerValue;
  }else{
    pausedTimerValue = millis()-currentTimerValue;
  }
}
void mousePressed(){
  gameInProgress = !gameInProgress;
  println("paused: " + (gameInProgress ? "NO" : "YES"));
}

Click the sketch to toggle modes and look in the console for times. You'll notice that you only loose a few millis between toggles, which is acceptable.

Upvotes: 3

mishadoff
mishadoff

Reputation: 10789

Use not system timer but special timer class with pause functionality. I'm sure it is not hard to implement such class by yourself. I know that java has Timer class but unfortunately it not support pause functionality.

Upvotes: 0

Related Questions