0
\$\begingroup\$

I am currently developing a Simon says type game using jquery and javascript.

I have linked a fully copy of the game on github

Github download and unzip to see the game fully https://github.com/Jamiex304/Simon_Says_Game_Demo(Disabled because resolved)

And I have reached a problem I want to add a timer that the player can see ?

currently the level will just go on til the user clicks the wrong button in the sequence.

Some Basic info on the game the user will see a random sequence each level a new sequence is added with one more extra move Each time the user enters the right sequence they go to the next level all info can be found in the attached JavaScript with comments

WHAT I WANT HELP ADDING

I just want to add a timer that starts at 10 seconds when the user clicks the start button Each time the enter the right sequence the timer starts again when they reach 5 right sequences the timer adds 5 extra seconds and so

I already have a div made for it called Timer so the user can see it in the middle of the screen

I have attached the html code and the JavaScript that the game events and the github link offers the full game

Javascript

var game={ //game object
 level: 1, //current level
 turn: 0, //current turn
 difficulty: 1, // user difficulty
 score: 0, //current score
 active: false, //whether a turn is active or not
 handler: false, // whether the click and sound handlers are active
 shape: '.shape', // cached string for the pad class
 genSequence: [], //array containing the generated/randomized pads
 plaSequence: [], //array containing the users pad selections
 init: function(){ //initialises the game
 if(this.handler === false){ //checks to see if handlers are already active
 this.initPadHandler(); //if not activate them
 }
 this.newGame(); //reset the game defaults
 },
 initPadHandler: function(){
 that=this;
 $('.pad').on('mouseup',function(){
 if(that.active===true){
 var pad=parseInt($(this).data('pad'),10);
 that.flash($(this),1,300, pad);
 that.logPlayerSequence(pad);
 }
 });
 this.handler=true;
 },
 newGame: function(){ //resets the game and generates a starts a new level
 this.level=1;
 this.score=0;
 this.newLevel();
 this.displayLevel();
 this.displayScore();
 },
 newLevel: function(){
 this.genSequence.length=0;
 this.plaSequence.length=0;
 this.pos=0;
 this.turn=0;
 this.active=true;
 this.randomizePad(this.level); //randomize pad with the correct amount of numbers for this level
 this.displaySequence(); //show the user the sequence
 },
 flash: function(element, times, speed, pad){ //function to make the pads appear to flash
 var that = this; //cache this
 if(times > 0){ //make sure we are supposed to flash
 that.playSound(pad); //play the corresponding pad sound
 element.stop().animate({opacity: '1'}, { //animate the element to appear to flash
 duration: 50,
 complete: function(){
 element.stop().animate({opacity: '0.6'}, 200);
 }
 }); //end animation
 }
 if (times > 0) { //call the flash function again until done the correct amount of times 
 setTimeout(function () {
 that.flash(element, times, speed, pad);
 }, speed);
 times -= 1; //times - 1 for each time it's called
 }
 },
 playSound: function(clip){ //plays the sound that corresponds to the pad chosen
 var sound= $('.sound'+clip)[0];
 console.log(sound);
 console.log($('.sound'+clip));
 sound.currentTime=0; //resets audio position to the start of the clip
 sound.play(); //play the sound
 },
 randomizePad: function(passes){ //generate random numbers and push them to the generated number array iterations determined by current level
 for(i=0;i<passes;i++){
 this.genSequence.push(Math.floor(Math.random() * 4) + 1);
 }
 },
 logPlayerSequence: function(pad){ //log the player selected pad to user array and call the checker function
 this.plaSequence.push(pad);
 this.checkSequence(pad);
 },
 checkSequence: function(pad){ //checker function to test if the pad the user pressed was next in the sequence
 that=this;
 if(pad !== this.genSequence[this.turn]){ //if not correct 
 this.incorrectSequence();
 }else{ //if correct
 this.keepScore(); //update the score
 this.turn++; //incrememnt the turn
 }
 if(this.turn === this.genSequence.length){ //if completed the whole sequence
 this.level++; //increment level, display it, disable the pads wait 1 second and then reset the game
 this.displayLevel();
 this.active=false;
 setTimeout(function(){
 that.newLevel();
 },1000);
 }
 },
 displaySequence: function(){ //display the generated sequence to the user
 var that=this;
 $.each(this.genSequence, function(index, val) { //iterate over each value in the generated array
 setTimeout(function(){
 that.flash($(that.shape+val),1,300,val);
 },500*index*that.difficulty); // multiply timeout by how many items in the array so that they play sequentially and multiply by the difficulty modifier
 });
 },
 displayLevel: function(){ //just display the current level on screen
 $('.level h2').text('Level: '+this.level);
 },
 displayScore: function(){ //display current score on screen
 $('.score h2').text('Score: '+this.score);
 },
 keepScore: function(){ //keep the score
 var multiplier=0;
 switch(this.difficulty) //choose points modifier based on difficulty
 {
 case '2':
 multiplier=1;
 break;
 case '1':
 multiplier=2;
 break;
 case '0.5':
 multiplier = 3;
 break;
 case '0.25':
 multiplier = 4;
 break;
 }
 this.score += (1 * multiplier); //work out the score
 this.displayScore(); //display score on screen
 },
 incorrectSequence: function(){ //if user makes a mistake
 var corPad = this.genSequence[this.turn], //cache the pad number that should have been pressed
 that = this;
 this.active=false;
 this.displayLevel();
 this.displayScore();
 setTimeout(function(){ //flash the pad 4 times that should have been pressed
 that.flash($(that.shape+corPad),4,300,corPad);
 },500);
 $('.start').show(); //enable the start button again and allow difficulty selection again
 $('.difficulty').show();
 }
};
$(document).ready(function(){ //document ready
 $('.start').on('mouseup', function(){ //initialise a game when the start button is clicked
 $(this).hide();
 game.difficulty = $('input[name=difficulty]:checked').val();
 $('.difficulty').hide();
 game.init();
 });
});
asked Oct 18, 2014 at 21:38
\$\endgroup\$
2
  • \$\begingroup\$ stackoverflow.com/questions/2064186/… \$\endgroup\$ Commented Oct 19, 2014 at 9:29
  • \$\begingroup\$ Please mark an answer as accepted when your problem is resolved. If you don't think any of the answers deserve to be marked as accepted write your own answer and mark that. \$\endgroup\$ Commented Oct 20, 2014 at 20:46

3 Answers 3

0
\$\begingroup\$

I guess you want something like this:

var givenTime=10000
var timeLimit
var clockInterval
resetClock()
function updateClock(){
 var now=new Date().getTime()
 if(now<timeLimit){
 //Set the displayed clock to timeLimit-now
 }
 else{
 //Time has run out
 clearInterval(clockInterval)
 }
}
function resetClock(){
 timeLimit=new Date().getTime()+givenTime
 clearInterval(clockInterval)
 clockInterval=setInterval(updateClock,10)
}

You have timeLimit set to the point in time where the timer runs out, and then a function in an interval recalculate the time left approximately once every 10 ms. Beware that you can't count on setInterval to fire exactly as often as you ask for, see setTimeout or setInterval?

answered Oct 19, 2014 at 10:02
\$\endgroup\$
2
  • \$\begingroup\$ this is great, but the problem i am having is implementing it with my code and my javascript, i have found dozens of examples but i cant get any of them to work with my code if u take a look at the game u can see what i want and what i mean \$\endgroup\$ Commented Oct 19, 2014 at 15:36
  • \$\begingroup\$ Try, and if you fail, post your broken code. \$\endgroup\$ Commented Oct 19, 2014 at 18:12
0
\$\begingroup\$

Javascript has the setInterval(function(), milliseconds) function which could help here.

If you need to get rid of the interval once you're done with it you can store your interval like so, and then clear it:

var timer = setInterval(tick, 1000);
clearInterval(timer);
answered Oct 19, 2014 at 8:22
\$\endgroup\$
4
  • \$\begingroup\$ You probably meant to write var timer = setInterval(tick, 1000); without a set of parentheses following the function identifier, as to pass the function reference rather than call the function and pass the result. \$\endgroup\$ Commented Oct 19, 2014 at 10:06
  • \$\begingroup\$ Indeed, fixed. My JS is a little rusty, the version I used as a reference has setInterval(function(){tick()},1000) \$\endgroup\$ Commented Oct 19, 2014 at 12:18
  • \$\begingroup\$ but the problem i am having is implementing it with my code and my javascript, i have found dozens of examples but i cant get any of them to work with my code if u take a look at the game u can see what i want and what i mean \$\endgroup\$ Commented Oct 19, 2014 at 15:36
  • \$\begingroup\$ @Jamiex304 your github link doesn't work for me. \$\endgroup\$ Commented Oct 20, 2014 at 13:24
0
\$\begingroup\$

Got it working full javascript below

var game = { //game object
 level: 1, //current level
 turn: 0, //current turn
 difficulty: 1, // user difficulty
 score: 0, //current score
 active: false, //whether a turn is active or not
 handler: false, // whether the click and sound handlers are active
 shape: '.shape', // cached string for the pad class
 genSequence: [], //array containing the generated/randomized pads
 plaSequence: [], //array containing the users pad selections
 init: function () { //initialises the game
 if (this.handler === false) { //checks to see if handlers are already active
 this.initPadHandler(); //if not activate them
 }
 this.newGame(); //reset the game defaults
 },
 initPadHandler: function () {
 that = this;
 $('.pad').on('mouseup', function () {
 if (that.active === true) {
 var pad = parseInt($(this).data('pad'), 10);
 that.flash($(this), 1, 300, pad);
 that.logPlayerSequence(pad);
 }
 });
 this.handler = true;
 },
 newGame: function () { //resets the game and generates a starts a new level
 this.level = 1;
 this.score = 0;
 this.newLevel();
 this.displayLevel();
 this.displayScore();
 //initialize timer to 10 seconds (10.0)
 this.timer = 10;
 },
 newLevel: function () {
 this.genSequence.length = 0;
 this.plaSequence.length = 0;
 this.pos = 0;
 this.turn = 0;
 this.active = true;
 this.randomizePad(this.level); //randomize pad with the correct amount of numbers for this level
 this.displaySequence(); //show the user the sequence
 },
 flash: function (element, times, speed, pad) { //function to make the pads appear to flash
 var that = this; //cache this
 if (times > 0) { //make sure we are supposed to flash
 that.playSound(pad); //play the corresponding pad sound
 element.stop().animate({
 opacity: '1'
 }, { //animate the element to appear to flash
 duration: 50,
 complete: function () {
 element.stop().animate({
 opacity: '0.6'
 }, 200);
 }
 }); //end animation
 }
 if (times > 0) { //call the flash function again until done the correct amount of times 
 setTimeout(function () {
 that.flash(element, times, speed, pad);
 }, speed);
 times -= 1; //times - 1 for each time it's called
 }
 },
 playSound: function (clip) { //plays the sound that corresponds to the pad chosen
 var sound = $('.sound' + clip)[0];
 console.log(sound);
 console.log($('.sound' + clip));
 sound.currentTime = 0; //resets audio position to the start of the clip
 sound.play(); //play the sound
 },
 randomizePad: function (passes) { //generate random numbers and push them to the generated number array iterations determined by current level
 for (i = 0; i < passes; i++) {
 this.genSequence.push(Math.floor(Math.random() * 4) + 1);
 }
 },
 logPlayerSequence: function (pad) { //log the player selected pad to user array and call the checker function
 this.plaSequence.push(pad);
 this.checkSequence(pad);
 },
 checkSequence: function (pad) { //checker function to test if the pad the user pressed was next in the sequence
 that = this;
 if (pad !== this.genSequence[this.turn]) { //if not correct 
 this.incorrectSequence();
 } else { //if correct
 this.keepScore(); //update the score
 this.turn++; //incrememnt the turn
 }
 if (this.turn === this.genSequence.length) { //if completed the whole sequence
 this.level++; //increment level, display it, disable the pads wait 1 second and then reset the game
 this.displayLevel();
 this.active = false;
 // Stop counting when sequence is correct to avoid time running out before starting next level
 clearInterval(this.timerInterval);
 //Add 5.0 seconds each 5th level
 this.timer = 10 + 5 * Math.floor(this.level / 5);
 //Update timerdisplay to show fulltime while displaying next level sequence
 $(".Timer p").html(this.timer);
 setTimeout(function () {
 that.newLevel();
 }, 1000);
 }
 },
 // Countdown and update timer, call incorrectsequence when time's up
 countDown: function () {
 this.timer -= 0.1;
 $(".Timer p").html(this.timer.toFixed(1)); // Display 9.0 instad of 9
 if (this.timer < 0.1) {
 this.incorrectSequence();
 }
 },
 displaySequence: function () { //display the generated sequence to the user
 var that = this;
 var timerCount = 0;
 $.each(this.genSequence, function (index, val) { //iterate over each value in the generated array
 timerCount = index;
 setTimeout(function () {
 that.flash($(that.shape + val), 1, 300, val);
 }, 500 * index * that.difficulty); // multiply timeout by how many items in the array so that they play sequentially and multiply by the difficulty modifier
 });
 // Wait to start timer until full sequence is displayed
 setTimeout(function () {
 that.timerInterval = setInterval(function () {
 that.countDown()
 }, 100)
 }, 500 * timerCount * that.difficulty);
 },
 displayLevel: function () { //just display the current level on screen
 $('.level h2').text('Level: ' + this.level);
 },
 displayScore: function () { //display current score on screen
 $('.score h2').text('Score: ' + this.score);
 },
 keepScore: function () { //keep the score
 var multiplier = 0;
 switch (this.difficulty) //choose points modifier based on difficulty
 {
 case '2':
 multiplier = 1;
 break;
 case '1':
 multiplier = 2;
 break;
 case '0.5':
 multiplier = 3;
 break;
 case '0.25':
 multiplier = 4;
 break;
 }
 this.score += (1 * multiplier); //work out the score
 this.displayScore(); //display score on screen
 },
 incorrectSequence: function () { //if user makes a mistake
 //Stop counting down timer and display start message
 clearInterval(this.timerInterval);
 $(".Timer p").html("Get Ready your time starts when you click start");
 var corPad = this.genSequence[this.turn], //cache the pad number that should have been pressed
 that = this;
 this.active = false;
 this.displayLevel();
 this.displayScore();
 setTimeout(function () { //flash the pad 4 times that should have been pressed
 that.flash($(that.shape + corPad), 4, 300, corPad);
 }, 500);
 $('.start').show(); //enable the start button again and allow difficulty selection again
 $('.difficulty').show();
 }
};
$(document).ready(function () { //document ready
 $('.start').on('mouseup', function () { //initialise a game when the start button is clicked
 $(this).hide();
 game.difficulty = $('input[name=difficulty]:checked').val();
 $('.difficulty').hide();
 game.init();
 });
});
answered Oct 20, 2014 at 23:25
\$\endgroup\$

You must log in to answer this question.