Skip to content

Instantly share code, notes, and snippets.

@shade
Created January 27, 2017 02:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shade/68b86d9767cafd0a25c259c3185315bc to your computer and use it in GitHub Desktop.
Save shade/68b86d9767cafd0a25c259c3185315bc to your computer and use it in GitHub Desktop.
// Closure for namespacing, and to prevent name collisions.
;(function() {
// Initialize constants
var NEW_GAME_DELAY = 1200
var NOTE_DURATION = 800
var ACCELERATION_CONSTANT = 0.8
var POINT_CONSTANT = 10
// Initilize the Simon game as a giant singleton, as only one instance is necessary.
var Simon = new function () {
// Initialize some arrays
// Stores the last game state, also used to calculate randomness.
this.game = []
// This is mutable and is unreliable for storage.
this.state = []
// Initialize the notes object collection.
this.notes = {}
// This is the simon notebox wheel DOM Element.
this.wheel = document.getElementById('notebox')
// This is the current score
this.score = 0
// This is the highscore
this.highscore = 0
// Execute the first Simon.
this.click = (key) => {
// Pop out the first key in the real sequence.
var realKey = this.state.shift()
// Check if the user's key matches the real key.
if (key == realKey) {
// Check if the current sequence is over.
if (this.state.length == 0) {
// Add points to the score.
this.displayScore(POINT_CONSTANT * this.game.length)
// Disable all inputs
this.disableAll()
// Create a new sequence, start the game over again.
this.newState()
}
} else {
// Make the current score the high score if possible
this.displayHighscore()
// Disable all inputs.
this.disableAll()
// Set the score to zero.
this.displayScore(-this.score)
// Since the keys didn't match, end the game.
this.end()
}
}
this.generate = () => {
return KEYS[~~(Math.random() * KEYS.length)]
}
this.newState = () => {
// Create a new letter to add to the sequence and push it into the game.
this.game.push(this.generate())
// Deep clone the Simon game into the state, to allow mutability in only the state.
this.state = this.game.slice(0)
// Give the user some rest, before the next game.
setTimeout(() => {
// Play the entire new sequence back to the user.
this.playAll()
}, NEW_GAME_DELAY)
}
this.disableAll = () => {
for (note in this.notes) {
this.notes[note].disable()
}
}
this.enableAll = () => {
for (note in this.notes) {
this.notes[note].enable()
}
}
this.playAll = () => {
// Iterate through the game notes and play the sequence.
this.game.forEach((note, i) => {
setTimeout(() => {
this.notes[note].play()
if ((i+1) == this.game.length) {
this.enableAll()
}
},i * NOTE_DURATION)
})
}
this.displayScore = (points) => {
let scoreCard = document.getElementById('score')
// Split the score value to extract the current score.
let scoreArr = scoreCard.innerHTML.split(' ')
// Update the score in the object
this.score += points
// Update the scor on the DOM.
scoreArr[1] = this.score
// Update the DOM with the new score.
scoreCard.innerHTML = scoreArr.join(' ')
}
this.displayHighscore = () => {
// Grab the high score label
let highScoreCard = document.getElementById('high-score')
// if the current score is greater, update it.
if (this.score > this.highscore) {
let scoreArr = highScoreCard.innerHTML.split(' ')
highScoreCard.style.display = 'block'
this.highscore = this.score
scoreArr[1] = this.highscore
highScoreCard.innerHTML = scoreArr.join(' ')
}
}
this.end = () => {
// Initialize number of degrees to turn by
var degrees = 0
// This is the change in degrees
var ddegrees = -8
// Turn the simon wheel.
var turnInterval = setInterval(() => {
// Stop everything, on a complete rotation and start a new game.
if (Math.abs(degrees) >= 360) {
this.newState()
clearInterval(turnInterval)
this.wheel.style.transform = ''
return
}
// Update the transformation
this.wheel.style.transform = 'rotate(' + degrees +'deg)'
// Increase the rotation of the wheel
degrees += 8-Math.abs(ddegrees)
// Add some acceleration to the mix.
ddegrees += ACCELERATION_CONSTANT
}, 10)
// Destroy the game sequence
this.state = []
this.game = []
// Play everything at once to give the user negative reinforcement.
for (note in this.notes) {
this.notes[note].play()
}
}
}
// Iterate through the keys and create noteboxes for them, while binding the .
KEYS.forEach((key) => {
Simon.notes[key] = new NoteBox(key, Simon.click.bind(Simon));
});
// Start the simon.
Simon.newState()
// Add this is the window as a globally accessible object.
window.Simon = Simon
})(window)
@shade
Copy link
Author

shade commented Jan 27, 2017

This is the actual simon code, that was compiled/minified and converted to pixels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment