2048小游戏项目总结

最近有在玩2048,所以写了个2048的代码
话不多说,先上截图和代码

游戏截图

HTML代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="initial-scale=1, width=device-width, maximum-scale=1, minimum-scale=1.0, user-scalable=no"><title>2048小游戏</title><link rel="stylesheet" href="css/normalize.css"><link rel="stylesheet" href="css/style.css"><script src="js/2048.js" type="text/javascript" charset="utf-8"></script>
</head>
<body><div class="score"><div class="current-score"><strong>当前得分:</strong><span id="current-score">0</span></div><div class="most-score"><strong>最高得分:</strong><span id="most-score">0</span></div></div><div class="contain"><div class="line-1"><div id="cd-11" class="n0"></div><div id="cd-12" class="n0"></div><div id="cd-13" class="n0"></div><div id="cd-14" class="n0"></div></div><div class="line-2"><div id="cd-21" class="n0"></div><div id="cd-22" class="n0"></div><div id="cd-23" class="n0"></div><div id="cd-24" class="n0"></div></div><div class="line-3"><div id="cd-31"class="n0"></div><div id="cd-32"class="n0"></div><div id="cd-33"class="n0"></div><div id="cd-34"class="n0"></div></div><div class="line-4"><div id="cd-41" class="n0"></div><div id="cd-42" class="n0"></div><div id="cd-43" class="n0"></div><div id="cd-44" class="n0"></div></div></div><div class="controlButton"><input type="button" value="开始" id="start" onclick="start()"><input type="button" value="重新开始" id="newstart" disabled="disabled" onclick="newstart()"></div><div class="information"><p>温馨提示:该游戏在PC端通过键盘上的方向键进行,在移动端通过滑动屏幕进行!</p></div><div class="number"><div class="line-1"><div id="cd-00" class="n2 n0">2</div><div id="cd-01" class="n4 n0">4</div><div id="cd-02" class="n8 n0">8</div><div id="cd-03" class="n16 n0">16</div></div><div class="line-2"><div id="cd-10" class="n32 n0">32</div><div id="cd-11" class="n64 n0">64</div><div id="cd-12" class="n128 n0">128</div><div id="cd-13" class="n256 n0">256</div></div><div class="line-3"><div id="cd-20" class="n512 n0">512</div><div id="cd-21" class="n1024 n0">1024</div><div id="cd-22" class="n2048 n0">2048</div><div id="cd-23" class="n4096 n0">4096</div></div><div class="line-4"><div id="cd-30" class="n8192 n0">8192</div><div id="cd-31" class="n0"></div><div id="cd-32" class="n0"></div><div id="cd-33" class="n0"></div></div></div>
</body>
</html>

HTML代码中存在下方的代码是为了禁止该网页在移动端进行缩放操作(当然,安卓系统下的UC浏览器貌似不起作用)。其中,initial-scale表示初始缩放比例,maximum-scale表示允许最大的缩放比例,minimum-scale表示允许最小的缩放比例,user-scalable表示是否可手动缩放。一行代码解决手机浏览器禁止缩放的问题。

<meta name="viewport" content="initial-scale=1, width=device-width, maximum-scale=1, minimum-scale=1.0, user-scalable=no">

CSS代码

.information {position: fixed;top: 30px;left: 50px;
}
.information p {color: red;width: 200px;line-height: 24px;
}
.score {font-size: 20px;margin: 30px auto 0; width: 400px;height: 8px;
}
.current-score,.most-score{width: 200px;float: left;text-align: center;
}
.current-score span {color: blue;
}
.most-score span {color: red;
}
.contain {clear: both;height: 400px;width: 400px;background-color: #ccc;margin: 40px auto 20px;padding: 5px;
}
.n0,.n2,.n4,.n8,.n16,.n32,.n64,.n128,.n256,.n512,.n1024,.n2048,.n4096,.n8192 {height: 90px;width: 90px;background-color: gray;float: left;margin: 5px;font-size: 30px;text-align: center;line-height: 90px;color: #fff;
}
.controlButton {width: 400px;height: 50px;margin: 0 auto;text-align: center;
}
#newstart {color: graytext;
}
/*设置每个数字的样式*/
.n2{background-color: #fff;color: black;}
.n4{background-color: #ede0c8;color: black;}
.n8{background-color: #f2b179;}
.n16{background-color: #f59563;}
.n32{background-color: #f67c5f;}
.n64{background-color: #f65e3b;}
.n128{background-color: #edcf72;}
.n256{background-color: #fec716;}
.n512{background-color: #ddc190;}
.n1024{background-color: #9f8963;}
.n2048{background-color: #cc8100;}
.n4096{background-color: #5d4d32;}
.n8192{background-color: #93c;}
.number{display: none;}
/*当屏幕宽度小于1080px时的样式*/
@media screen and (max-width: 1080px) {.information{position: relative;top: 0;left: 0;text-align: center;}.information p {width: auto;}
}

通过上方的css代码对游戏界面进行布局和配色,其中代码块

@media screen and (max-width: 1080px) {
………………
}

是响应式布局的css写法,表示当屏幕的宽度小于1080px时相应的样式

JS代码

var score,mostScore;
var c=[];
//初始化二维数组,0号,5号单位置为0
for(var i=0;i<=5;i++){c[i]=[];for(var j=0;j<=5;j++)c[i][j] = 0;
}
function start() {controlButton();//控制按钮的可用性score = mostScore = 0;//初始化分数//开始时随机生成两块randomDemo();randomDemo();
}function newstart() {if (confirm("确定要重新开始游戏吗?") == true) {// 将二维数组及当前分数清零for(var i=0;i<=5;i++){c[i]=[];for(var j=0;j<=5;j++){c[i][j] = 0;if(i>0&&j>0&&i<5&&j<5){document.getElementById("cd-"+i+j).innerText = "";document.getElementById("cd-"+i+j).className = "n0";}}}score = 0;document.getElementById("current-score").innerText = score;//重新随机生成两块randomDemo();randomDemo();}
}
//按钮的控制方法
function controlButton() {var s1 = document.getElementById("start");var ns = document.getElementById("newstart");//禁用开始按钮s1.setAttribute("disabled" ,"disabled");s1.style.color="graytext";//解禁重新开始按钮ns.removeAttribute("disabled");ns.style.color="inherit";
}
//随机生成方块
function randomDemo() {var randomnum,i,j;//随机产生坐标i = Math.floor(Math.random() * 4)+1;j = Math.floor(Math.random() * 4)+1;//生成新的方块if(c[i][j]==0){randomnum = Math.random()<0.75 ? 2:4;c[i][j] = randomnum;document.getElementById("cd-"+i+j).innerText = randomnum;document.getElementById("cd-"+i+j).className = "n"+randomnum;return true;}else return randomDemo();
}
//界面的更新方法
function update() {for(var i=1;i<=4;i++){for(var j=1;j<=4;j++){var pre = document.getElementById("cd-"+i+j);//当前对象if(c[i][j] != 0){pre.className = "n"+c[i][j];pre.innerText = c[i][j];}else {pre.className = "n0";pre.innerText = "";}}}
}
//判断是否可以左移
function canLeft() {for(var i=1;i<=4;i++){if(c[i][2]+c[i][3]+c[i][4]!=0){if(c[i][1]==0)return true;else if(c[i][2]==0)return true;else if(c[i][2]==c[i][1]||c[i][2]==c[i][3]||(c[i][4]!=0&&c[i][3]==c[i][4])||(c[i][3]==0&&c[i][4])!=0)return true;}    }return false;
}
//判断是否可以右移
function canRight() {for(var i=1;i<=4;i++){if(c[i][2]+c[i][3]+c[i][1]!=0){if(c[i][4]==0)return true;else if(c[i][3]==0)return true;else if(c[i][3]==c[i][4]||c[i][3]==c[i][2]||(c[i][1]!=0&&c[i][1]==c[i][2])||(c[i][2]==0&&c[i][1])!=0)return true;}}return false;
}
//判断是否可以上移
function canUp() {for(var i=1;i<=4;i++){if(c[2][i]+c[3][i]+c[4][i]!=0){if(c[1][i]==0)return true;else if(c[2][i]==0)return true;else if(c[3][i]==0 && c[4][i]!=0)return true;else if((c[3][i]!=0&&c[3][i]==c[4][i])||c[3][i]==c[2][i]||(c[1][i]==c[2][i]))return true;}}return false;
}
//判断是否可以下移
function canDown() {for(var i=1;i<=4;i++){if(c[2][i]+c[3][i]+c[1][i]!=0){if(c[4][i]==0)return true;else if(c[3][i]==0)return true;else if(c[2][i]==0 && c[1][i]!=0)return true;else if((c[1][i]!=0&&c[1][i]==c[2][i])||c[3][i]==c[2][i]||(c[3][i]==c[4][i]))return true;}       }return false;
}
//左移方法
function left() {var l = canLeft();for(var i=1;i<=4;i++){//1.先将一行内的元素以0为界排列好,如2020排成2200for(var j=4;j>1;j--){if(c[i][j-1] == 0){c[i][j-1]+=c[i][j];k=j;while(k<5){c[i][k] = c[i][k+1];k++;}}}//2.合并相同且相邻的方块并更新数组for(var j=1;j<4;j++){if(c[i][j]==c[i][j+1] && c[i][j]!=0){c[i][j]*=2;switch(c[i][j]){case 512:alert("恭喜您合并成512方块!");break;case 1024:alert("恭喜您合并成1024方块!");break;case 2048:alert("恭喜您合并成2048方块!");break;case 4096:alert("恭喜您合并成4096方块!");break;case 8192:alert("恭喜您合并成8192方块!");}score+=c[i][j];//更新分数document.getElementById("current-score").innerText = score;//判断是否破纪录if(score>mostScore){mostScore = score;document.getElementById("most-score").innerText = score;}k=j+1;//左移数组while(k<5){c[i][k] = c[i][k+1];k++;}}}}update();//更新界面//判断是否可以左移,能则生成方块if(l) randomDemo();
}
//右移方法
function right() {var r = canRight();for(var i=1;i<=4;i++){//1.先将一行内的元素以0为界排列好,如2020排成0022for(var j=1;j<4;j++){if(c[i][j+1] == 0){c[i][j+1]+=c[i][j];k=j;while(k>0){c[i][k] = c[i][k-1];k--;}}}//2.合并相同且相邻的方块并更新数组for(var j=4;j>0;j--){if(c[i][j]==c[i][j-1] && c[i][j]!=0){c[i][j]*=2;switch(c[i][j]){case 512:alert("恭喜您合并成512方块!");break;case 1024:alert("恭喜您合并成1024方块!");break;case 2048:alert("恭喜您合并成2048方块!");break;case 4096:alert("恭喜您合并成4096方块!");break;case 8192:alert("恭喜您合并成8192方块!");}score+=c[i][j];//更新分数document.getElementById("current-score").innerText = score;//判断是否破纪录if(score>mostScore){mostScore = score;document.getElementById("most-score").innerText = score;}k=j-1;//数组右移while(k>0){c[i][k] = c[i][k-1];k--;}}}}update();//更新界面//判断是否可以右移,能则生成方块if(r) randomDemo();
}
//上移方法
function up() {var u = canUp();for(var j=1;j<=4;j++){//1.先将一列内的元素以0为界排列好,如2202排成2220for(var i=4;i>1;i--){if(c[i-1][j] == 0){c[i-1][j]+=c[i][j];k=i;while(k<5){c[k][j] = c[k+1][j];k++;}}}//2.合并相同且相邻的方块并更新数组for(var i=1;i<4;i++){if(c[i][j]==c[i+1][j] && c[i][j]!=0){c[i][j]*=2;switch(c[i][j]){case 512:alert("恭喜您合并成512方块!");break;case 1024:alert("恭喜您合并成1024方块!");break;case 2048:alert("恭喜您合并成2048方块!");break;case 4096:alert("恭喜您合并成4096方块!");break;case 8192:alert("恭喜您合并成8192方块!");}score+=c[i][j];//更新分数document.getElementById("current-score").innerText = score;//判断是否破纪录if(score>mostScore){mostScore = score;document.getElementById("most-score").innerText = score;}k=i+1;//数组上移while(k<5){c[k][j] = c[k+1][j];k++;}}}}update();//更新界面//判断是否可以上移,能则生成方块if(u) randomDemo();
}
//下移方法
function down() {var d = canDown();for(var j=1;j<=4;j++){//1.先将一列内的元素以0为界排列好,如2202排成0222for(var i=1;i<4;i++){if(c[i+1][j] == 0){c[i+1][j]=c[i][j];k=i;while(k>0){c[k][j] = c[k-1][j];k--;}}}//2.合并相同且相邻的方块并更新数组for(var i=4;i>0;i--){if(c[i][j]==c[i-1][j] && c[i][j]!=0){c[i][j]*=2;switch(c[i][j]){case 512:alert("恭喜您合并成512方块!");break;case 1024:alert("恭喜您合并成1024方块!");break;case 2048:alert("恭喜您合并成2048方块!");break;case 4096:alert("恭喜您合并成4096方块!");break;case 8192:alert("恭喜您合并成8192方块!");}score+=c[i][j];//更新分数document.getElementById("current-score").innerText = score;//判断是否破纪录if(score>mostScore){mostScore = score;document.getElementById("most-score").innerText = score;}k=i-1;//数组下移while(k>0){c[k][j] = c[k-1][j];k--;}}}}update();//更新界面//判断是否可以下移,能则生成方块if(d) randomDemo();
}
//判断游戏是否结束,即上下左右都不能移动
function over() {if((!(canLeft()||canRight()||canUp()||canDown()))&&document.getElementById("start").disabled)alert("游戏结束,本局分数为"+score+",游戏的最高分数为"+mostScore);
}
//键盘事件的第一种写法
window.addEventListener("keydown",function(e) {if(e.keyCode == 37){e.preventDefault();left();over();}if(e.keyCode == 38){e.preventDefault();up();over();}if(e.keyCode == 39){e.preventDefault();right();over();}if(e.keyCode == 40){e.preventDefault();down();over();}
});
/*
//键盘事件的第二种写法
window.onkeydown = function (e) {if(e.keyCode == 37){e.preventDefault();left();over();}if(e.keyCode == 38){e.preventDefault();up();over();}if(e.keyCode == 39){e.preventDefault();right();over();}if(e.keyCode == 40){e.preventDefault();down();over();}
}*/
//监听移动设备的触摸开始
document.addEventListener('touchstart',function (event) {startx = event.touches[0].pageX;starty = event.touches[0].pageY;
});
//监听移动设备的触摸移动
document.addEventListener('touchmove',function (evnet) {event.preventDefault();
});
//监听移动设备的触摸结束
document.addEventListener('touchend',function (event) {endx = event.changedTouches[0].pageX;endy = event.changedTouches[0].pageY;var x = endx - startx;var y = endy - starty;//xif(Math.abs(x) > Math.abs(y)){if(x > 0){//向右移动if (canRight()){right();}over();} else {//向左移动if (canLeft()){left();}over();}} else if(Math.abs(x) < Math.abs(y)) { //yif (y < 0){//向上移动if (canUp()){up();}over();} else {  //向下移动if (canDown()){down();}over();}}});

JS中,用一个二维数组来存放每个方块的数值,其中适当地留空了某些空间以备数组的移动和变化

  • JS随机函数
代码 含义
Math.random() 表示返回【0,1)之间的随机数
Math.floor(Math.random()*10) 表示返回0至9之间的整数
Math.floor(Math.random()*11) 表示返回0至10之间的整数
  • 合并方块的思路
    (1)当想要往某个方向移动时,先判断是否可往该方向移动,可移动时先将一行(列)中的数组元素以0位界排列好,如当下移时,某列的元素分别是2202,则排列成0222;当右移时,某行的元素分别是2020,则排成0022。不可移动时不生成也不合并不移动方块。
    (2)合并相同且相邻的方块并更新数组、分数和界面。
    (3)判断往某个方向移动时是否可以再生成新的方块

  • 移动端JS触摸touch

(1) 4个监听事件

事件 触发时刻
touchstart 触摸屏幕上时触发
touchmove 触摸屏幕中滑动时触发
touchend 离开屏幕时触发
touchcancel 系统取消触摸事件的时候触发

(2) 监听触摸后触摸事件会实现一个event对象,这个对象里面包括3个触摸函数列表。

函数 触发函数列表
touches 屏幕上所有手指列表
targetTouches 在当前DOM标签上手指的列表
changedTouches 涉及当前事件的手指的列表

(3)触摸函数的属性,用于获取坐标

属性 获取的坐标
clientX 触摸目标在浏览器中的x坐标
clientY 触摸目标在浏览器中的y坐标
identifier 标识触摸的唯一ID
pageX 触摸目标在当前DOM中的x坐标
pageY 触摸目标在当前DOM中的y坐标
screenX 触摸目标在屏幕中的x坐标
screenY 触摸目标在屏幕中的y坐标
target 触摸的DOM节点目标
  • 键盘事件
    对于键盘事件,我在网上找了个链接,大家可以参考一下
    键盘事件讲解链接

Ending
在JS中我的算法思路不是很灵活也不是很高效,但基本还是实现了2048游戏的规则。另外还有一些操作也运用的比较陌生。倘若在阅读的过程中大家有发现错误的或者有更好的建议的,欢迎向我提出,我将感激不尽。

2048小游戏项目总结相关推荐

  1. 2048小游戏项目开发代码

    2048项目开发小游戏(C++) 前言:2048小游戏是我们经常接触的益智小游戏,那么如何完成这个简单游戏的代码操作呢? 代码解析 头文件: #include<stdio.h> #incl ...

  2. 2048小游戏项目招标书(简易版)

    小组成员:胡一铭,陈纪新 立项依据: 2048作为火爆一时的益智小游戏,玩法有创意,操作简易而不简单,在移动游戏盛行的时代,这样一个消磨时间.随时随地可享受的小游戏必然会在游戏市场中独树一帜,受到大众 ...

  3. 2048小游戏----嵌入式系统实训

    嵌入式系统设计实训 引言 本次嵌入式系统实训式设计一款2048小游戏,在Linux编译环境下及ARM Cortex-A8开发平台下的,实现2048游戏的开发,且对其进行性能分析.<2048> ...

  4. 一文梳理2048小游戏从开发到上云全流程

    摘要:本文主要以Cocos2d Web项目2048小游戏的开发上云为例,介绍DevOps开发实践的全流程 前言 本文主要以Cocos2d Web项目2048小游戏的开发上云为例,介绍DevOps开发实 ...

  5. python游戏代码五子棋_用20行Python代码实现2048小游戏,你会吗?

    前些天在b站上看到有个大佬用c写了一个2048小游戏,我便一下来了兴趣.心想着,我貌似也能用Python来整一波,话不多说,直接开搞. 2048的游戏规则: 2048游戏总共有16个格子,初始时会有两 ...

  6. python秒表游戏代码_用20行Python代码实现2048小游戏,你会吗?

    前些天在b站上看到有个大佬用c写了一个2048小游戏,我便一下来了兴趣.心想着,我貌似也能用Python来整一波,话不多说,直接开搞. 2048的游戏规则: 2048游戏总共有16个格子,初始时会有两 ...

  7. 我的名片能运行Linux和Python,还能玩2048小游戏,成本只要20元

    晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 猜猜它是什么?印着姓名.职位和邮箱,看起来是个名片.可是右下角有芯片,看起来又像是个PCB电路板. 其实它是一台超迷你的ARM计算机,不仅 ...

  8. python里graphics的使用_使用graphics.py实现2048小游戏

    1.过年的时候在手机上下载了2048玩了几天,心血来潮决定用py写一个,刚开始的时候想用QT实现,发现依赖有点大.正好看到graphics.py是基于tkinter做的封装就拿来练手,并借用了CSDN ...

  9. html css js实现快递单打印_JS与HTML、CSS实现2048小游戏(六)

    在前面的五篇文章中,小编带大家完成了网页版2048小游戏的基本游戏逻辑.但是在游戏结束的gameover()方法中咱们只是简单的通过alert来弹出一些信息,这样的话只能出现下图的效果.这样的游戏,不 ...

最新文章

  1. 现在很火的答题赢钱游戏,让我来简单教你怎么做自动答题器
  2. boost::hana::int_c用法的测试程序
  3. Github 移动端上架!把世界最大同性交友社区装进口袋
  4. java比较equlse_java基础知识要点
  5. 在yuv域如何降低画面亮度_家庭影院投影机错误地调节了亮度和对比度会得到怎么样的画面?...
  6. 为你的APK进行数字签名
  7. MATLAB挠曲线方程,挠曲线方程.PPT
  8. 高斯滤波 c++实现
  9. 实在小店在B2C平台具有一定的知名度
  10. 【小程序】rpx(responsive pixel)自适应像素浅析
  11. 目前最完美的魔兽世界服务端AzerothCore,Centos系统docker编译教程
  12. R语言 在R中实现vlookup的功能
  13. 网络服务器未运行是什么原因是,Win7系统网络诊断提示诊断策略服务未运行怎么办?...
  14. 计算机操作系统实验之进程调度(一)轮转调度法(C语言)
  15. GTD时间管理简洁做法
  16. Cadence OrCAD Capture 原理图设计过程产生的文件总结与说明
  17. Vector为什么是线程安全的呢?Vector为什么是线程不安全的呢?
  18. 航空专场 | 无人机设计仿真流程讲解与案例实操
  19. 压力传感器/压力变送器分类
  20. 逻辑回归三部曲——逻辑回归项目实战(信贷数据+Python代码实现)

热门文章

  1. 炉石传说酒馆战棋一键拔线(windows)
  2. 罗永浩 AR 创业公司估值 10 亿;​苹果宣布加大 AppStore 广告推送量;​Node.js 19 发布|极客头条...
  3. 掌上游戏机开发指南——GBA程序开发入门
  4. 全球及中国二手车贷款行业运行分析及项目动态研究报告2021年版
  5. python (语音)信号拆分为数据块,计算短期能量和过零率
  6. Linux系统的历史发展演绎
  7. MySQL8高级优化,持续更新......
  8. java实现顺时针螺旋填入
  9. 小米手机便签怎么看写了多少字 小米手机便签统计字数方法
  10. 村淘是什么,农村淘宝有什么用?如何知道宝贝是否加入村淘