Simon Says Game In jQuery Tutorial

Simon Says Game In jQuery Tutorial

In this tutorial i’m going to walk through the steps taken to build a Simon Says game in jQuery using some HTML5 and CSS3 features along the way.

The best way to improve at coding is to keep practising, we all know that so it’s good to set yourself a task every now and then to keep learning new things and also to give yourself a break from other coding you may be doing. I recently saw a logo design that incorporated the old Simon Says game into it, this got me thinking back to playing it at a friends house when I was younger, including the new fangled ‘Bop It’ derivative. Having not played them in years I decided it was time to resurrect the game in web form!

First lets start with a demo,

View the Demo

As you can see I’ve broken from the norm and gone with a random pattern for every level instead of just adding a new tone to the existing sequence. I find this more fun.

Download all the files

Simon Says Game In jQuery Tutorial
 

The HTML

 

The Board

First we want to build the board if you don’t know what the original looked like here is a picture.
Simon Says Unit

We want to create something a little similar looking, luckily with CSS3 we can create all kinds of shapes and we’re no longer restricted to just square/rectangular boxes so we now don’t have to mess around making lots of PNG images to create our game board.

Have a look at some of these shapes as an example of what you can achieve with CSS3.

We also want the pads to play a tone when we press them just like the original game. Now HTML5 audio is still a little up in the air, as usual different organisations see different formats as the future and are backing them above others. It’s the whole VCR/Beta or HDDVD/Blu-Ray saga again, maybe not on quite that scale but still hopefully the standard gets decided soon and we can move on! The 2 competing formats currently are MP3 and OGG, WAV is a third format but who wants to use uncompressed audio formats on a webpage? Unless it’s an audiophiles’ (and bandwidth king’s) homepage of course.
The situation is getting better but at the moment MP3 is supported by IE, Chrome, Safari and very recently Firefox. OGG is supported by Chrome, Firefox and Opera. We’ll include both Mp3 and OGG for now though to avoid any cross browser issues.

So, lets first of all create a wrapper div, entirely optional but centred content does make me happy we also use it as a relatively positioned element on which to base all our absolute elements from. Next we need to create a div for the background of the game, this will just be used as a background colour and shape for the game.

Next we create a div for each of the game pads there are 4 in total and we’ll give them the class of pad and shape”n” where n is the pad number. We’ll also use a data attribute on each pad so we can target them easier with jQuery later on. Just add a data attribute named pad to each pad div and number them accordingly.

Within each of these divs we will include an audio element including both the mp3 and ogg audio clips for reasons I explained above. We’ll give it a class of sound”n” again where n represents the pad number it’s attached to.

Finally we just want to include an element to act as the circle centre for the board within which you could choose to include a logo, text or the game start button, just give it whatever class you would like, for this example i’ve just kept it simple and used the class circle, original huh?

  <div class="wrapper">
    <div class="back">
      <div class="pad shape1">
        <audio preload="auto" class="sound1" data-pad="1">
          <source src="sounds/mp3/sounds_01.mp3" type="audio/mpeg"/>
          <source src="sounds/ogg/sounds_01.ogg" type="audio/ogg"/>
        </audio>
      </div>

      <div class="pad shape2">
        <audio preload="auto" class="sound2" data-pad="2">
          <source src="sounds/mp3/sounds_02.mp3" type="audio/mpeg"/>
          <source src="sounds/ogg/sounds_02.ogg" type="audio/ogg"/>
        </audio>
      </div>

      <div class="pad shape3">
        <audio preload="auto" class="sound3" data-pad="3">
          <source src="sounds/mp3/sounds_03.mp3" type="audio/mpeg"/>
          <source src="sounds/ogg/sounds_03.ogg" type="audio/ogg"/>
        </audio>
      </div>

      <div class="pad shape4">
        <audio preload="auto" class="sound4" data-pad="4">
          <source src="sounds/mp3/sounds_04.mp3" type="audio/mpeg"/>
          <source src="sounds/ogg/sounds_04.ogg" type="audio/ogg"/>
        </audio>
      </div>

      <div class="circle"></div>
    </div>

 

The Settings

We’re going to want a way for our users to keep track of which level they are currently on and also a score readout to give the game some ‘purpose’ even if it is just to beat your previous score. We’ll keep it simple with this tutorial and just use a couple of divs where we’ll update the text with our javascript. A div with the class level and div with the class score will suffice here.

Adding difficulty levels also adds an extra dimension to the game so we’ll include a few options. To that end we add a UL with the class difficulty and then a list element for each difficulty level we want. Within each list element include a radio input with the class difOpt, a name of difficulty and values as below, I’ll explain what the numbers do later on when we get to our code.
You can have as many difficulty options as you like but I’ve gone for the standards with easy, normal and hard but I’ve included an insane option for fun.

    <div class="level">
      <h2>Level: 1</h2>
    </div>

    <div class="score">
      <h2>Score: 0</h2>
    </div>
    
    <ul class="difficulty">

      <li>
        <input type="radio" class="difOpt" name="difficulty" value="2">Easy
      </li>

      <li>
        <input type="radio" class="difOpt" name="difficulty" value="1" checked>Normal
      </li>

      <li>
        <input type="radio" class="difOpt" name="difficulty" value="0.5">Hard
      </li>

      <li>
        <input type="radio" class="difOpt" name="difficulty" value="0.25">Insane
      </li>
    </ul>

    <div class="sButton">
      <button class="start">start</button>
    </div>

  </div>

The final part to include is a way of starting the game, we’ll only need it once per game so it can be any element you like, I’ve used a button with the class start, we’ll use our javascript to watch for a click event on this element to initiate a game.
 

CSS

The CSS for this is really simple. We’ll use a small amount of CSS3 with the border-radius property to allow us to get the nice rounded edges for our game pads.

I wont insult your intelligence by explaining all of the CSS, just the important bits.

We make our wrapper div as usual with the margin: 0 auto set and a width of 640px (the width of our game) with relative positioning. This keeps our content centred and allows us to absolutely position all of the child elements that make up the game.

Our back div we position absolutely with a width of 640px and a height of 640px too and we give every edge a border radius of 310px. This gives us the circular shape of the game board.


.wrapper{
  position: relative;
  width:640px;
  margin:0 auto;
}
.back{
  position: absolute;
  top:170px;
  width:640px;
  height: 640px;
  z-index:0;
  background-color: #000;
  border-radius: 310px;
}

For the game pads we want the edges to be rounded the same as the border of the game board that we set up above. First of all we use our pad class just to set the height and width to 300px and we float them all left. We set up our z-index to make sure we stack the elements on the page in the right order visually and importantly we give the pad an opacity of 0.6. We will use javascript to modify this opacity value to give the impression of a backlight on the pads when we use them as buttons.

We adjust the border-radius of each shape individually so that we can target the correct corner/edge using the border-top-left-radius style selector, we also give each pad a colour. The colours used on the original were green, red, yellow and blue so we will replicate that.

.pad {
  width: 300px;
  height: 300px;
  float: left;
  z-index: 1;
  margin: 10px;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
  filter: alpha(opacity=60);
  opacity: 0.6;
}

.shape1 {
  border-top-left-radius: 300px;
  background-color: green;
}

.shape2 {
  float: left;
  border-top-right-radius: 300px;
  background-color: red;
  clear: right;
}

.shape3 {
  float: left;
  border-bottom-left-radius: 300px;
  background-color: yellow;
  clear: left;
}

.shape4 {
  float: left;
  border-bottom-right-radius: 300px;
  background-color: blue;
}

The circle we create here is positioned into the centre of the board to mask the centre edges of each of the pads giving them their correct shapes. It’s also where you can add any text or branding that you’d like.

.circle {
  position: absolute;
  top: 195px;
  left: 195px;
  width: 250px;
  height: 250px;
  background: #000;
  border-radius: 125px;
  z-index: 10;
}

This next part is up to you really it’s just to place the start button the level identifier and the score identifier at the top of the page. You can get as fancy as you like.

.level, .score {
  width: 50%;
  float: left;
  text-align: center;
}

.sButton {
  width: 30%;
  margin: 0 auto;
}

.start {
  width: 100%;
  height: 30px;
  text-align: center;
}

 

Javascript

Now we get to the fun part, the functionality! We should be setup now with what looks like a simon says game on our page.

First we want to create a game object. with a couple of variables that will store all of our user settings and also keep track of the current turn and the generated sequence etc.

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
}

Let’s get some of the functionality sorted. One of the main things we need to sort is the ability to make the pads flash when we press them or the generated sequence is running and to have the corresponding sound play too.

We’ll create a function called flash which will accept 4 variables. We’ll pass it the element we wish to flash, the amount of times we want that element to flash, the speed of the flash and the pad number on which to trigger the sound.

We will give the illusion of the pad having a backlight flashing by adjusting the opacity to 1 and back to 0.6 as I alluded to in the CSS section above. We can use the jquery animate method on our element variable to do this, we’ll quickly get the pads opacity to 1 and then once the animation has completed we will call the animate method again to reduce opacity to 0.6.

We’ll wrap this whole animation cycle within an if statement so that it will only run when our times variable is greater than 0.

Use a setTimeout function below this to call the flash function. We use the speed variable here to set the timeout. By doing this we can stagger the flashes. Afterwards we decrement the times variable and again wrap the timeout function within a if statement that checks if the times variable is above 0.

By doing this we make sure that we call our flash function at certain intervals the correct amount of times. Essentially the function calls itself over and over until times equals 0 but only does this at intervals set by our speed variable which we can choose.

We also call the playSound function everytime the flash animation is run. So setup a function called playSound and pass it a variable that i’ve named clip, but it is essentially the pad number or clip number that we want to play when the pad flashes. Very simply we construct our selector by targeting our sound class and adding the clip number to the end of it. We don’t want to target the object that this returns though so add [0] to the end of the selector to actually target the audio element itself. We store that element in our sound variable and use the currentTime property to reset the sound clip to the start every time the playSound function is called. If we don’t do this the clip will just play from it’s current position when we call it which can lead to some unexpected behaviour. Finally just call the play method on our sound variable, this will do exactly as it says and play the selected audio clip. Because we have included both an OGG and mp3 version we should be safe whatever browser our user is using.

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];
		sound.currentTime=0;				//resets audio position to the start of the clip
		sound.play();						//play the sound


	},

One of the key functions we need to take care of is the generating of a random sequence that the user will have to copy, this is the crux of the game. We can easily create ‘random’ (as close to random as you need to) numbers in javascript. We need our random number to be between 1 and 4 as we have 4 possible pads on the game. We’ll store the generated sequence in an array that we will then iterate through and flash the corresponding pad to the user for them to copy.

Create a function called randomizePad and pass a variable named passes. This is essentially the level variable we have stored and determines how many numbers we would like to generate. So for level 10 we generate 10 numbers.

Using a for loop we generate a random number between 1 and 4 and push it to our genSequence array for the correct amount of passes. Math.random() generates a random number between 0 and 1 so we multiply this number by 4 and add 1 to get a value between 1 and 4, wrap this in Math.floor too to give us whole numbers with no decimal places.

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);
		}
	},

Now that we have our random sequence generated we need to actually display it to the user in the form of pad flashes and sounds. We already have most of this functinality set up so we’ll just create another function to actually handle staggering the pads so they play in an order that can be followed by our user.

To this end create a function called displaySequence. We will be using nested functions here so cache this at the top of the function to ensure we are always referencing the game object when we use ‘that’.

Use the jquery each method to perform a function on each value of the genSequence array which holds our random sequence. For each value of this array we will use setTimeout function to stagger when the pads are triggered depending on the position in the array and the difficulty level. So if we want to have 500ms of delay between each pad playing we’d set the timeout value of our setTimeout to 500 * the position in the array. For an example if we were on level 3 we would have 3 values in our generated sequence array. a value at position 0, 1 and 2 in the array. This means the timeout for each call of the flash function would be run at 0ms (500 * 0), 500ms (500*1) and 1000ms (500*2).

Our difficulty variable we will address in a moment but for now we use our default value of 1.

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
		});
	},

Before we get into registering the users selection we should make it so the user can see which level they are on and their current score.

We will simply update the score and level values on the page with simple jquery. Self explanatory, but we are writing our level value and our score value to each of the respective divs that we set up in the HTML.

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);
	},

To this end we need a way to actually keep track of the score. I’ve got this setup to give the user a set amount of points per correct pad they hit, the amount of points earned will be dependant on the difficulty the user is playing at.

Create a function called keepScore. Declare a variable named multiplier. We’ll use a switch statement to update this multiplier variable depending on the difficulty level the user has selected, meaning the higher the difficulty the more points the user will earn for each correct pad they’ve chosen, currently the balance may be a bit off with the points awarded but it can be tweaked however you like.

You can see below that every time we call this function we multiply the default points earned (1 point is default) by the multiplier and add it to our score variable. Once this is done we call our displayScore function we created previously to display it on the screen to our user. Simple.

For now the difficulty is whatever we set it at the beginning of our game object but we’ll soon sort out how to read the user settings from our difficulty selector element.


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
	},

This is all well and good, we have a way of displaying the score to our user, we generate a random sequence and play it back to them, now we need to sort out the users input or more importantly for now how we check what pad they pressed and whether it was the correct pad in the sequence. If the user is correct we want to be able to check the next pad in the sequence and if they get the whole sequence correct we want to move up a level and generate a larger sequence. To go with that we also need to make sure that if the user hits the wrong pad we alert them to which one it should have been and have the game reset to default for them to try again.

So although we are only concerned with the most recent pad the user has touched I thought for future purposes it would be useful to keep track of all the pads the user has hit on the current level, I don’t really know why yet but I tell myself that it’s a good idea so here we go.

Make a function called logPlayerSequence and pass the variable pad to it. All this function does is push the users pad selection to the player sequence array (plaSequence), the same as we do with the generated sequence, it then calls the checkSequence function and passes pad as an argument too.

Our checkSequence function is where the real work goes on and its so simple! Again we cache this in the that variable so we have access to the game object within the nested functions we will create. Use an if statement to check if the pad number isn’t the same as the pad number stored in the generated sequence array at position “turn” turn being the current position in the sequence the user is trying to remember. If they don’t match we call the incorrectSequence function, if on the other hand the user has remembered correctly and the 2 numbers match we update the score and move onto the next value in the sequence by incrementing the turn value.

After that we need to check to see if the sequence has been remembered correctly in its entirety. If it has we increment the level, display the new level value to the user, disable user input by setting game.active to false and then we do a quick 1 second wait before calling for the new level to start. The new level function does exactly what you would imagine so we’ll look at that shortly.

Next we need to manage what happens when the user gets it wrong.

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++;						//increment 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);
		}
	},

As we saw above if the checkSequence function finds the user has hit the wrong pad we call the incorrectSequence function. We want this function to disable user input, show the user their score and current level, make the user aware of which pad they should have hit and then enable the user to start again.

First we get the pad number that should have been hit from the generated sequence array and store it in a variable. Set game.active to false and display the score and the level, these two being a placeholder for further user interaction such as a tweet function to let the user tweet their high score etc. Use a setTimeout function to flash the correct pad 4 times to the user to basically rub it in with which one they got wrong. We then need to re enable / show the start button and the difficulty settings again (which we’ll hide in our init method in a moment!) so that the user can setup and start again.

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();

	}

};

So maybe we need to actually listen for a click event on each of the pads so the user can actually interact with our game, especially as we’ve gone through all this effort to check their input and make a game for them!

We’ll use a simple mouseup event and within that we’ll have a function that looks at the data attribute “pad” that we gave each of our pads. use parseInt to convert this to an integer, I always include the radix just to make sure so add 10 as an argument at the end of the parseInt statement.

We also want the pad to flash when we press it again to give the illusion that it’s a backlit button, so call our flash function again here and finally we call logPlayerSequence passing it the pad variable, this function as we’ve seen handles the logic of the game and how the game should react to this button press.

We set our handlers flag to true too just so we know that the event handler is ready and when we reset then the game we don’t need to register the handler again.

initPadHandler: function(){

		that=this;

		$('.pad').on('mouseup',function(){

			if(that.active===true){

				var pad=parseInt($(this).data('pad'),10); //10 is the radix here
					
				that.flash($(this),1,300, pad);

				that.logPlayerSequence(pad);

			}
		});

		this.handlers=true;

	},

Finally we need to setup our newLevel function and sort out how we start a game and initialise everything.

Create a function called init, all this function will do is start the game, it will check if the event handler for the pad is already setup and if it isn’t call the padHandler function. Finally we call the newGame function.

Our newGame function should just reset the level and score to their defaults ready for a new game to start and show the results to the user. Once those have been reset we call the newLevel function.

Our newLevel function resets the generated sequence array and player sequence array, it sets position and turn to 0 ready for a new level or game to start and it allows user input by setting the active flag to true. It then calls our randomize pad function to generate a sequence and then displays the sequence to the user.

And that is it. Our game logic is complete and we have a way of interacting with the game. One more step to take to start things moving.

init: function(){					//initialises the game
		if(this.handler === false){		//checks to see if handlers are already active
			this.initPadHandler();		//if not activate them
			this.handler=true;			//and set a flag
		}
		this.newGame();				//reset the game defaults

	},

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

	},

The very final step is to attach an event handler to our start button. We use this button to call the game.init method to start the ball rolling. It also sets the game difficulty based on the users selection within the difficulty radio buttons and then proceeds to hide both the difficulty settings and the start button to stop the difficulty being modified while a game is in progress.

$(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();


	});

	
});

I promise, that is everything you need to know. This is the first tutorial of this length I’ve written so I hope I haven’t rambled on too long and I’ve kept everything clear. If you’ve got anything to say, leave a comment or get in touch with me. Hopefully you find this helpful, it’s a bit of fun and a great little exercise.

View the Demo

Download Source Files
 

The complete script

Our Complete code.

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];
		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();


	});

	
});
  • Delicious
  • Facebook
  • Twitter
  • Reddit
  • StumbleUpon
blog comments powered by Disqus