Responsive 2048 with Mobile Touch support

JADE
#mobilewrap #container div.score p span.title Score span.scorefield 0 div.newgame div.button span New Game div.grid - for (var y = 0; y < 4; y++) div.row - for (var x = 0; x < 4; x++) div.base div.tiles div.over span Game Over div.won span.winner You win! span.bestscore BEST SCORE: span.numbest <a href="https://twitter.com/simoberny" target='_blank'><i class="fa fa-twitter" aria-hidden="true"></i></a>
SCSS
@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500'); @import url('https://fonts.googleapis.com/css?family=Montserrat'); html, body{ margin: 0; background: #111; min-height: 100%; font-family: 'Montserrat', sans-serif; } #mobilewrap{ position: absolute; width: 100%; height: 100%; a{ position: absolute; bottom: 5vh; right: 5vh; .fa-twitter{ font-size: 5vh; color: #FF5722; } } } #container{ position: absolute; width: 50vh; height: 50vh; background: #B0BEC5; margin: auto; left: 0; right: 0; top: 0; bottom: 0; border-radius: 0 0 5px 5px; .score{ position: absolute; display: table; top: -9vh; width: 22vh; height: 10vh; background: #B0BEC5; border-radius: 5px 0 0 0; text-align: center; padding-top: 0.5vh; box-sizing: border-box; p{ display: table-cell; font-size: 3.5vh; .title{ display: block; color: #455A64; } .scorefield{ color: white; letter-spacing: 1px; font-weight: 600; } } } .newgame{ position: absolute; top: -9vh; right: 0; width: 29vh; height: 10vh; background: #B0BEC5; border-radius: 0 5px 0 0; .button{ position: absolute; display: table; width: 24vh; height: 7vh; margin: auto; top: 0; bottom: 0; left: 0; right: 0; background: #CFD8DC; border-radius: 4px; text-align: center; cursor: pointer; transition: box-shadow 0.3s; &:hover{ box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); transition: box-shadow 0.3s; } &:active{ box-shadow: inset 0 10px 20px rgba(0,0,0,0.19), inset 0 6px 6px rgba(0,0,0,0.23); transition: all 0.3s; } span{ display: table-cell; color: #455A64; font-size: 3vh; vertical-align: middle; } } } .over{ position: absolute; top: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.7); display: table; text-align: center; border-radius: 4px; visibility: hidden; opacity: 0; transition: opacity 0.5s; span{ display: table-cell; color: #455A64; font-size: 5vh; vertical-align: middle; } } .won{ position: absolute; top: 0; left: 50vh; width: 30vw; height: 100%; padding-top: 0vh; border-radius: 4px; opacity: 0; visibility: hidden; padding-left: 4vh; transition: padding-top 0.3s, opacity 0.4s; .winner{ display: block; color: rgba(255,255,255,0.25); font-size: 13vh; } .bestscore{ color: rgba(255,255,255,0.25); font-size: 4vh; } .numbest{ color: #FF5722; font-size: 4.3vh; } } .grid{ width: 100%; height: 100%; padding-top: 1vh; .row{ position: relative; width: 100%; height: 10vh; padding-left: 1vh; .base{ position: relative; float: left; width: 10vh; height: 10vh; background: #CFD8DC; border-radius: 5px; margin: 1vh; text-align: center; } } } .tiles{ position: absolute; top: 0; width: 100%; height: 100%; padding: 2vh; box-sizing: border-box; .tile{ position: absolute; width: 10vh; height: 10vh; border-radius: 5px; overflow: hidden; transition: box-shadow 0.3s; &:hover{ box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); transition: box-shadow 0.3s; } .tile_content{ display: table; text-align: center; width: 100%; height: 100%; transform-origin: center center; animation: pop-up 0.3s ease-in forwards; padding: 1px; span{ display: table-cell; font-size: 3.5vh; vertical-align: middle; font-family: 'Roboto', sans-serif; } } } } } .tile-2{ background: rgba(255,255,255,0.9);} .tile-4{background: #B3E5FC;} .tile-8{background: #81D4FA;} .tile-16{background: #4FC3F7; color: white;} .tile-32{background: #29B6F6; color: white;} .tile-64{background: #03A9F4; color: white;} .tile-128{background: #E6EE9C;} .tile-256{background: #DCE775; box-shadow: 0 0 10px 1px #DCE775;} .tile-512{background: #D4E157; box-shadow: 0 0 15px 1px #D4E157;} .tile-1024{background: #FFEB3B;} .tile-2048{background: #FFC107; box-shadow: 0 0 10px 1px #FFC107;} .tile-4096{background: #FF9800; box-shadow: 0 0 15px 1px #FF9800; color: white;} .tile-8192{background: #7B1FA2; box-shadow: 0 0 10px 1px #7B1FA2; color: white;} @keyframes pop-up{ 0% { transform: scale(0.4); } 50%{ transform: scale(1.4); } 100% { transform: scale(1); } }
JAVASCRIPT
////// MOBILE GESTURES //////// var myElement = document.getElementById('mobilewrap'); var hammertime = new Hammer(myElement); hammertime.get('swipe').set({ direction: Hammer.DIRECTION_ALL }); hammertime.on('swipeleft', function(ev) { moveDirection(37); }); hammertime.on('swiperight', function(ev) { moveDirection(39); }); hammertime.on('swipeup', function(ev) { moveDirection(38); }); hammertime.on('swipedown', function(ev) { moveDirection(40); }); /* ---------------------------------------------------------------------- */ var matrix = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]; var component = new Array(); var best = 0; var score = 0; $(".button").on("click", function(){ restoreField(); init(); }); init(); function restoreField(){ score = 0; $(".scorefield").text(score); matrix = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]]; component = new Array(); $('.tiles').remove(); $("#container").append("<div class='tiles'></div>"); $(".over").css("visibility", "hidden").css("opacity", "0"); } function random(min, max) { return Math.floor((Math.random() * max) + min); } function dueoquattro(){ return (((Math.random() * 10) > 5) ? 4 : 2); } function init(){ var i = 0; while(i < 2){ var x = random(0, 4); var y = random(0, 4); if(matrix[x][y] == 0){ i++; matrix[x][y] = dueoquattro(); component.push({x: x, y: y}); updateTile(12 * x, 12 * y, x, y); } } } function updateTile(trax, tray, x, y){ $(".tiles").append("<div class='tile tile-" + matrix[x][y] + " tile-" + x + "-" + y + "' style='transform: translate(" + trax + "vh, " + tray + "vh);'><div class='tile_content'><span>" + matrix[x][y] + "</span></div></div>"); } window.addEventListener('keydown',this.direction,false); function compare(a,b) { if(dx == 1){ if (a.x < b.x) return -1; if (a.x > b.x) return 1; return 0; } } function moveDirection(code){ var change = 0; switch(code){ case 37: component.sort(function(a, b){if(a.x < b.x){return -1;}if(a.x > b.x){return 1;}return 0;}); change = move(-1,0); break; case 38: component.sort(function(a, b){if(a.y < b.y){return -1;}if(a.y > b.y){return 1;}return 0;}); change = move(0,-1); break; case 39: component.sort(function(a, b){if(a.x > b.x){return -1;}if(a.x < b.x){return 1;}return 0;}); change = move(1,0); break; case 40: component.sort(function(a, b){if(a.y > b.y){return -1;}if(a.y < b.y){return 1;}return 0;}); change = move(0, 1); break; } if(change > 0){ addTile(); } if(checkDefeat()){ $(".over").css("visibility", "visible").css("opacity", "1"); } } function checkDefeat(){ if(component.length == 16){ for(var i = 0; i < component.length; i++){ for(var x = -1; x <= 1; x++){ for(var y = -1; y <= 1; y++){ if(x != y && Math.abs(x) != Math.abs(y)){ if(isMovePossible(component[i].x, component[i].y, x, y, i)){ return false; } } } } } return true; } } function won(){ $(".won").css("visibility", "visible").css("padding-top", "0px").css("opacity", 1); } function direction(e) { moveDirection(e.keyCode); } function addTile(){ var i = 0; while(i < 1){ var x = random(0, 4); var y = random(0, 4); if(matrix[x][y] == 0){ i++; matrix[x][y] = dueoquattro(); component.push({x: x, y: y}); updateTile(12 * x, 12 * y, x, y); } } } function move(dx, dy){ var change = 0; for(var i = 0; i < component.length; i++){ while(isMovePossible(component[i].x, component[i].y, dx, dy, i)){ makeMove(component[i].x, component[i].y, dx, dy, i); change++; if(component[i].x != -1 && component[i].y != -1){ component[i].x += dx; component[i].y += dy; } } } checkTrash(); return change; } function makeMove(x, y, dx, dy, i){ var newX = x + dx; var newY = y + dy; var newValue = matrix[x][y] + matrix[newX][newY]; if(matrix[newX][newY] == matrix[x][y]){ component[i].x = -1; component[i].y = -1; score += newValue; $(".scorefield").text(score); if(score > best){ best = score; $(".numbest").text(best); } } matrix[newX][newY] = newValue; matrix[x][y] = 0; updateTile(12 * newX, 12 * newY, newX, newY); $('.tile-' + x + '-' + y + '').remove(); if(newValue == 2048){ won(); } } function checkTrash(){ for(var i = 0; i < component.length; i++){ if(component[i].x == -1 && component[i].y == -1){ component.splice(i, 1); } } } function isMovePossible(x, y, dx, dy, i){ var newX = x + dx; var newY = y + dy; if(newX < 4 && newX >= 0 && newY < 4 && newY >= 0){ if(matrix[newX][newY] == 0){ return true; }else if(matrix[newX][newY] == matrix[x][y]){ return true; }else{ return false; } }else{ return false; } }
Expand for more options Login