Last active
December 14, 2015 14:29
A rewrite of memory.js to be actually readable.
This file contains hidden or 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
/* | |
A rewrite of memory.js to be actually readable. | |
Written by Jonathan Cooper. | |
*/ | |
//Array of cards to display in the game | |
var cards = ["0", "A", "2", "3", "4", "5", "6", "7", "8", "9", "J", "Q", "K", "♥", "♠", "♦", "♣"]; | |
//Max of 24 attempts (48 clicks) | |
var tries = 48; | |
//Attempt counter | |
var attempts = 0; | |
var pairsLeft = 8; | |
var section = document.getElementsByTagName('section')[0]; | |
var canvas = document.getElementsByTagName('canvas')[0]; | |
document.body.clientWidth; // fix bug in webkit: http://qfox.nl/weblog/218 | |
//Need to detect if the browser supports local storage, since this entire game depends on it. | |
function supportsLocalStorage() { | |
try { | |
return 'localStorage' in window && window['localStorage'] != null; | |
} catch(e) { | |
return false; | |
} | |
} | |
window.onload = function() { | |
if(!supportsLocalStorage()) { | |
alert("Your browser is too old, bro. Get Chrome."); | |
} | |
else{ | |
var player = new Player("Cooper"); | |
player.loadGame(); | |
var divs = document.getElementsByClassName("c"); | |
for(i=0; i<divs.length; i++) { | |
divs[i].onclick = audio('http://rpg.hamsterrepublic.com/wiki-images/d/db/Crush8-Bit.ogg '); | |
} | |
} | |
} | |
//Sets a CSS class on an element | |
function setClass(element, className) { | |
element.className = 'w '+ className | |
} | |
//Adds vendor prefixes to a style rule | |
function prefix(style) { | |
return ";-webkit-"+ style +";-moz-"+ style +";-o-"+ style; | |
} | |
//Retrieve a random element from an array | |
function randomElement(array) { | |
return array.splice(0 | array.length*Math.random(),1)[0] | |
} | |
//Play a sound. Make it return a function for easy listener creation. | |
//Yay functional programming. | |
function audio(source) { | |
return function() { | |
var audioElement = document.createElement('audio'); | |
audioElement.setAttribute('src', source); | |
audioElement.load(); | |
audioElement.play(); | |
} | |
} | |
//Flips a card | |
function flip(card) { | |
//User still has some attemps left | |
if(attempts < tries) { | |
attempts++; | |
//Update turn counter every 2 clicks | |
document.querySelector("h1").innerHTML = "Turn: "+ parseInt(attempts/2); | |
//Get all visible cards | |
visible = document.querySelectorAll('.v'); | |
first = visible[0]; | |
last = visible[1]; | |
//If 2 cards are showing, both need to be flipped over | |
if(last) { | |
setClass(first, ""); | |
setClass(last, "") | |
} | |
//If a match is found, flip both cards | |
if(first && !last && first != card && first.innerHTML == card.innerHTML) { | |
audio('http://cd.textfiles.com/10000soundssongs/WAV/COWBELL2.WAV ')(); | |
setClass(first, "p"); | |
setClass(card, "p"); | |
pairsLeft--; | |
} | |
//Otherwise, just flip the current card | |
else { | |
setClass(card, "v"); | |
} | |
//Check to see if the game is finished | |
if(pairsLeft == 0) { | |
audio('http://www.earthstation1.com/SFXs/SFX_Wavs/cheer.wav')() | |
alert("You won, bro!"); | |
} | |
} | |
//Max attempts used | |
else { | |
var retry = confirm("Max attempts used! Try again?"); | |
if(retry) { | |
location.reload(); | |
} | |
else { | |
alert("Game over."); | |
} | |
} | |
} | |
function makeGameArea() | |
{ | |
var divNode = document.createElement("mdiv"); | |
divNode.innerHTML | |
="<style>\ | |
/* wrapper for the border of the card */\ | |
.w{" | |
+"width:99px;height:99px;" | |
+"border:10px solid #777\ | |
+margin-top:-30px\ | |
;text-align:center\ | |
;margin:5px\ | |
;float:left" | |
+"\ | |
}\ | |
\ | |
.v .b,.p .b{" | |
+prefix("transform:scale(0)") +"\ | |
}\ | |
/* card */\ | |
.c{" | |
+"width:99px;height:99px;" | |
+"position:absolute;" | |
+"font-size:80px\ | |
}\ | |
/* ♥♠♦♣ on the card */\ | |
b{" | |
+"position:absolute;" | |
+"font-size:24px\ | |
;left:5px\ | |
}\ | |
/* back of the card and ♥♦ are red */\ | |
.b,.r{\ | |
color:red\ | |
}\ | |
/* back of the card */\ | |
.z{\ | |
margin-top:30px\ | |
}\ | |
/* back of the card */\ | |
.b{\ | |
background:url('http://www.bmwblog.com/wp-content/uploads/porsche-cayman-s-03-100x100.jpg')" | |
+prefix("transition:1s") +"\ | |
;margin-top:-35px\ | |
}\ | |
</style>"; | |
document.body.appendChild(divNode); | |
cards[0]=10; | |
//Create pack of cards | |
pack=[]; | |
for(c=13;c<17;c++) { | |
for(i=0;i<13;i++) { | |
pack.push([c%2?' r':'',c,cards[i]]); | |
} | |
} | |
//Place a card on the deck twice to create pairs | |
deck = [] | |
for(k=0; k<8; k++) { | |
deck[k] = deck[k+8] = randomElement(pack) | |
} | |
// start to draw the screen | |
var gameArea='<div style="width:450px">'; | |
// we need to create 16 cards | |
for(i=16;i;i--) { | |
// take out a random element from the cards on the deck | |
card = randomElement(deck), | |
gameArea += '<div id="logo" class="w" onclick="flip(this)"><div class="c f' | |
+card[0] | |
+'"><b>' | |
+cards[card[1]] | |
+'</b>' | |
+card[2] | |
+'</div><div class="c b" ><div class="z"></div></div></div>'; | |
} | |
//return it for later use | |
return gameArea + '</div>'; | |
} | |
//Represents a player of the game | |
function Player(username) { | |
//Get game state from local storage, if it exists, or create a new board | |
this.getGameState = function() { | |
var player = JSON.parse(localStorage.getItem("player")); | |
if(player && player._gameState) { | |
return player.gameState; | |
} | |
return makeGameArea(); | |
}; | |
//Save the current board. | |
this.saveGame = function() { | |
this._gameState = section.innerHTML; | |
localStorage.setItem("player", JSON.stringify(this)); | |
}; | |
//Retrieve a board, or create a new game | |
this.loadGame = function() { | |
section.innerHTML = this._gameState; | |
}; | |
this.getHighScore = function() { | |
var player = JSON.parse(localStorage.getItem("player")); | |
if(player && player._highscore) { | |
return player._highscore; | |
} | |
return 0; | |
}; | |
this.setHighScore = function(score) { | |
if(score < this.getHighScore) { | |
this._highscore = score; | |
} | |
localStorage.setItem("player", JSON.stringify(this)); | |
}; | |
//User object properties. | |
//Link game state and high score to functions | |
//to allow for cleaner abstraction of player state. | |
this.username = username; | |
//Don't access these two properties directly. | |
//They are for INTERNAL USE ONLY. If you need | |
//access to a player's state (save game, etc.), | |
//use the provided methods. | |
this._gameState = this.getGameState(); | |
this._highscore = this.getHighScore(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment