Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added leaderboard #18

Open
wants to merge 1 commit into
base: gh-pages
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion game.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ var Game = function (cols, rows, number_of_bombs, emojiset, twemoji) {
this.number_of_bombs = Number(number_of_bombs)
this.rate = number_of_bombs / this.number_of_cells
this.numbermoji = [this.emojiset[0], '1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣']

this.init()
}

Expand Down Expand Up @@ -148,6 +147,9 @@ Game.prototype.resetMetadata = function () {
document.querySelector('.result-emoji').textContent = ''
document.querySelector('.default-emoji').innerHTML = this.twemoji ? twemoji.parse('😀') : '😀'
document.querySelector('.js-settings').innerHTML = this.twemoji ? twemoji.parse('🔧') : '🔧'
document.querySelector('.js-leaderboard').innerHTML = this.twemoji ? twemoji.parse('🏆') : '🏆'
document.getElementsByClassName('hurray')[0].innerHTML = this.twemoji ? twemoji.parse('🎊') : '🎊'
document.getElementsByClassName('hurray')[1].innerHTML = this.twemoji ? twemoji.parse('🎊') : '🎊'
}

Game.prototype.startTimer = function () {
Expand Down Expand Up @@ -224,6 +226,11 @@ Game.prototype.showMessage = function () {
document.querySelector('.wrapper').classList.add(this.result)
document.getElementById('timer').textContent = seconds
document.getElementById('result').innerHTML = this.twemoji ? twemoji.parse(emoji) : emoji

if(winner){
//if the player won check if his score gets into the leaderboard
leaderboard.checkScore(this.moves, seconds)
}
}

// console documentation
Expand Down
128 changes: 115 additions & 13 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<!-- haiiii https://github.com/twitter/twemoji is awesome -->
<script src="http://twemoji.maxcdn.com/twemoji.min.js"></script>
<script src="game.js"></script>
<script src="leaderboard.js"></script>

<style type="text/css">
body {
Expand Down Expand Up @@ -159,6 +160,12 @@
display: inline-block;
min-width: 250px;
}
#high-scores-title{
text-align: center;
font-family: 'Exo 2', sans-serif;
font-size: 21px;
font-weight: bold;
}

.won .default-emoji,
.lost .default-emoji {
Expand All @@ -173,6 +180,17 @@
.lost {
box-shadow: 0 0 1px #f00;
}
#scores{
margin-top:10px;
}
.score{
width: 100%;
font-size: 1rem;
text-align: center;
font-family: 'Exo 2', sans-serif;
margin: 0;
margin-bottom: 5px;
}

.won {
box-shadow: 0 0 1px #1a1;
Expand Down Expand Up @@ -200,34 +218,80 @@
letter-spacing: 1px;
content: attr(title);
}

.settings {
.menubuttons{
position: absolute;
width: 40px;
height: 40px;
top: -20px;
right: -20px;
background-color: #f4f4f4;
text-align: center;
border-radius: 25px;
padding: 2px 8px;
border: 5px solid #fff;
cursor: pointer;
z-index: 1;
top: -20px;
}
.leaderboard{
left: -20px;
}
#settings-wrap{
width:220px;
}
.settings {
right: -20px;
}
.leaderboard .emoji{
width : 15px;
margin : 6px 0;
}

.settings .emoji {
width: 15px;
margin: 6px 0;
}

