diff --git a/images/lf1.gif b/images/lf1.gif new file mode 100644 index 0000000..7d0eb31 Binary files /dev/null and b/images/lf1.gif differ diff --git a/images/lf10.jpg b/images/lf10.jpg new file mode 100644 index 0000000..7eaa4d4 Binary files /dev/null and b/images/lf10.jpg differ diff --git a/images/lf11.jpg b/images/lf11.jpg new file mode 100644 index 0000000..7e05707 Binary files /dev/null and b/images/lf11.jpg differ diff --git a/images/lf12.jpg b/images/lf12.jpg new file mode 100644 index 0000000..088d88f Binary files /dev/null and b/images/lf12.jpg differ diff --git a/images/lf13.png b/images/lf13.png new file mode 100644 index 0000000..6ef8be2 Binary files /dev/null and b/images/lf13.png differ diff --git a/images/lf2.gif b/images/lf2.gif new file mode 100644 index 0000000..946d947 Binary files /dev/null and b/images/lf2.gif differ diff --git a/images/lf3.jpg b/images/lf3.jpg new file mode 100644 index 0000000..07d71ec Binary files /dev/null and b/images/lf3.jpg differ diff --git a/images/lf4.jpg b/images/lf4.jpg new file mode 100644 index 0000000..fd046a2 Binary files /dev/null and b/images/lf4.jpg differ diff --git a/images/lf5.jpg b/images/lf5.jpg new file mode 100644 index 0000000..f965fe4 Binary files /dev/null and b/images/lf5.jpg differ diff --git a/images/lf6.jpg b/images/lf6.jpg new file mode 100644 index 0000000..a92d29a Binary files /dev/null and b/images/lf6.jpg differ diff --git a/images/lf7.jpg b/images/lf7.jpg new file mode 100644 index 0000000..3bb9120 Binary files /dev/null and b/images/lf7.jpg differ diff --git a/images/lf8.jpg b/images/lf8.jpg new file mode 100644 index 0000000..6e51748 Binary files /dev/null and b/images/lf8.jpg differ diff --git a/images/lf9.jpg b/images/lf9.jpg new file mode 100644 index 0000000..cf0f33e Binary files /dev/null and b/images/lf9.jpg differ diff --git a/index.html b/index.html index 4a7e370..a8c97cd 100644 --- a/index.html +++ b/index.html @@ -5,8 +5,18 @@ + +
+
0
+
+
+
+
+
+
+
diff --git a/javascripts/2048.js b/javascripts/2048.js index 13b971a..fe264b3 100644 --- a/javascripts/2048.js +++ b/javascripts/2048.js @@ -1,63 +1,331 @@ -function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; -} - var Game = function() { - // Game logic and initialization here this.board = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]; + this.newTile = true; this.spawnTile(); this.spawnTile(); + this.newTile = false; + this.score = 0; +}; + +Game.prototype.findFreeSpace = function() { + var spaceJam = []; + var self = this; + for(var r=0; r<4; r++){ + for(var c=0; c<4; c++){ + if (this.board[r][c] === 0) { + spaceJam.push(r.toString() + c.toString()); + } + } + } + + if (spaceJam.length === 0 && !this.movesLeft()){ + self.gameLost(); + }else if (this.newTile) { + return spaceJam[Math.floor(Math.random() * spaceJam.length)]; + } +}; + +Game.prototype.movesLeft = function() { + var r, c; + + for (r=0; r<4; r++) { + for (c=0; c<3; c++) { + if (this.board[r][c] === 0) { + break; + } else if (this.board[r][c].attr('data-val') === this.board[r][c+1].attr('data-val')) { + return true; + } + } + } + for (c=0; c<4; c++) { + for (r=0; r<3; r++) { + if (this.board[r][c] === 0) { + break; + } else if (this.board[r][c].attr('data-val') === this.board[r+1][c].attr('data-val')) { + return true; + } + } + } + return false; }; Game.prototype.spawnTile = function() { - var val = [2, 4][Math.floor(Math.random() * 2)]; - var row = getRandomInt(0, 3); - var col = getRandomInt(0, 3); + var val = Math.random() < 0.9 ? 2 : 4; + space = this.findFreeSpace(); + if (space !== undefined) { + row = space[0]; + col = space[1]; + + new_tile = $('
').attr('data-row', "r" + row).attr('data-col', "c" + col).attr('data-val', val).html(val); + + $(".cells").after(new_tile); - new_tile = $('
').attr('data-row', "r" + row).attr('data-col', "c" + col).attr('data-val', val).html(val); + this.board[row][col] = new_tile; + } +}; - $(".cells").after(new_tile); +Game.prototype.moveLeft = function() { + var rowClone, colClone, cloneIndex, r, c; - this.board[row][col] = val; + for(r=0; r<4; r++){ + cloneIndex = 0; + rowClone = new Array(5).join('0').split('').map(parseFloat); + for(c=0; c<4; c++){ + if (this.board[r][c] !== 0){ + rowClone[cloneIndex] = this.board[r][c]; + cloneIndex++; + } + } + + for (c=0; c<4; c++){ + this.newTile = this.newTile || (rowClone[c] !== this.board[r][c]); + } + this.board[r] = rowClone; + } +}; + +Game.prototype.moveRight = function() { + var rowClone, colClone, cloneIndex, r, c; + + for(r=0; r<4; r++){ + cloneIndex = 3; + rowClone = new Array(5).join('0').split('').map(parseFloat); + for(c=3; c>=0; c--){ + if (this.board[r][c] !== 0){ + rowClone[cloneIndex] = this.board[r][c]; + cloneIndex--; + } + } + + for (c=0; c<4; c++){ + this.newTile = this.newTile || (rowClone[c] !== this.board[r][c]); + } + this.board[r] = rowClone; + } +}; + +Game.prototype.moveUp = function() { + var rowClone, colClone, cloneIndex, r, c; + + for(c=0; c<4; c++){ + cloneIndex = 0; + colClone = new Array(5).join('0').split('').map(parseFloat); + for(r=0; r<4; r++){ + if (this.board[r][c] !== 0){ + colClone[cloneIndex] = this.board[r][c]; + cloneIndex++; + } + } + + for(r=0; r<4; r++){ + this.newTile = this.newTile || (colClone[r] !== this.board[r][c]); + this.board[r][c] = colClone[r]; + } + } +}; + +Game.prototype.moveDown = function() { + var rowClone, colClone, cloneIndex, r, c; + + for(c=0; c<4; c++){ + cloneIndex = 3; + colClone = new Array(5).join('0').split('').map(parseFloat); + for(r=3; r>=0; r--){ + if (this.board[r][c] !== 0){ + colClone[cloneIndex] = this.board[r][c]; + cloneIndex--; + } + } + for(r=3; r>=0; r--){ + this.newTile = this.newTile || (colClone[r] !== this.board[r][c]); + this.board[r][c] = colClone[r]; + } + } }; -Game.prototype.moveTile = function(tile, direction) { - // Game method here +Game.prototype.moveTile = function(direction) { switch(direction) { case 38: //up - console.log('up'); - row = parseInt(tile[0].getAttribute('data-row').slice(-1)); - tile.attr('data-row', "r" + (row - 1)); + this.moveUp(); + this.mergeUp(); + this.moveUp(); + this.updateDisplay(); + this.spawnTile(); + this.newTile = false; break; + case 40: //down - console.log('down'); - row = parseInt(tile[0].getAttribute('data-row').slice(-1)); - tile.attr('data-row', "r" + (row + 1)); + this.moveDown(); + this.mergeDown(); + this.moveDown(); + this.updateDisplay(); + this.spawnTile(); + this.newTile = false; break; + case 37: //left - console.log('left'); - col = parseInt(tile[0].getAttribute('data-col').slice(-1)); - tile.attr('data-col', "c" + (col - 1)); + this.moveLeft(); + this.mergeLeft(); + this.moveLeft(); + this.updateDisplay(); + this.spawnTile(); + this.newTile = false; break; + case 39: //right - console.log('right'); - col = parseInt(tile[0].getAttribute('data-col').slice(-1)); - tile.attr('data-col', "c" + (col + 1)); + this.moveRight(); + this.mergeRight(); + this.moveRight(); + this.updateDisplay(); + this.spawnTile(); + this.newTile = false; break; } }; +Game.prototype.mergeLeft = function() { + for(var r=0; r<4; r++){ + for(var c=0; c<3; c++){ + dom = this.board[r][c]; + nextDom = this.board[r][c+1]; + + if (dom !== 0 && nextDom !== 0) { + val = parseInt(dom.attr('data-val')); + nextVal = parseInt(nextDom.attr('data-val')); + if (val === nextVal){ + score = val*2; + this.updateScore(score); + nextDom.attr('data-val', score).text(score); + this.board[r][c] = 0; + dom.remove(); + } + } + } + } +}; + +Game.prototype.mergeRight = function() { + for(var r=0; r<4; r++){ + for(var c=3; c>=1; c--){ + dom = this.board[r][c]; + nextDom = this.board[r][c-1]; + + if (dom !== 0 && nextDom !== 0) { + val = parseInt(dom.attr('data-val')); + nextVal = parseInt(nextDom.attr('data-val')); + if (val === nextVal){ + score = val*2; + this.updateScore(score); + nextDom.attr('data-val', score).text(score); + this.board[r][c] = 0; + dom.remove(); + } + } + } + } +}; + +Game.prototype.mergeUp = function() { + for(var c=0; c<4; c++){ + for(var r=0; r<3; r++){ + dom = this.board[r][c]; + nextDom = this.board[r+1][c]; + + if (dom !== 0 && nextDom !== 0) { + val = parseInt(dom.attr('data-val')); + nextVal = parseInt(nextDom.attr('data-val')); + if (val === nextVal){ + score = val*2; + this.updateScore(score); + nextDom.attr('data-val', score).text(score); + this.board[r][c] = 0; + dom.remove(); + } + } + } + } +}; + +Game.prototype.mergeDown = function() { + for(var c=0; c<4; c++){ + for(var r=3; r>=1; r--){ + dom = this.board[r][c]; + nextDom = this.board[r-1][c]; + + if (dom !== 0 && nextDom !== 0) { + val = parseInt(dom.attr('data-val')); + nextVal = parseInt(nextDom.attr('data-val')); + if (val === nextVal){ + score = val*2; + this.updateScore(score); + nextDom.attr('data-val', score).text(score); + this.board[r][c] = 0; + dom.remove(); + } + } + } + } +}; + +Game.prototype.updateScore = function(score) { + if (score === 2048){ + this.gameWon(); + }else{ + this.score += score; + $("#score").text(this.score); + } +}; + +Game.prototype.updateDisplay = function() { + for(var r=0; r<4; r++){ + for(var c=0; c<4; c++){ + if (this.board[r][c] !== 0) { + dom = this.board[r][c]; + dom.attr('data-row', "r" + r).attr("data-col", "c" + c); + } + } + } +}; + +Game.prototype.gameLost = function () { + console.log("Game Over"); + $('body').off("keydown"); + $('.game-message').addClass('game-over'); + $(".game-over").prepend("

Game over!

"); + $(".lower").append("Try again"); +}; + +Game.prototype.gameWon = function () { + var game = this; + console.log("Game Won"); + $('body').off("keydown"); + $('.game-message').addClass('game-won'); + $(".game-won").prepend("

You Won!

"); + $(".lower").append($("Keep Playing?").click(function(event){ + $(".lower a").remove(); + $(".game-won p").remove(); + $('.game-message').removeClass('game-won'); + + $('body').keydown(function(event){ + game.keyHandling(event); + }); + })); +}; + +Game.prototype.keyHandling = function(event) { + var arrows = [37, 38, 39, 40]; + if (arrows.indexOf(event.which) > -1) { + var tile = $('.tile'); + this.moveTile(event.which); + } +}; + $(document).ready(function() { console.log("ready to go!"); // Any interactive jQuery functionality var game = new Game(); $('body').keydown(function(event){ - var arrows = [37, 38, 39, 40]; - if (arrows.indexOf(event.which) > -1) { - var tile = $('.tile'); - - game.moveTile(tile, event.which); - } + game.keyHandling(event); }); }); diff --git a/stylesheets/2048.css b/stylesheets/2048.css index 2a46a94..48fa71f 100644 --- a/stylesheets/2048.css +++ b/stylesheets/2048.css @@ -2,8 +2,24 @@ html { font: normal normal 30px/1 "Clear Sans", "Helvetica Neue", Arial, sans-serif; } +#score { + font: 400 3.5em/125% 'Berkshire Swash', Helvetica, Sans-serif; + display: inline-block; + background: #e80787; + padding: 15px 25px; + font-size: 30px; + height: 20px; + line-height: 20px; + float: right; + font-weight: bold; + border-radius: 3px; + color: white; + margin-top: 8px; + text-align: center; +} + #gameboard { - background: #bbada0; + background: #7D26CD; border-radius: 0.5rem; height: 18.5rem; margin: 1rem auto; @@ -25,7 +41,8 @@ html { top: 0; left: 0; transition: all 0.2s ease-in-out; - color: #f9f6f2; + /*color: #f9f6f2;*/ + color: transparent; background: #000; border-radius: 0.5rem; @@ -48,14 +65,114 @@ html { .tile[data-col=c2] { left: 9rem; } .tile[data-col=c3] { left: 13.5rem; } -.tile[data-val="2"] { color: #776e65; background-color: #eee4da; } -.tile[data-val="4"] { color: #776e65; background-color: #ede0c8; } -.tile[data-val="8"] { background-color: #f2b179; } -.tile[data-val="16"] { background-color: #f59563; } -.tile[data-val="32"] { background: #f67c5f; } -.tile[data-val="64"] { background: #f65e3b; } -.tile[data-val="128"] { background: #edcf72; } -.tile[data-val="256"] { background: #edcc61; } -.tile[data-val="512"] { background: #edc850; } -.tile[data-val="1024"] { background: #edc53f; } -.tile[data-val="2048"] { background: #edc22e; } +.tile[data-val="2"] { + background-image: url("../images/lf1.gif"); + background-size: cover; +} +.tile[data-val="4"] { + background-image: url("../images/lf2.gif"); + background-size: cover; +} +.tile[data-val="8"] { + background-image: url("../images/lf3.jpg"); + background-size: cover; +} +.tile[data-val="16"] { + background-image: url("../images/lf4.jpg"); + background-size: cover; +} +.tile[data-val="32"] { + background-image: url("../images/lf5.jpg"); + background-size: cover; +} +.tile[data-val="64"] { + background-image: url("../images/lf6.jpg"); + background-size: cover; +} +.tile[data-val="128"] { + background-image: url("../images/lf7.jpg"); + background-size: cover; +} +.tile[data-val="256"] { + background-image: url("../images/lf8.jpg"); + background-size: cover; +} +.tile[data-val="512"] { + background-image: url("../images/lf9.jpg"); + background-size: cover; +} +.tile[data-val="1024"] { + background-image: url("../images/lf10.jpg"); + background-size: cover; +} +.tile[data-val="2048"] { + background-image: url("../images/lf11.jpg"); + background-size: cover; +} +.tile[data-val="4096"] { + background-image: url("../images/lf12.jpg"); + background-size: cover; +} +.tile[data-val="8192"] { + background-image: url("../images/lf13.png"); + background-size: cover; +} + +.game-message { + font: 400 3.5em/125% 'Berkshire Swash', Helvetica, Sans-serif; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(255,233,236, 0.73); + padding-top: 40px; + text-align: center; + -webkit-animation: fade-in 800ms ease 1200ms; + -moz-animation: fade-in 800ms ease 1200ms; + animation: fade-in 800ms ease 1200ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } + .game-message p { + font-size: 60px; + font-weight: bold; + height: 60px; + line-height: 60px; + margin-top: 222px; + z-index: 1} + .game-message .lower { + display: block; + margin-top: 29px; } + .game-message a { + font-size: 40px; + display: inline-block; + background: #00FFCC; + border-radius: 3px; + padding: 20px 20px; + text-decoration: none; + color: black; + height: 40px; + line-height: 42px; + cursor: pointer; + margin-left: 9px; } + .game-over, .game-won { + background: rgba(255,182,230, 0.73); + color: black; + -webkit-animation: slide-up 1.5s ease-in-out 2500ms; + -moz-animation: slide-up 1.5s ease-in-out 2500ms; + animation: slide-up 1.5s ease-in-out 2500ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; + z-index: 1} + + .game-message.game-won p, .game-message.game-over p { + z-index: 1 + -webkit-animation: slide-up 1.5s ease-in-out 2500ms; + -moz-animation: slide-up 1.5s ease-in-out 2500ms; + animation: slide-up 1.5s ease-in-out 2500ms; + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + animation-fill-mode: both; } +}