1

I have the following script in a js file:

// Ad score
var score = 0;
//$('#score').text(score);
function foundMatchingBlocks(event, params) {
      params.elements.remove();
      score += 100;
      $('#score').text(score);
};

Now on each matching, 100 points are added to var score. This all works. Now I want to extend this a bit. As soon as the page loads I want to start a countdown to reduce the number of points (starting with 100) with 1 point a second for 60 seconds. So the minimum number of points a user can get is 40. When someone gets the points, the counter should reset and countdown again.

Example:

  1. Page loads (timer starts from 100)
  2. User has a match after 10 seconds (+90 points are added)
  3. Counter resets and countdown from 100 again
  4. User found a match after 35 sec (+65 points are added)
  5. etc etc

Problem is, I have no idea how to do this :( Hope someone can help me with this.

The above is fixed, thanks all for helping!!!

Maurice
  • 1,147
  • 2
  • 21
  • 49

3 Answers3

3

The big picture is, you'll need to become pretty familiar with timeouts and intervals in javascript. This is the reference page I keep going back to when I need to refresh my memory: http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/

For your specific task, you'll probably want to use an Interval that triggers every 1000 milliseconds to calculate the second-by-second point reduction, and a separate Timeout for failure that resets every time the user completes their challenge.

Here are a few tips for working with timeouts and intervals that usually lead to followup questions:

When you set a timeout, always capture the return value (I think it's basically a random integer). Save it to some global var for convenience.

var failureTimer; // global var high up in your scope

failureTimer = setTimeout ( "gameOver()", 100000 ); // 100 seconds * 1000ms

Then in whichever method gets called when the player completes their challenge, you call this:

clearTimeout (failureTimer); // resets the timer and gives them another 100 seconds

failureTimer = setTimeout ( "gameOver()", 100000 ); // yes call this again, to start the 100 sec countdown all over again.

The second pain point you're likely to encounter when working with Timeouts and Intervals is how to pass parameters to the functions like gameOver() in my example above. You have to use anonymous functions, as described here:

Pass parameters in setInterval function

For more on anonymous functions, this is a good overview:

http://helephant.com/2008/08/23/javascript-anonymous-functions/

Good luck with your project! Let me know if you have any questions.

Community
  • 1
  • 1
ElonU Webdev
  • 2,451
  • 14
  • 15
  • You should be passing a function reference, not a string, to `setTimeout`. – Na7coldwater Jul 10 '11 at 00:53
  • The string version will work, but the problem with using either a string or a function reference is how to pass parameters to the function. That's why I followed up with a recommendation to use anonymous functions further down in my answer. – ElonU Webdev Jul 10 '11 at 01:07
  • 1
    Okay, I confess that I didn't actually read your whole answer. But for the code that you posted, `setTimeout( gameOver, 10000 )` would have worked just as well (not to mention a slight performance boost since `"gameOver()"` wouldn't have to be compiled). – Na7coldwater Jul 10 '11 at 01:16
1

Here's some code without the use of timers. Call startCountdown() every time you want to re-initialize the count-down. Call getAvailableScore() when you want to fetch the current available score. You will have to decide what to do when the available score goes to zero.

var beginCountDownTime;

function startCountdown() {
    beginCountDownTime = new Date();
}

function getAvailableScore {
    var now = new Date();
    var delta = (now.getTime() - beginCountDownTime.getTime()) * 1000;  // time elapsed in seconds
    var points = 100 - (delta / 60);
    return(Math.round(Math.max(points, 0)));  // return integer result >= 0
}
jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

Maybe something like:

// Ad score
var score = 0;
var pointsAvailable = 100;

//$('#score').text(score);
function foundMatchingBlocks(event, params) {
      params.elements.remove();
      score += pointsAvailable;
      $('#score').text(score);
      pointsAvailable = 100;
};

$(document).ready(function() {doTimer();});

function doTimer() {
  setTimeout('reducePoints()',1000);
}

function reducePoints() {
  if(pointsAvailable>40) {
    pointsAvailable--;
  }
  doTimer();
}
psx
  • 4,040
  • 6
  • 30
  • 59
  • Hi, thank you for your reply, your solution works, but has a small "bug" in it. It doesn't reset the pointsAvailable after a found match. At the moment this happens: after 10 sec: 90 points, after another 10 sec: 80 points, after another 10 seconds: 70 points, etc. So it counts down from the last score. It should always countdown from 100 after each matching, so I guess some reset somewhere? But where? Thanks again – Maurice Jul 10 '11 at 09:19
  • Updated. It now resets back to 100 after a match – psx Jul 10 '11 at 10:09
  • Works great, a small request: is there a way to see the amount of points added? I used .html('+' + pointsAvailable) before your update to see the result, but after the update this will always show 100 – Maurice Jul 10 '11 at 12:55
  • You should be able to do it just after the score.text line in foundmatchingblocks – psx Jul 10 '11 at 21:37