.settings-popup {
.popup{
position: relative;
padding: 10px;
width: 100%;
}
.left{
float:left;
}
.leaderboard-popup{
display: none;
}
.hurray{
width: 2%;
height: 35px;
}
.highscore-tite{
width: 74%;
margin-left: 12%;
}
.hurray .emoji{
width: 10%;
position: absolute;
padding: 10px;
}

.overlay-popup{
display:none;
font-family: 'Exo 2', sans-serif;
width: 100%;
margin-top: 30%;
position: absolute;
background-color: white;
z-index: 1;
border: 3px solid #f4f4f4;
border-radius: 10px;
padding: 15px;
font-size: 22px;
}

.settings-popup {
display: none;
}

leaderboard-popup

.settings-popup button {
width: 100%;
margin: 0;
Expand All @@ -242,7 +306,10 @@
}

.settings-popup.show ~ * {
visibility: hidden;
display: none;
}
.leaderboard-popup.show ~ * {
display: none;
}

.divider {
Expand All @@ -267,8 +334,10 @@
</head>
<body>
<div class="wrapper">
<button class="settings js-settings"></button>
<div class="js-settings-popup settings-popup">
<button class="settings js-settings menubuttons"></button>
<button class="leaderboard js-leaderboard menubuttons"></button>
<div class="js-settings-popup settings-popup popup">
<div id="settings-wrap">
<div class="flex-table">
<label class="btn flex-cell-min"><input type="radio" name="emoji" id="twemoji" checked> Twemoji</label>
<label class="btn flex-cell-min"><input type="radio" name="emoji" id="emoji"> Native emoji</label>
Expand All @@ -288,6 +357,16 @@
<option value="☀ ⚡ ☔ ☁️">☀ ⚡ ☔ ☁️</option>
</select>
<button class="js-popup-new-game btn">Restart Game</button>
</div>
</div>
<div class="js-leaderboard-popup leaderboard-popup popup">
<p id="high-scores-title">High Scores</p>
<div id="scores"></div>
</div>
<div id="highscore-popup" class="overlay-popup">
<div class="hurray left"></div>
<div class="highscore-tite left">New High Score!</div>
<div class="hurray left"></div>
</div>
<a href="#" class="action-btn js-new-game">
<span class="default-emoji"></span>
Expand All @@ -310,14 +389,37 @@
var bombs = document.getElementById('bombs')

game = new Game(cols.value, rows.value, bombs.value, emojiset, document.getElementById('twemoji').checked)
leaderboard = new Leaderboard()
//initializes highscores on first load only
leaderboard.initScores()

document.querySelector('.js-new-game').addEventListener('click', restart)
document.querySelector('.js-popup-new-game').addEventListener('click', restart)

document.querySelector('.js-settings').addEventListener('click', function() {
var list = document.querySelector('.js-settings-popup').classList
list.contains('show') ? list.remove('show') : list.add('show')
openPopup("settings")
//sends the type of popup that needs to be opened
})

document.querySelector('.js-leaderboard').addEventListener('click', function(){
openPopup("leaderboard")
})
function openPopup(clicked){
//gets all class lists and hides the unwanted popups and shows the wanted one
var settingsList = document.querySelector('.js-settings-popup').classList, leaderboardList = document.querySelector('.js-leaderboard-popup').classList
switch(clicked){
case "settings":
settingsList.contains('show') ? settingsList.remove('show') : settingsList.add('show')
if(leaderboardList.contains('show')) leaderboardList.remove('show')
break;
case "leaderboard":
leaderboardList.contains('show') ? leaderboardList.remove('show') : leaderboardList.add('show')
if(settingsList.contains('show')) settingsList.remove('show')
break;
default:
break;
}
}

function restart () {
clearInterval(game.timer)
Expand Down
93 changes: 93 additions & 0 deletions leaderboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
var Leaderboard = function(){
this.scoresArr = []//array that stores the highscores
}

Leaderboard.prototype.updateScoreView = function(place, time, moves){
//function which creates new scores in the highscores view
var node, textnode

node = document.createElement("p")
node.className = "score"
textnode = document.createTextNode(place + ". " + "time: " + time + ", " + "moves: " + moves)
node.appendChild(textnode)
node.appendChild(document.createElement("br"))
document.getElementById("scores").appendChild(node)
}

//initializes the highscores when page loads
Leaderboard.prototype.initScores = function(){
//if there isn't a saved leaderboard
var node, textnode

node = document.getElementById("scores");
while (node.firstChild) {
node.removeChild(node.firstChild);
}
if(!localStorage.getItem("scores")){
//create a new leaderboard
this.scoresArr = []

function addScore(i, arr) {
return function() {
arr.push({place: i, moves: 0, time: 0 })
Leaderboard.prototype.updateScoreView(i, 0, 0)
};
}
//creating a leaderboard with 10 scores
for(var i = 1; i <= 10; i++ ){
//wrapping the function with another function to avoid closure problem
addScore(i,this.scoresArr)()
}
//stores the scores in the browser's localStorage
localStorage.setItem("scores", JSON.stringify(this.scoresArr))
}else{
//if there's already a leaderboard retrive it
this.scoresArr = JSON.parse(localStorage.getItem("scores"))
for(var i = 0, length = this.scoresArr.length; i < length; i++){
Leaderboard.prototype.updateScoreView(i + 1, this.scoresArr[i].time, this.scoresArr[i].moves)
}
}
}

//check if there's a new highscore
Leaderboard.prototype.checkScore = function(moves, time){

var scoreTime, //time of a specific score in the array
scoresArr = this.scoresArr, //the leaderboard array
addFlag = false, //flag for checking if the score had been added
time = parseFloat(time) // takes the time and turns it to float

for(var i = 0, length = scoresArr.length; i < length; i++){

scoreTime = scoresArr[i].time
//if not added
if(!addFlag){
//if the time is 0
if(scoreTime == 0){
//add the score
addFlag = true
scoresArr.splice(i,0,{place:i+1,moves : moves, time:time})
}else if(time <= scoreTime){
//if the player's time is shorter than the current score replace it'
addFlag = true
scoresArr.splice(i,0,{place:i+1,moves : moves, time:time})
}
}else{
//if the score had been added
scoresArr[i].place++ //change the place of each of the following scores
if(i == length - 1){
scoresArr.pop() //remove the last score so there are only 10 score
}
}
}
if(addFlag){
//update the localstorage data
localStorage.setItem("scores", JSON.stringify(this.scoresArr))//update localstorage with the new leaderboard
//init scores arr and view
this.initScores()
//show new highscore message
document.getElementById("highscore-popup").style.display = "block"
//hide it again after 3 seconds
setTimeout(function(){ document.getElementById("highscore-popup").style.display = "none" }, 3000);
}
}