Skip to content

Instantly share code, notes, and snippets.

@Jean13
Created January 26, 2016 03:40
Show Gist options
  • Save Jean13/692ddd8eb16333107ca7 to your computer and use it in GitHub Desktop.
Save Jean13/692ddd8eb16333107ca7 to your computer and use it in GitHub Desktop.
Jean's Dune Simon Game
html
h1#title Jean's
h2#sub Dune
body
.wrap
.wrap-in
.row
#3.top-left.inline.push.green.unclickable
#2.top-right.inline.push.red.but.unclickable
.row
#1.bottom-left.inline.push.yellow.unclickable
#0.bottom-right.inline.push.blue.but.unclickable
.center
h1.brand
| Simon
span.small ®
.row
.display.inline
h1.count.led-off --
h3.label Count
.btn-box.inline
#start.round-btn.full-red.but.clickable
h3.label Start
.btn-box.inline
#mode.round-btn.but.clickable
h3.label Strict
#mode-led.led
.row.bot
h3.label.inline Off
.switch-slot.inline
#power.switch
h3.label.inline On

Jean's Dune Simon Game

A simple Simon game in a desert setting. Win by getting a series of 20 steps correct!

A Pen by Jean on CodePen.

License.

$(document).ready(function() {
var AudioContext = window.AudioContext ||
window.webkitAudioContext ||
false;
if (!AudioContext) {
alert("Oops! Your browser currently does not support the full game. Please, download the latest version of Google Chrome for the best playing experience.");
} else {
var audioCtx = new AudioContext();
var frequencies = [329.63, 261.63, 220, 164.81];
var errOsc = audioCtx.createOscillator();
errOsc.type = 'triangle';
errOsc.frequency.value = 110;
errOsc.start(0.0);
var errNode = audioCtx.createGain();
errOsc.connect(errNode);
errNode.gain.value = 0;
errNode.connect(audioCtx.destination);
var ramp = 0.1;
var vol = 0.5;
var gameStatus = {};
gameStatus.reset = function() {
this.init();
this.strict = false;
};
gameStatus.init = function() {
this.lastPush = $('#0');
this.sequence = [];
this.tStepInd = 0;
this.index = 0;
this.count = 0;
this.lock = false;
};
var oscillators = frequencies.map(function(frq) {
var osc = audioCtx.createOscillator();
osc.type = 'sine';
osc.frequency.value = frq;
osc.start(0.0);
return osc;
});
var gainNodes = oscillators.map(function(osc) {
var g = audioCtx.createGain();
osc.connect(g);
g.connect(audioCtx.destination);
g.gain.value = 0;
return g;
});
function playGoodTone(num) {
gainNodes[num].gain.linearRampToValueAtTime(vol, audioCtx.currentTime + ramp);
gameStatus.currPush = $('#' + num);
gameStatus.currPush.addClass('light');
};
function stopGoodTones() {
if (gameStatus.currPush)
gameStatus.currPush.removeClass('light');
gainNodes.forEach(function(g) {
g.gain.linearRampToValueAtTime(0, audioCtx.currentTime + ramp);
});
gameStatus.currPush = undefined;
gameStatus.currOsc = undefined;
};
function playErrTone() {
errNode.gain.linearRampToValueAtTime(vol, audioCtx.currentTime + ramp);
};
function stopErrTone() {
errNode.gain.linearRampToValueAtTime(0, audioCtx.currentTime + ramp);
};
function gameStart() {
resetTimers();
stopGoodTones();
stopErrTone();
$('.count').text('--').removeClass('led-off');
flashMessage('--', 1);
gameStatus.init();
addStep();
}
function setTimeStep(num) {
var tSteps = [1250, 1000, 750, 500];
if (num < 4)
return tSteps[0];
if (num < 8)
return tSteps[1];
if (num < 12)
return tSteps[2];
return tSteps[3];
}
function notifyError(pushObj) {
stopGoodTones();
playErrTone();
if (pushObj)
pushObj.addClass('light');
gameStatus.toHndl = setTimeout(function() {
stopErrTone();
if (pushObj)
pushObj.removeClass('light');
gameStatus.toHndlSt = setTimeout(function() {
if (gameStatus.strict)
gameStart()
else
playSequence();
}, 1000);
}, 1000);
flashMessage('X', 2);
};
function notifyWin() {
var cnt = 0;
var last = gameStatus.lastPush.attr('id');
gameStatus.seqHndl = setInterval(function() {
playGoodTone(last);
gameStatus.toHndl = setTimeout(stopGoodTones, 80);
cnt++;
if (cnt === 8) {
clearInterval(gameStatus.seqHndl);
}
}, 160);
flashMessage('**', 2);
}
function flashMessage(msg, times) {
$('.count').text(msg);
var lf = function() {
$('.count').addClass('led-off');
gameStatus.toHndlFl = setTimeout(function() {
$('.count').removeClass('led-off');
}, 250);
};
var cnt = 0;
lf();
gameStatus.flHndl = setInterval(function() {
lf();
cnt++;
if (cnt === times)
clearInterval(gameStatus.flHndl);
}, 500)
};
function displayCount() {
var p = (gameStatus.count < 10) ? '0' : '';
$('.count').text(p + (gameStatus.count + ''));
}
function playSequence() {
stopGoodTones();
var i = 0;
gameStatus.index = 0;
gameStatus.seqHndl = setInterval(function() {
$('.push').removeClass('light');
displayCount();
gameStatus.lock = true;
playGoodTone(gameStatus.sequence[i]);
gameStatus.toHndl = setTimeout(stopGoodTones, gameStatus.timeStep / 2 - 10);
i++;
if (i === gameStatus.sequence.length) {
clearInterval(gameStatus.seqHndl);
$('.push').removeClass('unclickable').addClass('clickable');
gameStatus.lock = false;
gameStatus.toHndl = setTimeout(notifyError, 5 * gameStatus.timeStep);
}
}, gameStatus.timeStep);
};
function addStep() {
gameStatus.timeStep = setTimeStep(gameStatus.count++);
gameStatus.sequence.push(Math.floor(Math.random() * 4));
gameStatus.toHndl = setTimeout(playSequence, 500);
};
function resetTimers() {
clearInterval(gameStatus.seqHndl);
clearInterval(gameStatus.flHndl);
clearTimeout(gameStatus.toHndl);
clearTimeout(gameStatus.toHndlFl);
clearTimeout(gameStatus.toHndlSt);
};
function pushColor(pushObj) {
clearTimeout(gameStatus.toHndl);
var pushNr = pushObj.attr('id');
if (pushNr == gameStatus.sequence[gameStatus.index] && gameStatus.index < gameStatus.sequence.length) {
playGoodTone(pushNr);
gameStatus.lastPush = pushObj;
gameStatus.index++;
if (gameStatus.index < gameStatus.sequence.length) {
gameStatus.toHndl = setTimeout(notifyError, 5 * gameStatus.timeStep);
} else if (gameStatus.index == 20) {
$('.push').removeClass('clickable').addClass('unclickable');
gameStatus.toHndl = setTimeout(notifyWin, gameStatus.timeStep);
} else {
$('.push').removeClass('clickable').addClass('unclickable');
addStep();
}
} else {
$('.push').removeClass('clickable').addClass('unclickable');
notifyError(pushObj);
}
}
$('.push').mousedown(function() {
pushColor($(this));
});
$('*').mouseup(function(e) {
e.stopPropagation();
if (!gameStatus.lock)
stopGoodTones();
});
function toggleStrict() {
$('#mode-led').toggleClass('led-on');
gameStatus.strict = !gameStatus.strict;
}
$('.switch-slot').click(function() {
$('#power').toggleClass('switch-on');
if ($('#power').hasClass('switch-on') === false) {
gameStatus.reset();
$('.count').text('--');
$('.count').addClass('led-off');
$('#mode-led').removeClass('led-on');
$('.push').removeClass('clickable').addClass('unclickable');
$('#start').off('click');
$('#mode').off('click');
$('.btn').removeClass('unclickable').addClass('clickable');
resetTimers();
stopGoodTones();
stopErrTone();
} else {
$('.btn').removeClass('unclickable').addClass('clickable');
$('.count').removeClass('led-off');
$('#start').click(gameStart);
$('#mode').click(toggleStrict);
}
});
gameStatus.reset();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
@import url(https://fonts.googleapis.com/css?family=Cinzel|Philosopher|Kreon|Inconsolata|Oxygen|Geo);
$midBrown: #595530;
$darkPurple: #260833;
$opaqueRed: #430710;
$redRed: #DC0D29;
$sand: #b8b264;
$darkGreen: #003e0b;
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
text-transform: uppercase;
vertical-align: baseline;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
html{
background-image: url('http://tevfikceritoglu.com/resimler/arkaplan.jpg');
}
#title {
font-family: 'Cinzel';
text-align: center;
color: white;
font-size: 28px;
}
#sub {
text-align: center;
color: $midBrown;
font-size: 24px;
text-shadow: 1px 1px 2px brown;
margin-top: 1%;
margin-bottom: 1%;
}
.inline{
display: inline-block;
}
.push{
position : relative;
width: 200px;
height: 200px;
background-color: grey;
border: 12px solid;
border-color: $sand;
}
.row{
margin-bottom: -4px;
}
.bottom-right{
border-bottom-right-radius: 100%;
}
.bottom-left{
border-bottom-left-radius: 100%;
}
.top-left{
border-top-left-radius: 100%;
}
.top-right{
border-top-right-radius: 100%;
}
.wrap{
width: 472px;
height: 472px;
border-radius: 100%;
position: relative;
text-align: center;
margin: auto;
background-color: $darkPurple;
top: 10vh;
box-shadow: 0px 0px 12px #222;
}
.wrap-in{
position: relative;
top: 12px;
}
.center{
width: 220px;
height: 220px;
position: absolute;
border-radius: 100%;
top: 50%;
left: 50%;
margin: -122px 0 0 -122px;
background-color: #001a49;
border: 12px solid;
border-color: $sand;
}
.brand{
font-family: 'Oxygen';
color: $midBrown;
font-size: 3.2em;
margin-top: 35px;
}
.brand .small{
font-size: 0.3em;
position: relative;
top: -20px;
}
.count{
font-family: 'Cinzel';
color: #DC0D29;
padding: 0px;
font-size: 2em;
width: 50px;
background-color: #32050C;
position: relative;
border: 4px solid #222;
border-radius: 10px;
margin: auto;
}
.round-btn{
width: 20px;
height: 20px;
position: relative;
background-color: yellow;
border-radius: 100%;
border: 4px solid #444;
box-shadow : 0px 2px 3px #222;
margin: auto;
top: -5px;
}
.round-btn:active{
box-shadow: 0 1px 1px #292929;
top: -4px;
}
.clickable{
pointer-events: auto;
cursor: pointer;
}
.unclickable{
pointer-events: none;
}
.led{
width: 6px;
height: 6px;
background-color: #32050C;
border-radius: 100%;
position: absolute;
left: 0;
right: 0;
margin: auto;
border: 2px solid #222;
top: -18px;
}
.led-on{
background-color: $redRed;
}
.led-off{
color: $opaqueRed;
}
.label{
color : $midBrown;
font-family : 'Inconsolata';
font-size: 12px;
margin-top: 5px;
text-align: center;
font-weight: bold;
}
.display{
width : 60px;
position: relative;
text-align: center;
}
.btn-box{
width : 50px;
position: relative;
}
.switch-slot{
height: 20px;
width: 40px;
background-color : #222;
position: relative;
top: 5px;
border-radius: 2px;
cursor: pointer;
}
.switch{
height: 16px;
width: 16px;
border-radius: 4px;
background-color : #3193DE;
position: relative;
border : 2px solid #333;
}
.switch-on{
left: 20px;
}
.row.bot{
margin-top: 10px;
}
.full-red{
background-color: #FC0102;
}
.red{
background-color: #9f0f17;
}
.green{
background-color: #00a74a;
}
.yellow{
background-color: #cca707;
}
.blue{
background-color: #094a8f;
}
.yellow.light{
background-color: #fed93f;
}
.blue.light{
background-color: #1c8cff;
}
.red.light{
background-color: #ff4c4c;
}
.green.light{
background-color: #13ff7c;
}
@media screen and (max-width: 500px){
.wrap {
top: 40px;
-moz-transform: scale(0.6);
-ms-transform: scale(0.6);
-o-transform: scale(0.6);
-webkit-transform: scale(0.6);
transform: scale(0.6);
-o-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
transform-origin: 0 0;
left: 50%;
margin-left: -142px;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment