Skip to content

Instantly share code, notes, and snippets.

@JohnnyBizzel
Created September 18, 2017 01:38
Show Gist options
  • Save JohnnyBizzel/c32330288eb3025a7e9fb92db5d0cd67 to your computer and use it in GitHub Desktop.
Save JohnnyBizzel/c32330288eb3025a7e9fb92db5d0cd67 to your computer and use it in GitHub Desktop.
Simon's Piano game
<h1>Simon Keyboard Game</h1>
<div class="user-controls">
<div class="on-off">
<button>Off</button>
</div>
<div class="scoreboard">
<span>00</span>
</div>
<div class="strict-mode">
<button>Strict Mode</button>
</div>
</div>
<div class="piano">
<div class="key" data-key="f" id="f">
<p class="letter">F</p>
</div>
<div class="key" data-key="g" id="g">
<p class="letter">G</p>
</div>
<div class="key" data-key="a" id="a">
<p class="letter">A</p>
</div>
<div class="key" data-key="b" id="b">
<p class="letter">B</p>
</div>
</div>
<div id="helpText">
Instructions:<br/>
A sequence of notes will play starting at one note, incrementing each round. Repeat the sequence after it plays. Get to the magic number of correct notes to win the game.
To repeat the same sequence after an incorrect guess, chose Easy Mode, otherwise you will have to start again with a new sequence (Strict Mode).
</div>
<!--
<audio data-key="f" src="https://s3.amazonaws.com/freecodecamp/simonSound1.mp3"></audio>
<audio data-key="g" src="https://s3.amazonaws.com/freecodecamp/simonSound2.mp3"></audio>
<audio data-key="a" src="https://s3.amazonaws.com/freecodecamp/simonSound3.mp3"></audio>
<audio data-key="b" src="https://s3.amazonaws.com/freecodecamp/simonSound4.mp3"></audio>
https://www.dropbox.com/s/fm5d186yliwwm5w/g_note1.wav?dl=0
-->
<audio data-key="wrong" src="https://dl.dropboxusercontent.com/s/r37z5gz4atss8aa/family_fortunes__wrong_answer.mp3">
<audio data-key="a" src="https://dl.dropboxusercontent.com/s/0gv5xq9bggrc1fc/a_note1.wav"></audio>
<audio data-key="b" src="https://dl.dropboxusercontent.com/s/vf22bxhw2lmintz/b_note1.wav"></audio>
<audio data-key="f" src="https://dl.dropboxusercontent.com/s/0ml89c51jtlpfva/f_note1.wav"></audio>
<audio data-key="g" src="https://dl.dropboxusercontent.com/s/fm5d186yliwwm5w/g_note1.wav"></audio>
<!-- <audio data-key="wrong" src="https://drive.google.com/uc?export=download&id=0B4JeNrcqav8XOVFXcEotQVI5T0E">
https://www.dropbox.com/s/g6e7xlqxsvv6thu/200w_s.gif?dl=0
</audio> -->
<audio data-key="a0" src="https://drive.google.com/uc?export=download&id=0B4JeNrcqav8XODk5U05RekliYWc"></audio>
<audio data-key="b0" src="https://drive.google.com/uc?export=download&id=0B4JeNrcqav8XcHZTdUVpOUQtcjQ"></audio>
<audio data-key="f0" src="https://drive.google.com/uc?export=download&id=0B4JeNrcqav8XZ292T1lTZWd4MTQ"></audio>
<audio data-key="g0" src="https://drive.google.com/uc?export=download&id=0B4JeNrcqav8XNE9mR25ETThuNm8"></audio>
"use strict";
const WINNING_SCORE = 19;
let isOn = false;
let notePlaying = false;
let isStrict = true;
let gameWon = false;
const notes = ["f", "g", "a", "b"];
const keyColors = ["tomato", "dodgerblue", "lightseagreen", "goldenrod"];
let sequence = [];
let guessSequence = [];
let idx = 0;
let guessIdx = 0;
window.onload = function() {
gameInit();
};
function resetGame() {
sequence = [];
$(".scoreboard").text("!!");
continueGame();
}
function gameInit() {
$(".on-off button").click(function() {
let onOff = $(".on-off button").text();
if (onOff != "On") {
// Reset game to ready state
$(".on-off button").text("On");
$(".on-off button").css("background", "lightgreen");
$('h1').css('color', 'black');
$('body').css("background-image", "none");
isOn = true;
gameWon = false;
sequence = [];
addtoSequence(true); // start game so pass true
} else {
$(".on-off button").text("Off");
$(".on-off button").css({
background: "gray",
color: "black"
});
isOn = false;
gameWon = false;
// clear sequence
sequence = [];
$(".scoreboard").text("00");
}
});
$(".strict-mode button").click(function() {
let strictMode = $(".strict-mode").text().trim();
console.log(strictMode);
if (strictMode === "Strict Mode") {
$(".strict-mode button").text("Easy Mode");
$(".strict-mode button").css("background", "lightseagreen");
isStrict = false;
} else {
$(".strict-mode button").text("Strict Mode");
$(".strict-mode button").css({
background: "gray",
color: "black"
});
isStrict = true;
}
});
}
function playSequence(note) {
// for(var i=0; i<sequence.length; i++) {
// const randomNote = notes[randomNum];
const audio = document.querySelector(`audio[data-key=${note}]`);
audio.play();
notePlaying = true;
// Work out correct colour
$("#" + note).css("background", keyColors[notes.indexOf(note)]);
idx++;
audio.onended = function() {
audio.currentTime = 0;
$("#" + note).css("background", "none");
notePlaying = false;
};
if (idx >= sequence.length) {
guessIdx = 0;
return;
}
// else
setTimeout(() => {
playSequence(sequence[idx]);
}, 1100);
}
function addtoSequence(reStart) {
if (!notePlaying) {
const randomNum = Math.floor(Math.random() * notes.length);
sequence.push(notes[randomNum]);
// set the first note of the sequence to be the first index
idx = 0;
// play the whole sequence using this recursive function:
playSequence(sequence[0]);
let scoreboard = 0;
if (reStart || document.querySelector(".scoreboard").innerText === '!!')
{
scoreboard = 1;
} else {
scoreboard = Number(document.querySelector(".scoreboard").innerText) + 1;
}
$(".scoreboard").text(scoreboard);
}
}
function compareGuess(note) {
console.log("user guessed", note);
guessSequence.push(note);
console.log("seq:", sequence);
console.log("Guess:", guessSequence);
// const audio = document.querySelector(`audio[data-key="wrong"]`);
// audio.play();
if (sequence[guessIdx] === note) {
guessIdx++;
// got (5) correct. Get 20 correct to win
if (sequence.length > WINNING_SCORE && guessIdx > WINNING_SCORE) {
// winner!!
gameWon = true;
isOn = false;
return true;
}
return true;
} else {
return false;
}
}
function wrongAnswer() {
console.log("Wrong!!");
const audio = document.querySelector(`audio[data-key="wrong"]`);
audio.play();
guessIdx = 0;
guessSequence = [];
if (isStrict) {
resetGame();
} else {
idx = 0;
playSequence(sequence[0]);
}
}
function continueGame() {
//reset guess position
setTimeout(function() {
guessIdx = 0;
guessSequence = [];
addtoSequence(false);} , 1200 );
}
$("#f").mousedown(function() {
// can't use (event.target.id) to pass in the parameter because if you click
// the letter inside the <p> it doesn't have the correct id
// So parameters need to be specified.
if (isOn) {
playingNoteInGame('f');
} else {
playNote('f');
}
});
$("#g").mousedown(function() {
if (isOn) {
playingNoteInGame('g');
} else {
playNote('g');
}
});
$("#a").mousedown(function() {
if (isOn) {
playingNoteInGame('a');
} else {
playNote('a');
}
});
$("#b").mousedown(function() {
if (isOn) {
playingNoteInGame('b');
} else {
playNote('b');
}
});
function playingNoteInGame(note) {
// compare with sequence
let playingNote = false;
const ok = compareGuess(note);
if (!ok) {
wrongAnswer();
return;
}
const audio = document.querySelector(`audio[data-key=${note}]`);
console.log(audio.src);
console.log(audio.currentTime);
// check if Audio is still playing
if (audio.currentTime > 0) {
setTimeout(function() {
audio.currentTime = 0;
audio.play();
$("#" + note).css("background", keyColors[notes.indexOf(note)]);
// if (guessIdx === 5) {
// console.log("!! winner !!");
// // Todo: Winning state
// $(".scoreboard").text('Win');
// $("body").css('background-image', "url('https://dl.dropboxusercontent.com/s/g6e7xlqxsvv6thu/200w_s.gif')");
// gameWon = true;
// }
audio.onended = function() {
audio.currentTime = 0;
$("#" + note).css("background", "none");
notePlaying = false;
if (guessIdx >= sequence.length && !gameWon) {
continueGame();
} else if (gameWon) {
console.log('You won! I think...');
setWinState();
}
};
}, 100);
} else {
audio.play();
$("#" + note).css("background", keyColors[notes.indexOf(note)]);
audio.onended = function() {
audio.currentTime = 0;
$("#" + note).css("background", "none");
notePlaying = false;
if (guessIdx >= sequence.length && !gameWon) {
continueGame();
} else if (gameWon) {
console.log('You won!');
setWinState();
}
};
}
}
function setWinState() {
$(".scoreboard").text('Win');
$(".on-off button").text('Reset');
$(".on-off button").css('background-color', 'gray');
$("body").css('background-image', "url('https://dl.dropboxusercontent.com/s/g6e7xlqxsvv6thu/200w_s.gif')");
$(".key").each(function() {
$(this).addClass('whiteBg');
$(this).removeAttr("style");
});
$(".key > p").each(function() {
$(this).css('color', '#282830');
});
$('h1').css('color', 'white');
gameWon = true;
isOn = false;
}
function playNote(nt) {
const audio = document.querySelector(`audio[data-key="${nt}"]`);
audio.play();
$(`#${nt}`).css("background", keyColors[notes.indexOf(nt)]);
audio.onended = function() {
audio.currentTime = 0;
$(`#${nt}`).css("background", "none");
notePlaying = false;
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
body {
height: 95vh;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Boogaloo', cursive;
flex-direction: column;
/* background-image: 'none'; url('https://dl.dropboxusercontent.com/s/g6e7xlqxsvv6thu/200w_s.gif');*/
}
h1 {
animation: 2s ease-in-out slideIn;
}
@keyframes slideIn {
0% {
transform: translateX(-400%)
}
100% {
transform: translateX(0);
}
}
.piano {
width: 400px;
height: 400px;
margin: 0 auto;
position: relative;
overflow: hidden;
box-shadow: 0 5px 10px 2px black;
display: flex;
}
.user-controls {
width: 450px;
height: 100px;
margin: 0 auto;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
justify-content: space-around;
align-items: center;
}
.scoreboard {
width: 60px;
background: #000;
border-radius: 50%;
height: 60px;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 2em;
margin: 5px;
}
.key {
width: 100px;
height: 100px;
min-height: 100%;
border: 1px solid black;
position: relative;
transition: 0.3s ease-in-out;
-webkit-transition: 0.3s ease-in-out;
cursor: pointer;
&:after {
width: 50px;
height: 170px;
margin-left: 75px;
overflow: hidden;
background: #000;
content: '';
position: absolute;
z-index: 3000;
box-shadow: inset 1px 1px 7px 1px #777;
cursor: auto;
}
}
.key > p {
position: absolute;
bottom: 5%;
font-size: 3em;
left: 40%;
color: rgba(40,40,51,1);
}
.whiteBg {
background-color: white;
}
.on-off > button {
&:hover {
background: lightgreen;
}
}
.strict-mode > button {
&:hover {
background: crimson;
}
}
/* hide black key on the B key */
#b {
width: 100px;
height: 100px;
min-height: 100%;
border: 1px solid black;
position: relative;
&:after {
opacity: 0;
}
}
button {
outline: 0;
color: #000;
transition: background 500ms ease-in-out, opacity 300ms ease-in-out;
width: 100px;
height: 40px;
border: 0;
cursor: pointer;
&:hover {
opacity: 0.8;
background-position: 100%;
}
}
#helpText {
margin-top: 3em;
font-size: 0.9em
}
<link href="https://fonts.googleapis.com/css?family=Boogaloo" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment