实现的效果图:
计分规则:每合并一次增加两个分
游戏涉及到的文件:
实现的html代码:
2048game
2048Game
Score: 0
css样式代码:
*{
margin: 0;
padding: 0;
MARGIN-RIGHT: auto;
MARGIN-LEFT: auto;
}
body{
width:100%;
height:100%;
}
.game{
position: absolute;
text-align: center;
width: 34%;
height: 98%;
border: 2px #ee8972 solid;
margin-top: 1%;
margin-left: 33%;
border-radius: 5px;
background-color: #fbe3b9;
}
.game .game_top{
position: relative;
width: 100%;
height: 20%;
/* border: 1px yellow solid; */
}
.game .game_top h1{
position: relative;
display: block;
font-size: 52px;
top: 5%;
margin-bottom: 0;
color: #ee8972;
/* border: 1px rebeccapurple solid; */
}
.game .game_top button{
position: relative;
height: 22%;
background-color: #ee8972;
color:#fff;
margin-top: 2%;
border-radius: 2px;
font-size: 28px;
}
.game .game_top button:focus{
box-shadow: 4px 4px #d1cebd;
outline: none;
opacity: 0.9;
}
.game .game_top p{
display: block;
position: relative;
/* width: 80%; */
height: 20%;
margin-top: 2%;
font-size: 100%;
color: #ee8972;
}
.game .game_top p span{
position: relative;
vertical-align: middle;
display: inline-block;
border:2px #ee8972 solid;
border-radius: 5%;
color: #ee8972;
/* line-height: 32px; */
font-size: 100%;
width: 30%;
}
.game .game_container{
position: absolute;
width: 82%;
height: 50%;
/* padding: 2px #ee8972 solid; */
border: 2px #ee8972 solid;
/* margin-top: 40%; */
margin: 1% 7%;
border-radius: 2px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 2% 1% 1% 1%;
background-color: #ee8972;
}
.game .game_container div{
position: relative;
width: 22%;
height: 22%;
/* border: 1px #ee8972 solid; */
border-radius: 2px;
background-color: #d1cebd;
/* box-shadow: -1px -1px -1px -1px #ee8972; */
}
.game .game_control{
position: absolute;
width: 34%;
height: 22%;
margin: 1% 7%;
bottom: 1px;
margin-top: 78%;
margin-left: 33%;
border: 2px #ee8972 solid;
border-radius: 2px;
background-color: #ee8972;
}
.game .game_control button{
display: block;
position: absolute;
width: 32%;
height: 32%;
border: 1px yellow solid;
background-color: #ee8972;
border-radius: 2px;
background-color: #d1cebd;
}
.game .game_control .b1{
position: absolute;
margin-left: 34%;
margin-top: 1%;
}
.game .game_control .b2{
position: absolute;
top: 31%;
}
.game .game_control .b3{
position: absolute;
top: 31%;
margin-left: 69%;
}
.game .game_control .b4{
position: absolute;
bottom: 2%;
margin-left: 34%;
}
.game .game_control button img{
position: relative;
height: 100%;
width: 100%;
opacity: 0.5;
}
.game .game_control .b1 img{
transform: rotate(-90deg);
-ms-transform: rotate(-90deg); /* IE 9 */
-moz-transform: rotate(-90deg); /* Firefox */
-webkit-transform: rotate(-90deg); /* Safari and Chrome */
-o-transform: rotate(-90deg); /* Opera */
}
.game .game_control .b4 img{
transform: rotate(90deg);
-ms-transform: rotate(90deg); /* IE 9 */
-moz-transform: rotate(90deg); /* Firefox */
-webkit-transform: rotate(90deg); /* Safari and Chrome */
-o-transform: rotate(90deg); /* Opera */
}
.game .game_control .b2 img{
transform: rotate(180deg);
-ms-transform: rotate(180deg); /* IE 9 */
-moz-transform: rotate(180deg); /* Firefox */
-webkit-transform: rotate(180deg); /* Safari and Chrome */
-o-transform: rotate(180deg); /* Opera */
}
.game .game_control button:focus{
box-shadow: 4px 4px #d1cebd;
outline: none;
opacity: 0.9;
}
/* 设置方格里的数字 */
.num_set{
position: absolute;
width: 100%;
height: 100%;
text-align: center;
font-size: 52px;
color: #3c3d47;
font-weight: 800;
}
.win{
position: absolute;
height: 15%;
width: 80%;
margin-left: 10%;
margin-top: 25%;
background: #000000;
border: 1px sienna solid;
border-radius: 15px;
opacity: 0.8;
color: #fff;
text-align: center;
}
.hide{
display: none;
}
.win h1{
margin-top: 3%;
}
.win span{
font-size: 28px;
}
.t1{
width:100%;
height:100%;
position: absolute;
z-index: 1;
animation:divanimation 5s infinite;
-moz-animation:divanimation 5s infinite; /* Firefox */
-webkit-animation:divanimation 5s infinite; /* Safari and Chrome */
-o-animation:divanimation 5s infinite; /* Opera */
}
@keyframes divanimation
{
from {width: 100%; height: 100%; top: 0%;left: 0; font-size: 18px; line-height: 45px; background: #000000 ;display: block;}
to {width: 100%; height: 100%; top: 0%;left: 340%; font-size: 48px; line-height: 45px;background: #000000 ; display: none;}
}
@-moz-keyframes divanimation /* Firefox */
{
from {width: 45px; height: 45px; top: 24px;left: 24px; font-size: 18px; line-height: 45px;display: block;}
to {width: 45px; height: 45px; top: 0px;left: 0px; font-size: 48px; line-height: 45px;display: none;}
}
@-webkit-keyframes divanimation /* Safari and Chrome */
{
from {width: 45px; height: 45px; top: 24px;left: 24px; font-size: 18px; line-height: 45px;display: block;}
to {width: 45px; height: 45px; top: 0px;left: 0px; font-size: 48px; line-height: 45px;display: none;}
}
@-o-keyframes divanimation /* Opera */
{
from {width: 45px; height: 45px; top: 24px;left: 24px; font-size: 18px; line-height: 45px;display: block;}
to {width: 45px; height: 45px; top: 0px;left: 0px; font-size: 48px; line-height: 45px;display: none;}
}
js实现代码:
// 记录得分与16个方格的信息
var sroce = 0;//计分
var infor = new Array();//数组存贮16个空格
document.getElementById("newgame").addEventListener("click", newGame);//初始话新游戏
document.getElementById("l").addEventListener("click", toleftbtn);
document.getElementById("r").addEventListener("click", torigthbtn);
document.getElementById("up").addEventListener("click", toupbtn);
document.getElementById("down").addEventListener("click", todownbtn);
// 初始化一个游戏
function newGame() {
newinfo(infor);// 初始化十六个空格的信息
generateOneNumber(infor);// 随机生成两个数字
renderBoard(infor);
generateOneNumber(infor);
renderBoard(infor);
document.getElementById("win_over").classList.add("hide");
document.getElementById("game_win").classList.add("hide");
document.getElementById("game_over").classList.add("hide");
}
// 点击向左按钮更新数据与页面
function toleftbtn() {
gamewin(infor);
gameover(infor);
toleft(infor);
// delayRun(generateOneNumber(infor),5000);
generateOneNumber(infor);
// game_generateNumber(infor);
renderBoard(infor);
document.getElementById("srcoe").innerHTML = sroce;
}
// 点击向右按钮更新数据与页面
function torigthbtn() {
gamewin(infor);
gameover(infor);
torigth(infor);
generateOneNumber(infor);
// game_generateNumber(infor);
renderBoard(infor);
document.getElementById("srcoe").innerHTML = sroce;
}
// 点击向上按钮更新数据与页面
function toupbtn() {
gamewin(infor);
gameover(infor);
toup(infor);
infor = newArray;
generateOneNumber(infor);
// game_generateNumber(infor);
renderBoard(infor);
document.getElementById("srcoe").innerHTML = sroce;
}
// 点击向下按钮更新数据与页面
function todownbtn() {
gamewin(infor);
gameover(infor);
todown(infor);
infor = newArray;
generateOneNumber(infor);
// game_generateNumber(infor);
renderBoard(infor);
document.getElementById("srcoe").innerHTML = sroce;
}
// 更新分数函数
function newinfo(arr) {
sroce = 0;
document.getElementById("srcoe").innerHTML = "0";
for (var i = 0; i < 4; i++) {
arr[i] = new Array();
for (var j = 0; j < 4; j++) {
arr[i][j] = 0;
var t = document.getElementById('c_' + i + '_' + j);
t.innerHTML = " ";
t.style.background = "#ee8972";
}
}
}
// 在空的方格位置随机产生一个2或者4的数字
function generateOneNumber(arr) {
var randnum = Math.random() < 0.5 ? 2 : 4;
var randX = Math.floor(Math.random() * 4);
var randY = Math.floor(Math.random() * 4);
if (arr[randX][randY] == 0) {
arr[randX][randY] = randnum;
}
else {
generateOneNumber(arr);
}
}
// 游戏过程随机生成一个数子
function game_generateNumber(arr) {
if (nospace(arr)) {
generateOneNumber(arr);
}
}
// 当方格有数字时,空格样式发生改变
function renderBoard(arr) {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
var num = arr[i][j];
if (num != 0) {
var t = document.getElementById('c_' + i + '_' + j);
// console.log(t);
// var temp = document.createElement("div");
// var tem = document.createElement("div");
// var y1=document.getElementById("c_0_0");
// console.log(tem);
// y1.appendChild(tem);
// temp.classList.add("t1");
// t.appendChild(temp);
// creatediv(num);
t.innerHTML = num;
t.classList.add("num_set");
t.style.background = backgcolor(num);
}
else {
var t = document.getElementById('c_' + i + '_' + j);
t.innerHTML = " ";
t.style.background = "#d1cebd";
}
}
}
}
// 判断输赢
function gamewin(arr) {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (arr[i][j] == 2048) {
win();
}
}
}
}
// 赢时显示祝贺页面
function win() {
document.getElementById("win_over").classList.remove("hide");
document.getElementById("game_win").classList.remove("hide");
}
// 输时显示遗憾页面
function over() {
document.getElementById("win_over").classList.remove("hide");
document.getElementById("game_over").classList.remove("hide");
}
// 判断是否游戏结束
function gameover(arr) {
if ((nospace(arr) == 1) && (donmove(arr) == 1)) {
over();
}
}
// 游戏结束必要条件之一:每个小空格多有大于2的数值
function nospace(arr) {
var flag1 = 1;
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (arr[i][j] == 0) {
flag1 = 0;
}
}
}
return flag1;
}
// 游戏结束的必要条件之二:如何两个相邻的数字都不相等
function donmove(arr) {
var flag = 1;
// 二维数组中任何两个相邻的数不相等
for (var i = 0; i < 3; i++) {
// 判断行中相邻的两数有没有相等的
for (var j = 0; j < 3; j++) {
if ((infor[i][j] == arr[i][j + 1]) || infor[i][j] == infor[i + 1][j]) {
flag = 0;
}
}
}
return flag;
}
// 向左合并的计算逻辑
function toleft(arr){
var x=arr.length;
var y=arr[0].length;
var tag=0;
// 预处理,将数组集中到数组的左侧,即去除数组中的0
for(var i = 0 ; i < x ; i++){
for (var j = 0; j < y ; j++){
if(arr[i][tag] == 0){
arr[i].splice(tag, 1);
arr[i].push(0);
}
else{
tag++;
// document.getElementById()
continue;
}
}
tag=0;
for(var j=1;j 0 ; j--){
// alert(j);
if(arr[i][tag] == 0){
arr[i].splice(tag, 1);
arr[i].unshift(0);
}
else{
tag--;
continue;
}
}
tag=y-1;
for(var j=y-1 ;j>=0; j--){
// alert(j);
if((arr[i][j]==arr[i][j-1])&&(arr[i][j]!=0)){
arr[i][j]=arr[i][j-1]*2;
// 更新游戏分数,合并一次+2分
sroce=sroce+2;
arr[i].splice(j-1,1);
arr[i].unshift(0);
}
}
}
}
// 转置函数(向上与向下合并使用转置函数)
var newArray = [];
function transposition(item){
newArray = item[0].map(function(col, i) {
return item.map(function(row) {
return row[i];
});
});
}
//向上合并计算逻辑
function toup(arr){
transposition(arr);//将函数装置后得到新函数
arr = newArray;
toleft(arr);
transposition(arr);//计算后将结果转至回去
arr = newArray;
}
//向下合并 计算逻辑
function todown(arr){
transposition(arr);
arr = newArray;
torigth(arr);
transposition(arr);
arr = newArray;
}
// 改变方格的背景颜色
function backgcolor (num){
switch (num){
case 2 :
return "#e8d4b4";
case 4 :
return "#d2d0fe";
case 8 :
return "#f67280";
case 16 :
return "#eb4d55";
case 32 :
return "#e688a1";
case 64 :
return "#b5525c";
case 128 :
return "#ad62aa";
case 256 :
return "#eab9c9";
case 512 :
return "#eca0b6";
case 1024 :
return "#fc9d9d";
case 2048 :
return "#ea728c";
default:
return "#ee8972"
}
}
暂时还没实现动画效果,因为在实现的过程中发现自己的css有太多的盲区,填补盲区后有时间再实现一下