2048游戲代碼及思路
關(guān)于游戲
《2048》,是一款益智小游戲,這款游戲是由年僅19歲的意大利程序員加布里勒希魯尼( )開發(fā)出來(lái)的微信小程序2048六角數(shù)字消除,官方版本只能在網(wǎng)頁(yè)上或通過其移動(dòng)網(wǎng)站運(yùn)行。
2048游戲共有16個(gè)格子,初始時(shí)會(huì)有兩個(gè)格子上安放了兩個(gè)數(shù)字2,每次可以選擇上下左右其中一個(gè)方向去滑動(dòng),每滑動(dòng)一次,所有的數(shù)字方塊都會(huì)往滑動(dòng)的方向靠攏外,系統(tǒng)也會(huì)在空白的地方隨即出現(xiàn)一個(gè)數(shù)字方塊,相同數(shù)字的方塊在靠攏、相撞時(shí)會(huì)相加。系統(tǒng)給予的數(shù)字方塊不是2就是4,玩家要想辦法在這小小的16格范圍中湊出“2048”這個(gè)數(shù)字方塊。
(以上文字來(lái)源于搜狗百科)
關(guān)于代碼
利用了html+css+協(xié)作完成,以下是我的代碼
html代碼
Document
<script src="support.js"></script>
<script src="gamePlay.js"></script>
<script src="control.js"></script>
<script src="main.js"></script>
貳 零 肆 捌
!score!
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
#14
#15
<script>
changeColor()
</script>
!G!A!M!E! !O!V!E!R!
使用鍵盤上下左右或右下控制盤控制
為自己取名{小于8個(gè)字符)
▲
▼
當(dāng)前使用id:unnamed
歷史分?jǐn)?shù)
排行榜
css代碼
header{
text-align: center;
font-size: xx-large;
font-family: 楷體, fantasy;
}
.game{
float: left;
position: relative;
left: 50%;
top: 25px;
transform: translate(-50%,0);
background: rosybrown;
width: 480px;
height: 650px;
}
.gamePlatform{
float: left;
position: absolute;
left: 50%;
top: 200px;
padding: 10px;
border-radius: 3em;
transform: translate(-50%,0);
background: bisque;
width: 400px;
height: 400px;
}
.gamePlace{
float: left;
position: relative;
margin: 10px;
width: 80px;
height: 80px;
border-radius: 2em;
background: aliceblue;
text-align: center;
font-size: xx-large;
font-family: 漢儀樂喵體簡(jiǎn), serif;
line-height: 80px;
}
.gameOver{
float: left;
position: absolute;
left: 50%;
top: 350px;
width: 250px;
height: 150px;
border-radius: 0.5em;
transform: translate(-50%,0);
background: darkgray;
filter:alpha(Opacity=60);
-moz-opacity:0.6;
opacity: 0.6;
line-height: 150px;
text-align: center;
}
.buttons{
float: contour;
position: relative;
left: 50%;
transform: translate(-50%,0);
padding: 5px;
border-radius: 1em;
}
.controlEr{
font-size: xx-large;
float: right;
position: absolute;
top: 500px;
right: -25%;
}
.controlButton{
float: left;
position: absolute;
color: #e5b49a;
text-shadow:2px 2px #655d60;
}
.sideWindow{
width: 400px;
height: 300px;
float: left;
position: absolute;
background: #ececec;
filter: alpha(opacity=80);
opacity: 0.5;
border: 1.5px #655d60 solid;
left: 3%;
top: 50px;
overflow: scroll;
}
.sideWindow_2{
width: 400px;
height: 90px;
float: left;
position: absolute;
background: #ececec;
filter: alpha(opacity=80);
opacity: 0.5;
border: 1.5px #655d60 solid;
left: 3%;
top: 400px;
}
.windowTitle{
background: #655d60;
text-align: center;
}
.name{
float: right;
position: absolute;
right: 2%;
top: 20px;
}
#score{
text-align: center;
font-size: x-large;
font-family: 黑體, monospace;
}
#gameOver{
display: none;
}
#toStart{
display: inline;
line-height: 30px;
}
#start{

filter:alpha(Opacity=100);
-moz-opacity:1;
opacity: 1;
left: 17%;
}
#name{
filter:alpha(Opacity=100);
-moz-opacity:1;
opacity: 1;
line-height: 20px;
}
#controlEr{
height: 94px;
width: 94px;
background: #fcfcda;
border-radius: 47px;
}
#up{
top: -4px;
left: 30px;
}
#down{
top: 56px;
left: 30px;
}
#left{
top: 26px;
left: 0;
}
#right{
top: 26px;
left: 60px;
}
#score{
float: right;
position: absolute;
top: 150px;
right: 50%;
transform: translate(50%,0);
}
#history{
overflow: hidden;
}
#nameOk{
float: left;
position: relative;
top: 20px;
left: 50%;
transform: translate(-50% 0);
}
代碼
這部分代碼分成了幾部分來(lái)寫,在實(shí)際使用中只要分開保存并且確保html中載入了每一個(gè)文件的src就可以保證全部得到執(zhí)行
main.js
let score=0;
let board=[];
let add=[];
let id="unnamed";
let top1=0;
let top2=0;
let top3=0;
/*
function check() {//檢查代碼,后期消除
document.getElementById("gameOver").style.display="none";
score=0;
changeColor();
inBoard();
}
*/
function start() {//起初的開始游戲按鍵
document.getElementById("toStart").style.display="none";
score=0;
cleanBoard();
inBoard();
newNumber();
newNumber();
changeColor();
}
function gameOver() {//你死了
document.getElementById("gameOver").style.display="inline";
}
function newGame() {//新游戲
scoreSet();
document.getElementById("gameOver").style.display="none";
score=0;
showScore();
cleanBoard();
inBoard();
newNumber();
newNumber();
changeColor();
}
function nameCheck(){
let name=document.getElementById("nameLine").value;
let nameLength=name.length;
if(nameLength>8){
document.getElementById("toName").innerText="to much words";
}
else if (nameLength===0){
id="unnamed";
document.getElementById("name").style.display="none";
showName(id);
}
else{
id=name;
document.getElementById("name").style.display="none";
showName(id);
}
}
function rename(){
document.getElementById("name").style.display="inline";
}
.js
//移動(dòng)指令響應(yīng)
//鍵盤指令輸入
document.onsystemevent = grabEvent;
document.onkeypress = grabEvent;
document.onirkeypress = grabEvent;
document.onkeyup = grabEvent;
function grabEvent() {
let it = event.which||event;
switch (it) {
case 3:
case 37:
case 271://left

moveLeft();
showScore();
break;
case 1:
case 38:
case 269://up
moveUp();
showScore();
break;
case 4:
case 39:
case 272://right
moveRight();
showScore();
break;
case 2:
case 40:
case 270://down
moveDown();
showScore();
break;
}
}
function upKeyDown() {
moveUp();
showScore();
document.getElementById("up").style.textShadow="0 0";
}
function rightKeyDown() {
moveRight();
showScore();
document.getElementById("right").style.textShadow="0 0";
}
function downKeyDown() {
moveDown();
showScore();
document.getElementById("down").style.textShadow="0 0";
}
function leftKeyDown() {
moveLeft();
showScore();
document.getElementById("left").style.textShadow="0 0";
}
function upKeyUp() {
document.getElementById("up").style.textShadow="2px 2px #655d60";
}
function rightKeyUp() {
document.getElementById("right").style.textShadow="2px 2px #655d60";
}
function downKeyUp() {
document.getElementById("down").style.textShadow="2px 2px #655d60";
}
function leftKeyUp() {
document.getElementById("left").style.textShadow="2px 2px #655d60";
}
.js
function scoreSet() {
setHistory();
setTop();
}
let date=new Date();
function setHistory() {//顯示歷史成績(jī)
let m=date.getMonth()+1;
let d=date.getFullYear()+"年"+m+"月"+date.getDate()+"日"+date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
let x=document.createElement("div");
x.innerText=d+" "+id+" "+score;
let firstChild=document.getElementById("history").firstChild;
document.getElementById("history").insertBefore(x,firstChild);
}
function setTop() {
if(score>top1){
putTop1();
return true;
}
if(score>top2){
putTop2();
return true;
}
if(score>top3){
putTop3();
return true;
}
}
function putTop1() {
document.getElementById("top3").innerText=document.getElementById("top2").innerText;
top3=top2;
document.getElementById("top2").innerText=document.getElementById("top1").innerText;
top2=top1;
let m=date.getMonth()+1;
let d=date.getFullYear()+"年"+m+"月"+date.getDate()+"日"+date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
document.getElementById("top1").innerText=d+" "+id+" "+score;
top1=score;
}
function putTop2() {
document.getElementById("top3").innerText=document.getElementById("top2").innerText;
top3=top2;
let m=date.getMonth()+1;
let d=date.getFullYear()+"年"+m+"月"+date.getDate()+"日"+date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
document.getElementById("top2").innerText=d+" "+id+" "+score;
top2=score;
}
function putTop3() {
let m=date.getMonth()+1;
let d=date.getFullYear()+"年"+m+"月"+date.getDate()+"日"+date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
document.getElementById("top3").innerText=d+" "+id+" "+score;
top3=score;
}
function inBoard() {//格子初始化
for(let i = 0;i<4;i++) {
board[i] = [];
for (let j = 0; j < 4; j++) {
board[i][j] = 0;
}
}
}
function cleanAdd() {//清空格子合并的統(tǒng)計(jì)集
for(let i = 0;i<4;i++) {
add[i] = [];
for (let j = 0; j < 4; j++) {
add[i][j] = 0;
}
}
}

function cleanBoard() {//清理格子
for(let i=0;i<4;i++)
for(let j=0;j<4;j++) {
let temp = document.getElementById("gamePlace_" + i + "_" + j);
temp.innerText = "";
}
}
function newNumber(){//生成隨機(jī)的格子
if (spaceCheck(board)===false) {
return false;
}
let randx = Math.floor(Math.random()*4);
let randy = Math.floor(Math.random()*4);
while(true){
if (board[randx][randy]===0)
break;
randx = Math.floor(Math.random()*4);
randy = Math.floor(Math.random()*4);
}
let randNumber = Math.random()<0.5 ? 2 : 4;
//在隨機(jī)位置顯示隨機(jī)數(shù)字2or4
board[randx][randy] = randNumber;
score+=board[randx][randy];
showNumber(randx,randy,randNumber);
return true;
}
function showNumber(randx,randy,num) {//顯示出數(shù)字
let temp = document.getElementById("gamePlace_" + randx + "_" + randy);
if(num===0){
temp.innerText="";
}
else
temp.innerText=num;
}
function showAllNumber(board) {
for(let i=0;i<4;i++)
for(let j=0;j<4;j++){
let e=board[i][j];
showNumber(i,j,e);
}
}
function spaceCheck(board) {//監(jiān)測(cè)是否有空余空間
for(let i = 0;i<4;i++) {
for (let j = 0; j < 4; j++) {
if(board[i][j] === 0)
return true;
}
}
return false;
}
function showScore() {//更新當(dāng)前分?jǐn)?shù)
document.getElementById("score").innerText="score:"+score;
}
function showName(id) {
document.getElementById("nameRightNow").innerText="當(dāng)前使用id:"+id;
}
function changeColor() {//顏色讀取
for(let i=0;i<4;i++)
for(let j=0;j<4;j++)
{
let temp=document.getElementById("gamePlace_"+i+"_"+j);
if(temp.innerText==="16384")
temp.innerText="#14";
if(temp.innerText==="32768")
temp.innerText="#15";
if(temp.innerText==="65536")
temp.innerText="#16";
if(temp.innerText==="")
temp.style.background="aliceblue";
if(temp.innerText==="2")
temp.style.background="#fafbb0";
if(temp.innerText==="4")
temp.style.background="#cbd781";
if(temp.innerText==="8")
temp.style.background="#d0ce4a";
if(temp.innerText==="16")
temp.style.background="#d1a735";
if(temp.innerText==="32")
temp.style.background="#ffbab5";
if(temp.innerText==="64")
temp.style.background="#fb918a";
if(temp.innerText==="128")
temp.style.background="#fb4855";
if(temp.innerText==="256")
temp.style.background="#fb7ce6";
if(temp.innerText==="512")
temp.style.background="#9c82d1";
if(temp.innerText==="1024")
temp.style.background="#7376d0";
if(temp.innerText==="2048")
temp.style.background="#57aabd";
if(temp.innerText==="4096")
temp.style.background="#3f887c";
if(temp.innerText==="8192")
temp.style.background="#318853";
if(temp.innerText==="#14")
temp.style.background="#1c682c";
if(temp.innerText==="#15")
temp.style.background="#2c4816";
if(temp.innerText==="#16")
temp.style.background="#3a4811";
}
}
.js
function isGameOver() {//你死了
if(canMoveLeft()===false&&canMoveRight()===false&&canMoveDown()===false&&canMoveUp()===false)
gameOver();
}
function moveLeft() {//移動(dòng)的過程
if(canMoveLeft()===false)
return false;
cleanAdd();
for(let i=0;i<4;i++)
for(let j=1;j<4;j++){
if(board[i][j]!==0)
for(let k=j;k>0;k--){
if(board[i][k-1]===0){
board[i][k-1]=board[i][k];
board[i][k]=0;
add[i][k-1]=add[i][k];
add[i][k]=0;
}
if(board[i][k-1]===board[i][k]&&add[i][k-1]===0&&add[i][k]===0){
board[i][k-1]*=2;
score+=board[i][k-1];
board[i][k]=0;
add[i][k]=0;
add[i][k-1]+=1;
}
}
}
showAllNumber(board);

newNumber();
changeColor();
isGameOver();
}
function moveRight() {
if(canMoveRight()===false)
return false;
cleanAdd();
for(let i=0;i<4;i++)
for(let j=2;j>=0;j--){
if(board[i][j]!==0)
for(let k=j;k<3;k++){
if(board[i][k+1]===0){
board[i][k+1]=board[i][k];
board[i][k]=0;
add[i][k+1]=add[i][k];
add[i][k]=0;
}
if(board[i][k+1]===board[i][k]&&add[i][k+1]===0&&add[i][k]===0){
board[i][k+1]*=2;
score+=board[i][k+1];
board[i][k]=0;
add[i][k]=0;
add[i][k+1]+=1;
}
}
}
showAllNumber(board);
newNumber();
changeColor();
isGameOver();
}
function moveUp() {
if(canMoveUp()===false)
return false;
cleanAdd();
for(let j=0;j<4;j++)
for(let i=1;i<4;i++){
if(board[i][j]!==0)
for(let k=i;k>0;k--){
if(board[k-1][j]===0){
board[k-1][j]=board[k][j];
board[k][j]=0;
add[k-1][j]=add[k][j];
add[k][j]=0;
}
if(board[k-1][j]===board[k][j]&&add[k-1][j]===0&&add[k][j]===0){
board[k-1][j]*=2;
score+=board[k-1][j];
board[k][j]=0;
add[k][j]=0;
add[k-1][j]+=1;
}
}
}
showAllNumber(board);
newNumber();
changeColor();
isGameOver();
}
function moveDown() {
if(canMoveDown()===false)
return false;
cleanAdd();
for(let j=0;j<4;j++)
for(let i=2;i>=0;i--){
if(board[i][j]!==0)
for(let k=i;k<3;k++){
if(board[k+1][j]===0){
board[k+1][j]=board[k][j];
board[k][j]=0;
add[k+1][j]=add[k][j];
add[k][j]=0;
}
if(board[k+1][j]===board[k][j]&&add[k+1][j]===0&&add[k][j]===0){
board[k+1][j]*=2;
score+=board[k+1][j];
board[k][j]=0;
add[k][j]=0;
add[k+1][j]+=1;
}
}
}
showAllNumber(board);
newNumber();
changeColor();
isGameOver();
}
function canMoveLeft(){//可以移動(dòng)的判定
for (let i=0;i<4;i++)
for (let j=0;j<4;j++){
if(board[i][j]!==0&&j!==0)
if(board[i][j-1]===0||board[i][j-1]===board[i][j])
return true;
}
return false;
}
function canMoveRight(){
for (let i=0;i<4;i++)
for (let j=0;j<4;j++){
if(board[i][j]!==0&&j!==3)
if(board[i][j+1]===0||board[i][j+1]===board[i][j])
return true;
}
return false;
}
function canMoveUp(){
for (let i=0;i<4;i++)
for (let j=0;j<4;j++){
if(board[i][j]!==0&&i!==0)
if(board[i-1][j]===0||board[i-1][j]===board[i][j])
return true;
}
return false;
}
function canMoveDown(){
for (let i=0;i<4;i++)
for (let j=0;j<4;j++){
if(board[i][j]!==0&&i!==3)
if(board[i+1][j]===0||board[i+1][j]===board[i][j])
return true;
}
return false;
}
寫的原因
寒假作業(yè)嘛。。。寫就是了
仍然有的缺陷
在編碼到“排行榜”部分時(shí)數(shù)組的使用出現(xiàn)了一些問題,在代碼中_數(shù)組_的使用出現(xiàn)了一些問題,這很大程度上影響到了代碼的簡(jiǎn)潔和效果微信小程序2048六角數(shù)字消除,希望之后可以找到辦法改吧。。
最后,
:guixv/2048.git