Using Javascript to Gamify a Countdown Timer (incorrect answers subtract time)

Apr 18, 2024

Hi all, 

Appreciate your help looking into this. What I am trying to do is gamify an activty where there is a countdown where the learner has to type in the correct response before the time runs out AND there is consequences to writing incorrect answers by subtracting the time. 

I have the timer all set up with no issues via Javascript. Since the variable timer is updated via a trigger, the Javascript needs to also have a function that retrieves the existing value of the variable timer because, it sets the value of the variable timer based on the internal variable "sec". Since "sec" isn't affected by the update of the variable timer via the trigger on the incorrect layer, it won't retrieve it and will just continue with the count based on sec.

How can I modify the variable so Javascript subtracts from the time and then continues counting down?

Here is the code for the timer: 

 //Getting the player
const player = GetPlayer();

//Where to start
let sec = 60;

//Set up the timer
function startTimer(){
  sec -= 1;
  player.SetVar("timer",sec);
  if (sec == 0) {
    clearInterval(timerId);
  }
}

//Start the timer
timerId=setInterval(startTimer,1000);

*While there are ways to do it via the timeline & master slides/layers, if you have different layers it messes with the timer so I need a Javascript solution

7 Replies
Nedim Ramic

Hi Maddie,

Although I sometimes prefer solving problems using JavaScript, this time I decided to take a different approach just for fun and to demonstrate that it's possible to achieve this using Storyline alone. Please check out my short video demonstrating this concept, and let me know if you're interested in incorporating it into your project. If you're interested, I can provide my .story file for you to rebuild and customize as necessary.

John Cooper

But if you want to stick with JavaScript, I think you just need to retrieve the current value of the timer variable from Storyline each time before you update it.

Putting a line:

let sec = player.GetVar("timer");

Before you decrement the timer would be my initial thought, but I haven't tried it - so other changes might be needed. But the above would allow you to decrement the timer outside of the function (due to an incorrect answer) and still allow the countdown to work.

Hope that helps

John

Andrew Hanley

@John's reply is how I would handle it too.

With one addition perhaps, which is you will need to set up a new JS function which retrieves the timer value at any given moment. This function is necessary because Im guessing you have your JS trigger currently on a slide that Storyline stays on throughout.
Either way, you will need a trigger that is not constant (ie. part of the Interval ticks) in order to return the value.
So... 1 trigger counts down, while a different trigger returns values.

Nedim Ramic

Below is a JavaScript code. It assumes that another variable named "incorrect" is created within Storyline, initialized with a value of false. This variable switches to true when the timeline starts on the "Try Again" layer. In the code, it is switched back to false as soon as 10 seconds are subtracted from the timer. Maddie, this code may need constant updates based on your final scenario interaction and as the project scales. That's why I preferred Storyline alone over JavaScript, allowing those without JavaScript experience to easily update and progress. Attached is a short video demonstration of your revised project, along with the .story file for reference.

const player = GetPlayer();
let sec = player.GetVar("timer");

//Set up the timer
function startTimer(){
  if (sec > 0) {
    if (player.GetVar('incorrect')) {
      if (sec < 10) { // Check if remaining time is less than 10 seconds
        sec = 0; // Set timer to 0 if less than 10 seconds remaining
      } else {
        sec -= 10;
      }
      player.SetVar('incorrect', false); // Set incorrect to false after subtracting 10 seconds
    } else {
      sec -= 1;
    }
    player.SetVar("timer", sec);
    if (sec <= 0) {
      clearInterval(timerId);
    }
  }
}

//Start the timer
let timerId = setInterval(startTimer, 1000);


Please set the timer value to 60 in Storyline and remove the trigger that subtracts 10 seconds from the timer, as it is now managed with JavaScript.