游戏截图:
  对应的html代码:
<script src="https://cdn.staticfile.org/jquery/2.2.4/jquery.min.js"></script>
<h1>
通过四个方向键移动
</h1>
<div class="container text-center" id="2048">
</div>
<script>
$(document).ready(function () {
$("#2048").init2048();
});
</script>
对应的css代码:
.holder2048 {
width: 280px;
height: 380px;
position: relative;
margin: 0 auto;
}
.holder2048>.container {
width: 280px;
height: 280px;
position: relative;
margin: 0 auto;
border-style: none;
border: 3px solid #BBADA0;
background-color: #CCC0B3;
}
.holder2048>.container>.mask {
width: 70px;
height: 70px;
position: absolute;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
border: 3px solid #BBADA0;
}
.holder2048>.container>.box {
width: 66px;
height: 66px;
background-color: Black;
position: absolute;
color: #776E65;
font-size: x-large;
font-weight: bolder;
font-family: Arial;
text-align: center;
line-height: 70px;
}
.holder2048>.container>.box[value='2'] {
background-color: #FFF8D7
}
.holder2048>.container>.box[value='4'] {
background-color: #FFED97
}
.holder2048>.container>.box[value='8'] {
background-color: #FFBB77
}
.holder2048>.container>.box[value='16'] {
background-color: #FF9224
}
.holder2048>.container>.box[value='32'] {
background-color: #FF5809
}
.holder2048>.container>.box[value='64'] {
background-color: #EA0000
}
.holder2048>.container>.box[value='128'] {
background-color: #FFFF37
}
.holder2048>.container>.box[value='256'] {
background-color: #F9F900
}
.holder2048>.container>.box[value='512'] {
background-color: #E1E100
}
.holder2048>.container>.box[value='1024'] {
background-color: #C4C400
}
.holder2048>.container>.box[value='2048'] {
background-color: #9AFF02
}
.holder2048>.container>.box[value='4096'] {
background-color: #00FFFF
}
.holder2048>.container>.box[value='8192'] {
background-color: #FF00FF
}
对应的js代码:
(function ($) {
var defaults = {
delay: 200
};
$.fn.init2048 = function (_options) {
var _this = this,
options = $.extend(defaults, _options),
dir = {
up: 'up',
right: 'right',
down: 'down',
left: 'left'
},
holder = {},
content = {},
matrix = [],
boxes = [],
isCheating = 0,
isGameOver = false;
resetGame();
bind();
function resetGame() {
boxes = [];
matrix = [];
isCheating = 0;
isGameOver = false;
holder = $('<div>').addClass('holder2048');
content = $('<div>').addClass('container').appendTo(holder);
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
matrix[i * 4 + j] = {
top: i * 70,
left: j * 70,
taken: false,
combined: false,
value: 0
};
$('<div>').addClass('mask').css({
left: j * 70 + "px",
top: i * 70 + "px"
}).appendTo(content);
}
}
createBox();
_this.html(holder);
}
function cheat() {
resetGame();
createBox(4096);
}
function createBox(value) {
var emptyMatrix = 0;
for (var i = 0; i < matrix.length; i++) {
if (!matrix[i].taken) {
emptyMatrix++;
}
}
if (emptyMatrix === 0) {
return;
}
var random = Math.floor(Math.random() * emptyMatrix + 1);
var chosenIndex = 0;
for (var j = 0; chosenIndex < matrix.length; chosenIndex++) {
while (matrix[chosenIndex].taken) {
chosenIndex++;
}
if (++j === random) {
matrix[chosenIndex].taken = true;
break;
}
}
value = value ? value : (Math.floor(Math.random() * 4 + 1) === 4 ? 4 : 2);
var newBox = $('<div>').addClass('box').attr({
position: chosenIndex,
value: value
}).css({
marginTop: matrix[chosenIndex].top + 2,
marginLeft: matrix[chosenIndex].left + 2,
opacity: 0
}).text(value).appendTo(content).animate({
opacity: 1
}, options.delay * 2);
boxes.push(newBox);
}
function combineBox(source, target, value) {
var _value = parseInt(value) * 2;
boxes[target].attr('value', _value).html(_value).css({
zIndex: 99
}).animate({
width: '+=20',
height: '+=20',
marginTop: '-=10',
marginLeft: '-=10'
}, options.delay / 2, function () {
$(this).animate({
width: '-=20',
height: '-=20',
marginTop: '+=10',
marginLeft: '+=10'
}, options.delay / 2, function () {
$(this).css({
zIndex: 1
})
})
});
boxes[source].remove();
boxes.splice(source, 1);
}
function gameOver() {
if (boxes.length != 16) {
return false;
}
var i, a, b;
for (i = 0; i < 16; i++) {
for (a = 0; a < 16; a++) {
if (boxes[a].attr('position') == i)
break;
}
if (i % 4 != 3) {
for (b = 0; b < 16; b++) {
if (boxes[b].attr('position') == i + 1)
break;
}
if (boxes[a].attr('value') == boxes[b].attr('value'))
return false;
}
if (i < 12) {
for (b = 0; b < 16; b++) {
if (boxes[b].attr('position') == i + 4)
break;
}
if (boxes[a].attr('value') == boxes[b].attr('value'))
return false;
}
}
return true;
}
function gameRun(dir) {
if (isGameOver) {
return;
}
if (run(dir)) {
createBox();
}
if (gameOver()) {
isGameOver = true;
alert("Game Over");
}
}
function bind() {
$(window).keydown(function (event) {
if (!isGameOver) {
if (event.which == 37) {
event.preventDefault();
gameRun(dir.left);
} else if (event.which == 38) {
event.preventDefault();
gameRun(dir.up);
} else if (event.which == 39) {
event.preventDefault();
gameRun(dir.right);
} else if (event.which == 40) {
event.preventDefault();
gameRun(dir.down);
}
}
});
var touchStartClientX, touchStartClientY;
document.addEventListener("touchstart", function (event) {
if (event.touches.length > 1)
return;
touchStartClientX = event.touches[0].clientX;
touchStartClientY = event.touches[0].clientY;
});
document.addEventListener("touchmove", function (event) {
event.preventDefault();
});
document.addEventListener("touchend", function (event) {
if (event.touches.length > 0)
return;
var dx = event.changedTouches[0].clientX - touchStartClientX;
var absDx = Math.abs(dx);
var dy = event.changedTouches[0].clientY - touchStartClientY;
var absDy = Math.abs(dy);
if (Math.max(absDx, absDy) > 10) {
if (absDx > absDy) {
if (dx > 0) {
gameRun(dir.right);
} else {
gameRun(dir.left);
}
} else {
if (dy > 0) {
gameRun(dir.down);
} else {
gameRun(dir.up);
}
}
}
});
}
function run(dir) {
var isMoved = false;
var i, j, k, empty, _empty, position, value1, value2, temp;
for (i = 0; i < 16; i++) {
matrix[i].combined = false;
}
if (dir == "left") {
isCheating = -1;
for (i = 0; i < 4; i++) {
empty = i * 4;
_empty = empty;
for (j = 0; j < 4; j++) {
position = i * 4 + j;
if (!matrix[position].taken) {
continue;
}
if (matrix[position].taken && position === empty) {
empty++;
if (empty - 2 >= _empty) {
for (k = 0; k < boxes.length; k++) {
if (boxes[k].attr("position") == position) {
break;
}
}
value1 = boxes[k].attr('value');
for (temp = 0; temp < boxes.length; temp++) {
if (boxes[temp].attr("position") == empty - 2) {
break;
}
}
value2 = boxes[temp].attr('value');
if (value1 == value2 && !matrix[empty - 2].combined) {
combineBox(k, temp, value1);
matrix[empty - 1].taken = false;
matrix[empty - 2].combined = true;
empty--;
isMoved = true;
}
}
} else {
for (k = 0; k < boxes.length; k++) {
if (boxes[k].attr("position") == position) {
break;
}
}
boxes[k].animate({
marginLeft: matrix[empty].left + 2,
marginTop: matrix[empty].top + 2
}, options.delay);
boxes[k].attr('position', empty);
matrix[empty].taken = true;
matrix[position].taken = false;
empty++;
isMoved = true;
if (empty - 2 >= _empty) {
value1 = boxes[k].attr('value');
for (temp = 0; temp < boxes.length; temp++) {
if (boxes[temp].attr("position") == empty - 2) {
break;
}
}
value2 = boxes[temp].attr('value');
if (value1 == value2 && !matrix[empty - 2].combined) {
combineBox(k, temp, value1);
matrix[empty - 1].taken = false;
matrix[empty - 2].combined = true;
empty--;
}
}
}
}
}
} else if (dir == "right") {
isCheating = -1;
for (i = 3; i > -1; i--) {
empty = i * 4 + 3;
_empty = empty;
for (j = 3; j > -1; j--) {
position = i * 4 + j;
if (!matrix[position].taken) {
continue;
}
if (matrix[position].taken && position === empty) {
empty--;
if (empty + 2 <= _empty) {
for (k = 0; k < boxes.length; k++) {
if (boxes[k].attr("position") == position) {
break;
}
}
value1 = boxes[k].attr('value');
for (temp = 0; temp < boxes.length; temp++) {
if (boxes[temp].attr("position") == empty + 2) {
break;
}
}
value2 = boxes[temp].attr('value');
if (value1 == value2 && !matrix[empty + 2].combined) {
combineBox(k, temp, value1);
matrix[empty + 1].taken = false;
matrix[empty + 2].combined = true;
empty++;
isMoved = true;
}
}
} else {
for (k = 0; k < boxes.length; k++) {
if (boxes[k].attr("position") == position) {
break;
}
}
boxes[k].animate({
marginLeft: matrix[empty].left + 2,
marginTop: matrix[empty].top + 2
}, options.delay);
boxes[k].attr('position', empty);
matrix[empty].taken = true;
matrix[position].taken = false;
empty--;
isMoved = true;
if (empty + 2 <= _empty) {
value1 = boxes[k].attr('value');
for (temp = 0; temp < boxes.length; temp++) {
if (boxes[temp].attr("position") == empty + 2) {
break;
}
}
value2 = boxes[temp].attr('value');
if (value1 == value2 && !matrix[empty + 2].combined) {
combineBox(k, temp, value1);
matrix[empty + 1].taken = false;
matrix[empty + 2].combined = true;
empty++;
}
}
}
}
}
} else if (dir == "up") {
isCheating = -1;
for (i = 0; i < 4; i++) {
empty = i;
_empty = empty;
for (j = 0; j < 4; j++) {
position = j * 4 + i;
if (!matrix[position].taken) {
continue;
}
if (matrix[position].taken && position === empty) {
empty += 4;
if (empty - 8 >= _empty) {
for (k = 0; k < boxes.length; k++) {
if (boxes[k].attr("position") == position) {
break;
}
}
value1 = boxes[k].attr('value');
for (temp = 0; temp < boxes.length; temp++) {
if (boxes[temp].attr("position") == empty - 8) {
break;
}
}
value2 = boxes[temp].attr('value');
if (value1 == value2 && !matrix[empty - 8].combined) {
combineBox(k, temp, value1);
matrix[empty - 4].taken = false;
matrix[empty - 8].combined = true;
empty -= 4;
isMoved = true;
}
}
} else {
for (k = 0; k < boxes.length; k++) {
if (boxes[k].attr("position") == position) {
break;
}
}
boxes[k].animate({
marginLeft: matrix[empty].left + 2,
marginTop: matrix[empty].top + 2
}, options.delay);
boxes[k].attr('position', empty);
matrix[empty].taken = true;
matrix[position].taken = false;
empty += 4;
isMoved = true;
if (empty - 8 >= _empty) {
value1 = boxes[k].attr('value');
for (temp = 0; temp < boxes.length; temp++) {
if (boxes[temp].attr("position") == empty - 8) {
break;
}
}
value2 = boxes[temp].attr('value');
if (value1 == value2 && !matrix[empty - 8].combined) {
combineBox(k, temp, value1);
matrix[empty - 4].taken = false;
matrix[empty - 8].combined = true;
empty -= 4;
}
}
}
}
}
} else if (dir == "down") {
if (isCheating != -1) {
isCheating++;
if (isCheating == 10) {
cheat();
return true;
}
}
for (i = 0; i < 4; i++) {
empty = i + 12;
_empty = empty;
for (j = 3; j > -1; j--) {
position = j * 4 + i;
if (!matrix[position].taken) {
continue;
}
if (matrix[position].taken && position === empty) {
empty -= 4;
if (empty + 8 <= _empty) {
for (k = 0; k < boxes.length; k++) {
if (boxes[k].attr("position") == position) {
break;
}
}
value1 = boxes[k].attr('value');
for (temp = 0; temp < boxes.length; temp++) {
if (boxes[temp].attr("position") == empty + 8) {
break;
}
}
value2 = boxes[temp].attr('value');
if (value1 == value2 && !matrix[empty + 8].combined) {
combineBox(k, temp, value1);
matrix[empty + 4].taken = false;
matrix[empty + 8].combined = true;
empty += 4;
isMoved = true;
}
}
} else {
for (k = 0; k < boxes.length; k++) {
if (boxes[k].attr("position") == position) {
break;
}
}
boxes[k].animate({
marginLeft: matrix[empty].left + 2,
marginTop: matrix[empty].top + 2
}, options.delay);
boxes[k].attr('position', empty);
matrix[empty].taken = true;
matrix[position].taken = false;
empty -= 4;
isMoved = true;
if (empty + 8 <= _empty) {
value1 = boxes[k].attr('value');
for (temp = 0; temp < boxes.length; temp++) {
if (boxes[temp].attr("position") == empty + 8) {
break;
}
}
value2 = boxes[temp].attr('value');
if (value1 == value2 && !matrix[empty + 8].combined) {
combineBox(k, temp, value1);
matrix[empty + 4].taken = false;
matrix[empty + 8].combined = true;
empty += 4;
}
}
}
}
}
}
return isMoved;
}
}
})(jQuery);
|