Created
April 3, 2014 07:57
-
-
Save macisi/9950181 to your computer and use it in GitHub Desktop.
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> | |
<head> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> | |
<meta charset="utf-8"> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<div class="grid-container position" id="J-grids"> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
<div class="grid"></div> | |
</div> | |
<div class="tile-container position" id="J-tiles"> | |
</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
(function(d){ | |
"use strict"; | |
var GridSize = 100; | |
var GridGap = 10; | |
var UnitStep = GridSize + GridGap; | |
var Max = 3; | |
var Lock = false; | |
var _slice = [].slice; | |
var _sort = [].sort; | |
var _transform = Modernizr.prefixed("transform"); | |
var Control = { | |
init: function(){ | |
d.addEventListener("keyup", this.move, false); | |
}, | |
move: function(e){ | |
if (Lock) return; | |
switch(e.keyCode) { | |
case 39: //right | |
Tile.move(1, 0); | |
break; | |
case 38: //up | |
Tile.move(0, -1); | |
break; | |
case 40: //down | |
Tile.move(0, 1); | |
break; | |
case 37: //left | |
Tile.move(-1, 0); | |
break; | |
default: | |
break; | |
} | |
} | |
}; | |
var Tile = { | |
el: d.getElementById("J-tiles"), | |
init: function(){ | |
this.availables = []; | |
for (var i = 0; i <= Max; i += 1) { | |
for (var j = 0; j <= Max; j += 1) { | |
this.availables.push([i, j].join(",")); | |
} | |
} | |
this.born(2); | |
}, | |
collection: [], | |
//create a random tile | |
//born(4, [1, 2]) | |
born: function(value){ | |
var tilePos; | |
var availables = this.availables.slice(0); | |
value = value || 2; | |
this.collection.forEach(function(tile){ | |
tilePos = [tile.dataset.x, tile.dataset.y].join(","); | |
if (availables.indexOf(tilePos) !== -1) { | |
availables.splice(availables.indexOf(tilePos), 1); | |
} | |
}); | |
if (availables.length === 0) { | |
//game end | |
return; | |
} | |
tilePos = availables[Math.round(Math.random() * (availables.length - 1))]; | |
tilePos = tilePos.split(","); | |
var tile = d.createElement("div"); | |
tile.className = "tile"; | |
tile.innerText = value; | |
tile.dataset.value = value; | |
tile.dataset.x = tilePos[0]; | |
tile.dataset.y = tilePos[1]; | |
tile.style[_transform] = "translate(" + tilePos[0] * UnitStep + "px, " + tilePos[1] * UnitStep + "px) scale(.4)"; | |
this.collection.push(tile); | |
this.el.appendChild(tile); | |
Modernizr.prefixed('requestAnimationFrame', window)(function(){ | |
tile.style[_transform] = "translate(" + tilePos[0] * UnitStep + "px, " + tilePos[1] * UnitStep + "px) scale(1)"; | |
}); | |
}, | |
move: function(horizontal, vertical){ | |
Lock = true; | |
var poses = [0, 1, 2, 3], groups = [], len, delt, updated = false; | |
if (horizontal !== 0) { | |
poses.forEach(function(pos){ | |
groups.push(this.getTileGroup("y", pos)); | |
}, this); | |
} else if(vertical !== 0) { | |
poses.forEach(function(pos){ | |
groups.push(this.getTileGroup("x", pos)); | |
}, this); | |
} else { | |
return; | |
} | |
groups.forEach(function(group, index){ | |
if (horizontal + vertical > 0) { | |
//正向 | |
len = group.length; | |
while(group[len - 1]) { | |
if (group[len - 2]) { | |
//if two tile has the same value, join them | |
if (group[len - 1].dataset.value === group[len - 2].dataset.value) { | |
this.join(group[len - 2], group[len - 1]); | |
group.splice(len - 2, 1); | |
updated = true; | |
len -= 2; | |
continue; | |
} | |
} | |
len -= 1; | |
} | |
} else { | |
//逆向 | |
var i = 0; | |
len = group.length; | |
while(i < len) { | |
if (group[i + 1]) { | |
//if two tile has the same value, join them | |
if (group[i].dataset.value === group[i + 1].dataset.value) { | |
this.join(group[i + 1], group[i]); | |
group.splice(i + 1, 1); | |
updated = true; | |
i += 2; | |
continue; | |
} | |
} | |
i += 1; | |
} | |
} | |
delt = (horizontal + vertical) > 0 ? Max - (group.length - 1): 0; | |
group.forEach(function(tile, index){ | |
if (horizontal && (+tile.dataset.x) !== (index + delt)) { | |
tile.dataset.x = index + delt; | |
updated = true; | |
} else if (vertical && (+tile.dataset.y) !== (index + delt)) { | |
tile.dataset.y = index + delt; | |
updated = true; | |
} | |
tile.style[_transform] = "translate(" + tile.dataset.x * UnitStep + "px, " + tile.dataset.y * UnitStep + "px)"; | |
}); | |
}, this); | |
updated && this.born(2); | |
Lock = false; | |
}, | |
getTileGroup: function(prop, pos){ | |
var tiles = this.el.querySelectorAll(".tile[data-" + prop + "='" + pos + "']"); | |
var exchange = {x: "y", y: "x"}; | |
tiles = _slice.call(tiles, 0); | |
if (tiles.length > 0) { | |
tiles.sort(function(t1, t2){ | |
return t1.dataset[exchange[prop]] - t2.dataset[exchange[prop]]; | |
}); | |
} | |
return tiles; | |
}, | |
// join two tiles to one tile with values doubled | |
// tileA + tileB == > tileB | |
join: function(tileA, tileB){ | |
tileA.style[_transform] = tileB.style[_transform]; | |
tileB.dataset.value *= 2; | |
tileB.innerText = tileB.dataset.value; | |
this.el.removeChild(tileA); | |
this.collection.splice(this.collection.indexOf(tileA), 1); | |
} | |
}; | |
var Game = { | |
init: function(){ | |
Control.init(); | |
Tile.init(); | |
console.clear(); | |
//console.log(Modernizr.prefixed('requestAnimationFrame', window)); | |
} | |
}; | |
Game.init(); | |
}(document)); |
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
@grid-width: 100px; | |
@grid-height: 100px; | |
@gap: 10px; | |
@background: #ccc; | |
@grid-color: #aaa; | |
@tile-color: #ffc7c7; | |
@font-color: #666; | |
.position { | |
position: absolute; | |
left: 0; | |
top: 0; | |
} | |
.grid-container { | |
z-index: 1; | |
display: flex; | |
padding: @gap; | |
/* flex-direction: row; */ | |
/* flex-wrap: wrap; */ | |
flex-flow: row wrap; | |
justify-content: space-between; | |
align-content: space-between; | |
width: @grid-width * 4 + @gap * 3; | |
height: @grid-height * 4 + @gap * 3; | |
background-color: @background; | |
.grid { | |
width: @grid-width; | |
height: @grid-height; | |
background-color: @grid-color; | |
} | |
} | |
.tile-container { | |
z-index: 2; | |
padding: @gap; | |
.tile { | |
position: absolute; | |
width: @grid-width; | |
height: @grid-height; | |
background-color: @tile-color; | |
text-align: center; | |
line-height: @grid-height; | |
font-size: 64px; | |
color: @font-color; | |
transition: transform ease .125s; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment