Last active
June 23, 2016 01:34
-
-
Save programus/2192639 to your computer and use it in GitHub Desktop.
Javascript Game Memory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame | |
Remove this if you use the .htaccess --> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> | |
<title>memory</title> | |
<meta name="description" content="A memory game." /> | |
<meta name="author" content="Programus" /> | |
<meta name="viewport" content="width=device-width; initial-scale=1.0" /> | |
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> | |
<script src="http://www.codebase.es/riffwave/riffwave.js" type="text/javascript"></script> | |
<!-- Replace favicon.ico & apple-touch-icon.png in the root of your domain and delete these references --> | |
<link rel="shortcut icon" href="images/memory.ico" /> | |
<link rel="stylesheet" href="memory.css" /> | |
<script type="text/javascript" src="memory.js"></script> | |
</head> | |
<body> | |
<div> | |
<header> | |
<h1>memory</h1> | |
</header> | |
<div id="game-panel" align="center"> | |
<noscript>This page need javascript...</noscript> | |
<div id="settings"> | |
<span id="matrix-size-span"> | |
<select id="matrix-size" name="matrix-size"> | |
</select> | |
</span> | |
</div> | |
<hr /> | |
<div> | |
<table id="matrix" class="matrix"> | |
<tbody class="matrix" id="matrix-body"></tbody> | |
</table> | |
</div> | |
<div id="score-panel"> | |
<span id="score-bar"> | |
<label for="score">Score:</label> | |
<span id="score" class="score-value">0</span> | |
</span> | |
</div> | |
<div> | |
<input type="button" id="start-action" class="start-button" value="START" /> | |
</div> | |
</div> | |
<footer> | |
</footer> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
table.matrix,tbody.matrix { | |
border-style:double; | |
border-width:3px; | |
border-color:#000000; | |
border-spacing:0; | |
padding:0; | |
margin:0; | |
background-color:#aaffff; | |
} | |
table.matrix td { | |
border-style:solid; | |
border-width:1px; | |
border-color:#AAAAAA; | |
padding:0; | |
margin:0; | |
width:1.5em; | |
height:1.5em; | |
} | |
table.matrix td.action { | |
background:#ffffff; | |
cursor:pointer; | |
} | |
table.matrix td.fading { | |
background:#ffffff; | |
} | |
table.matrix td.action:hover { | |
background:#ccffcc; | |
cursor:pointer; | |
} | |
table.matrix td.error { | |
border-color:#ff0000; | |
} | |
table.matrix td.error-action { | |
border-color:#aaff00; | |
} | |
table.matrix td.show { | |
background:#dddddd; | |
} | |
#matrix-size-span { | |
width:3em; | |
overflow-x:hidden; | |
display:inline-block; | |
background-image:url("../select-arrow.png"); | |
background-repeat:no-repeat; | |
background-position:center right; | |
border: 1px solid #ccc; | |
} | |
#matrix-size-span.disabled { | |
background-color:#777777; | |
} | |
#matrix-size { | |
color:#777777; | |
width:5em; | |
background: transparent; | |
border: 0px; | |
cursor:pointer; | |
} | |
#matrix-size:disabled { | |
color:#444444; | |
text-decoration:none; | |
text-shadow:1px 1px 0px #aaaaaa; | |
cursor:default; | |
} | |
#score.updating { | |
color:#00aa00; | |
background:#dddd88; | |
} | |
#score.stable { | |
background:inherit; | |
} | |
#score-panel { | |
margin-top:0.3em; | |
margin-bottom:0.2em; | |
} | |
#score-bar { | |
padding:2px; | |
} | |
#score-bar.finished { | |
color:#444444; | |
background:#edcfaa; | |
} | |
#score-bar.normal { | |
color:#777777; | |
} | |
#game-panel { | |
} | |
#start-action { | |
background-color:#ededed; | |
border:1px solid #dcdcdc; | |
display:inline-block; | |
color:#777777; | |
font-family:arial; | |
font-size:11px; | |
font-weight:bold; | |
padding:2px 5px; | |
text-decoration:none; | |
cursor:pointer; | |
} | |
#start-action:disabled { | |
background-color:#777777; | |
color:#444444; | |
border:1px solid #444444; | |
text-decoration:none; | |
text-shadow:1px 1px 0px #aaaaaa; | |
cursor:default; | |
} | |
#start-action:enabled:hover { | |
background-color:#dfdfdf; | |
} | |
#start-action:enabled:active { | |
position:relative; | |
top:1px; | |
} | |
h1 { | |
text-align:center; | |
color:#444444; | |
text-decoration:none; | |
text-shadow:1px 1px 0px #aaaaaa; | |
} | |
body { | |
background-color:#ededed; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Programus | |
*/ | |
var GLOBAL = function( ) { | |
var LOWEST_LEVEL = 3; | |
var NODES = [ | |
261.63 , | |
277.18 , | |
293.66 , | |
311.13 , | |
329.63 , | |
349.23 , | |
369.99 , | |
392 , | |
415.3 , | |
440 , | |
466.16 , | |
493.88 , | |
/* | |
523.26 , | |
554.37 , | |
587.33 , | |
622.25 , | |
659.26 , | |
698.46 , | |
739.99 , | |
783.99 , | |
830.61 , | |
880 , | |
932.33 , | |
987.77 , | |
*/ | |
]; | |
var audio; | |
try { | |
audio = new Audio(); | |
} catch(e) { | |
// If browser is not support Audio. create a fake one. | |
audio = { | |
src: null, | |
play: function(){}, | |
}; | |
} | |
var wave = new RIFFWAVE(); | |
wave.header.sampleRate = 44100; | |
wave.header.numChannel = 1; | |
var that = { | |
showSeq: [], | |
actionSeq: [], | |
currLevel: 0, | |
score: 0, | |
state: 'finished', | |
}; | |
that.playSound = function(index) { | |
var soundLevel = parseInt(index / NODES.length); | |
var vol = 96 / (soundLevel / 2 + 1) + 32; | |
var frequency = NODES[index % NODES.length] * Math.pow(2, soundLevel); | |
var samples = []; | |
var samples_length = 44100; // Plays for 1 second (44.1 KHz) | |
for (var i=0; i < samples_length ; i++) { // fills array with samples | |
var t = i/samples_length; // time from 0 to 1 | |
samples[i] = Math.sin(frequency*2*Math.PI*t); // wave equation (between -1,+1) | |
samples[i] *= (1-t); // "fade" effect (from 1 to 0) | |
samples[i] = 128 + vol * samples[i]; | |
} | |
wave.Make(samples); | |
audio.src = wave.dataURI; | |
audio.play(); | |
}; | |
that.playCell = function(cell) { | |
var index = that.getCellIndex(cell); | |
if (index !== null) { | |
that.playSound(that.getCellIndex(cell)); | |
} | |
}; | |
that.getCellIndex = function(cell) { | |
var c; | |
if (cell.hasOwnProperty('length')) { | |
if (cell.length > 0) { | |
c = cell[0]; | |
} else { | |
c = null; | |
} | |
} else { | |
c = cell; | |
} | |
return c === null ? null : parseInt(c.id.slice('td-'.length)); | |
}; | |
that.generateShowSeq = function(arr, level, max) { | |
return function(level, max) { | |
arr.splice(0, arr.length); | |
for (var i = 0; i < level; i++) { | |
var rand = null; | |
while (rand === null || (i < max && $.inArray(rand, arr) >= 0)) { | |
rand = parseInt(Math.random() * max); | |
} | |
arr[i] = rand; | |
} | |
return arr; | |
}; | |
}(that.showSeq); | |
that.clearMatrix = function() { | |
var tds = $('#matrix td'); | |
if (tds.hasClass('show')) { | |
tds.attr('class', 'show'); | |
} else { | |
tds.attr('class', 'action'); | |
} | |
tds.removeAttr('title'); | |
}; | |
that.enableAction = function(isEnable) { | |
if (isEnable) { | |
$('#matrix td').removeClass('show').addClass('action'); | |
} else { | |
$('#matrix td').removeClass('action').addClass('show'); | |
} | |
}; | |
that.enableSettings = function(isEnable) { | |
$('#matrix-size').attr('disabled', !isEnable); | |
if (isEnable) { | |
$('#matrix-size-span').removeClass('disabled'); | |
} else { | |
$('#matrix-size-span').addClass('disabled'); | |
} | |
}; | |
that.enableStartButton = function(isEnable) { | |
$('#start-action').attr('disabled', !isEnable); | |
}; | |
that.finishedScore = function(isFinished) { | |
$('#score-bar').attr('class', isFinished ? 'finished' : 'normal'); | |
}; | |
that.nextLevel = function() { | |
that.enableAction(false); | |
level = that.currLevel + LOWEST_LEVEL; | |
that.currLevel++; | |
var max = $('#matrix td').length; | |
that.showQeustion(that.generateShowSeq(level, max)); | |
}; | |
that.showQeustion = function(seq) { | |
for (var i = 0; i < seq.length; i++) { | |
var v = seq[i]; | |
setTimeout((function(num) { | |
return function() { | |
that.highlightCell(num); | |
}; | |
})(v), 1000 * i); | |
} | |
setTimeout(function() { | |
that.startAction(); | |
}, 1000 * seq.length); | |
}; | |
that.startAction = function() { | |
that.enableAction(true); | |
that.actionSeq.splice(0, that.actionSeq.length); | |
}; | |
that.highlightCell = function(cell) { | |
if (cell % 1 === 0) { | |
cell = $('#td-' + cell); | |
} | |
that.playCell(cell); | |
cell.addClass('fading'); | |
cell.fadeOut(500).fadeIn(500); | |
cell.removeClass('fading'); | |
}; | |
that.errorCell = function(cell, type) { | |
if (cell % 1 === 0) { | |
cell = $('#td-' + cell); | |
} | |
cell.addClass(type === 'action' ? 'error-action' : 'error'); | |
cell.attr('title', type === 'action' ? 'you clicked' : 'it should be'); | |
}; | |
that.refreshActionSeq = function(cell) { | |
var index = that.getCellIndex(cell); | |
if (index !== null) { | |
that.actionSeq.push(that.getCellIndex(cell)); | |
} | |
}; | |
that.refreshScore = function() { | |
that.score += (1 << (that.currLevel + LOWEST_LEVEL)) * $('#matrix td').length; | |
var plusScore = function() { | |
var scoreCtrl = $('#score'); | |
var score = parseInt(scoreCtrl.text()); | |
if (score < that.score) { | |
score += Math.max(parseInt(that.score / 100), 1); | |
if (score > that.score) { | |
score = that.score; | |
} | |
scoreCtrl.text(score); | |
scoreCtrl.attr('class', 'updating'); | |
setTimeout(plusScore, 10); | |
} else { | |
scoreCtrl.attr('class', 'stable'); | |
setTimeout(that.nextLevel, 100); | |
} | |
}; | |
plusScore(); | |
}; | |
that.judge = function() { | |
for (var i = 0; i < that.actionSeq.length; i++) { | |
if (that.showSeq[i] !== that.actionSeq[i]) { | |
that.errorCell(that.showSeq[i], 'show'); | |
that.errorCell(that.actionSeq[i], 'action'); | |
return false; | |
} | |
} | |
return true; | |
}; | |
that.startGame = function() { | |
that.currLevel = 0; | |
that.score = 0; | |
that.enableSettings(false); | |
that.enableStartButton(false); | |
that.clearMatrix(); | |
that.nextLevel(); | |
that.finishedScore(false); | |
}; | |
that.finishGame = function() { | |
that.enableAction(false); | |
that.enableSettings(true); | |
that.enableStartButton(true); | |
that.finishedScore(true); | |
}; | |
return that; | |
}( ); | |
$().ready(function() { | |
if ($.browser.msie) { | |
// sorry, not support IE. | |
$('#game-panel').text('This game cannot be run on IE. Please use firefox or chrome.'); | |
return; | |
} | |
// set up settings. | |
for (var i = 2; i < 9; i++ ) { | |
$('#matrix-size') | |
.append($('<option>') | |
.attr('value', i) | |
.text(i + 'x' + i)); | |
} | |
// setting matrix | |
$('#matrix-size').change(function() { | |
var n = this.value; | |
var html4matrix = $('<tbody>'); | |
html4matrix.addClass('matrix'); | |
for (var r = 0; r < n; r++) { | |
var row = $('<tr>'); | |
for (var c = 0; c < n; c++) { | |
var num = r * n + c; | |
var cell = $('<td>').attr('id', 'td-' + num); | |
cell.attr('class', 'show'); | |
cell.click(function(theCell) { | |
return function() { | |
if (theCell.attr('class') === 'action') { | |
GLOBAL.highlightCell(theCell); | |
setTimeout(function(){ | |
GLOBAL.refreshActionSeq(theCell); | |
if (!GLOBAL.judge()) { | |
GLOBAL.finishGame(); | |
} else if (GLOBAL.actionSeq.length >= GLOBAL.showSeq.length) { | |
GLOBAL.refreshScore(); | |
} | |
}, 1000); | |
} | |
}; | |
}(cell)); | |
row.append(cell); | |
} | |
html4matrix.append(row); | |
} | |
$('#matrix').html(html4matrix); | |
}); | |
$('#matrix-size').change(); | |
$('#start-action').click(function() { | |
$('#score').text(0); | |
GLOBAL.startGame(); | |
}); | |
GLOBAL.finishGame(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment