每个男孩都有一个游戏梦吧,本例简单讲述一款很火的游戏《2048》的制作。

  本例参考地址:https://www.imooc.com/learn/76

游戏准备

  1、游戏的逻辑(2048大家去玩一玩就知道逻辑了)

  2、制作技术:Html,Css,Javascript,Jquery

  3、美术

游戏架构

  

游戏代码

  html代码:

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>2048</title>
<link rel="stylesheet" type="text/css" href="css/index.css">
<script type="text/javascript" src="lib/jquery/jquery.min.js"></script>
<script type="text/javascript" src="js/support.js"></script>
<script type="text/javascript" src="js/animation.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</head>
<body>
<!-- 头部 -->
<header>
<h1>2048</h1>
<a href="javascript:newgame();" id="newgamebutton">New Game</a>
<p>score:<span id="score">0</span></p>
</header> <section id="grid-container">
<div class="grid-cell" id="grid-cell-0-0"></div>
<div class="grid-cell" id="grid-cell-0-1"></div>
<div class="grid-cell" id="grid-cell-0-2"></div>
<div class="grid-cell" id="grid-cell-0-3"></div>
<div class="grid-cell" id="grid-cell-1-0"></div>
<div class="grid-cell" id="grid-cell-1-1"></div>
<div class="grid-cell" id="grid-cell-1-2"></div>
<div class="grid-cell" id="grid-cell-1-3"></div>
<div class="grid-cell" id="grid-cell-2-0"></div>
<div class="grid-cell" id="grid-cell-2-1"></div>
<div class="grid-cell" id="grid-cell-2-2"></div>
<div class="grid-cell" id="grid-cell-2-3"></div>
<div class="grid-cell" id="grid-cell-3-0"></div>
<div class="grid-cell" id="grid-cell-3-1"></div>
<div class="grid-cell" id="grid-cell-3-2"></div>
<div class="grid-cell" id="grid-cell-3-3"></div> </section>
</body>
</html>

  css代码:

 /*头部*/
header {
margin: 0 auto;
width: 500px;
text-align: center;
} header h1 {
font-family: Arial;
font-size: 60px;
font-weight: bold;
} header #newgamebutton {
display: block;
margin: 20px auto; width: 100px;
padding: 10px;
background-color: #8f7a66; font-family: Arial;
color: white;
border-radius: 10px;
text-decoration: none;
} header #newgamebutton:hover {
background-color: #9f8b77;
} header p {
font-family: Arial;
font-size: 25px;
margin: 20px auto;
} /*格子*/
#grid-container {
width: 460px;
height: 460px;
padding: 20px; margin: 50px auto;
background-color: #bbada0; border-radius: 10px;
position: relative;
}
#grid-container .grid-cell {
width: 100px;
height: 100px;
border-radius: 6px;
background-color: #ccc0b3; position: absolute;
} #grid-container .number-cell {
border-radius: 6px; font-family: Arial;
font-weight: bold;
font-size: 60px;
line-height: 100px;
text-align: center; position: absolute;
}

  js部分

  底层js:

 /* 底层支持js */

 //获取格子距离顶部的距离
function getPosTop(i, j) {
return 20 + i * 120;
}
//获取格子距离左边的距离
function getPosLeft(i, j) {
return 20 + j * 120;
} //获取格子背景色
function getNumberBackgroundColor(number) {
switch (number) {
case 2:
return "#eee4da";
break;
case 4:
return "#ede0c8";
break;
case 8:
return "#f2b179";
break;
case 16:
return "#f59563";
break;
case 32:
return "#f67c5f";
break;
case 64:
return "#f65e3b";
break;
case 128:
return "#edcf72";
break;
case 256:
return "#edcc61";
break;
case 512:
return "#9c0";
break;
case 1024:
return "#33b5e5";
break;
case 2048:
return "#09c";
break;
case 4096:
return "#s6c";
break;
case 8192:
return "#93c";
break;
}
return "black";
} //获取格子文字色
function getNumberColor(number) {
if (number <= 4) {
return "#776e65";
}
return "white";
} // 判断格子是否有无空余
function nospace(board) {
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++) {
if (board[row][col] == 0) {
return false;
}
}
}
return true;
} //判断能否左移
function canMoveLeft(board) {
for (var i = 0; i < 4; i++) { for (var j = 1; j < 4; j++) {
if (board[i][j] != 0) { if (board[i][j-1] == 0 || board[i][j-1] == board[i][j]) {
// 左侧格子空 或 左侧盒子等于自己
return true;
}
}
}
}
return false;
} function canMoveRight(board) {
for (var i = 0; i < 4; i++) {
for (var j = 2; j >= 0; j--) {
if (board[i][j] != 0) {
if (board[i][j+1] == 0 || board[i][j+1] == board[i][j]) { return true;
}
}
}
}
return false;
} //判断能否上移
function canMoveUp(board) {
for (var j = 0; j < 4; j++) {
for (var i = 1; i < 4; i++) {
if (board[i][j] != 0) {
if (board[i-1][j] == 0 || board[i-1][j] == board[i][j]) { return true;
}
}
}
}
return false;
} function canMoveDown(board) {
for (var j = 0; j < 4; j++) {
for (var i = 2; i >= 0; i--) {
if (board[i][j] != 0) {
if (board[i+1][j] == 0 || board[i+1][j] == board[i][j]) { return true;
}
}
}
}
return false;
} // 判断水平方向上是否有障碍物
function noBlockHorizontal(row, col1, col2, board) {
for (var i = col1 + 1; i < col2; i++) {
if(board[row][i] != 0){
return false;
}
}
return true;
} // 判断垂直方向是否有障碍物
function noBlockVertical(col, row1, row2, board) {
for (var i = row1 + 1; i < row2; i++) {
if(board[i][col] != 0){
return false;
}
}
return true;
} function nomove(board) {
if(canMoveLeft(board)
|| canMoveRight(board)
|| canMoveUp(board)
|| canMoveDown(board))
return false;
return true;
}

  动画js:

// 显示随机数字
function showNumberWithAnimation(randx, randy, randNumber) {
var numberCell = $("#number-cell-" + randx + "-" + randy);
numberCell.css("background-color", getNumberBackgroundColor(randNumber));
numberCell.css("color", getNumberColor(randNumber));
numberCell.text(randNumber); numberCell.animate({
width: "100px",
height: "100px",
top: getPosTop(randx, randy),
left: getPosLeft(randx, randy)
}, 50);
} // 显示移动动画
function showMoveAnimation(fromx, fromy, tox, toy){
var numberCell = $("#number-cell-" + fromx + "-" + fromy);
numberCell.animate({
top: getPosTop(tox, toy),
left: getPosLeft(tox, toy)
},200);
} function updateScore(score) {
$("#score").text(score);
}

  逻辑js:

 var board = new Array();//全局二维数组
var score = 0;//全局分数
var hasConflicted = new Array();//全局碰撞二维数组 //入口
$(document).ready(function() {
newgame();
}); //新游戏
function newgame() {
// 初始化棋盘格
init();
// 在随机两个各自生成数字
generateOneNumber();
generateOneNumber();
} // 初始化棋盘格
function init() { // 初始位子
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
var gridCell = $("#grid-cell-" + i + "-" + j);
gridCell.css("top", getPosTop(i, j));
gridCell.css("left", getPosLeft(i, j));
}
} // 初始值
for (var i = 0; i < 4; i++) {
board[i] = new Array();
hasConflicted[i] = new Array();
for (var j = 0; j < 4; j++) {
board[i][j] = 0;
hasConflicted[i][j] = false;
}
} // 更新界面显示
updateBoardView(); score = 0;
updateScore(score); } // 更新界面显示
function updateBoardView() {
// 移除已有值的元素
$(".number-cell").remove(); for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
$("#grid-container").append("<div class='number-cell' id='number-cell-" + i + "-" + j + "'></div>");
var theNumberCell = $("#number-cell-" + i + "-" + j); if (board[i][j] == 0) {
theNumberCell.css("width", "0px");
theNumberCell.css("height", "0px");
theNumberCell.css("top", getPosTop(i, j) + 50);
theNumberCell.css("left", getPosLeft(i, j) + 50);
} else {
theNumberCell.css("width", "100px");
theNumberCell.css("height", "100px");
theNumberCell.css("top", getPosTop(i, j));
theNumberCell.css("left", getPosLeft(i, j));
theNumberCell.css("background-color", getNumberBackgroundColor(board[i][j]));
theNumberCell.css("color", getNumberColor(board[i][j]));
theNumberCell.text(board[i][j]); }
hasConflicted[i][j] = false;
}
}
} // 随机在格子中生成一个数
function generateOneNumber() { // 判断格子空间
if (nospace(board)) {
return false;
} // 随机一个位子 var randx = 0;
var randy = 0;
do {
randx = parseInt(Math.floor(Math.random() * 4));
randy = parseInt(Math.floor(Math.random() * 4));
if (board[randx][randy] == 0) break;
}
while(true); // 随机一个数
var randNumber = Math.random() < 0.5 ? 2 : 4 ; // 在随机位子显示随机数
board[randx][randy] = randNumber;
showNumberWithAnimation(randx, randy, randNumber); return true; } // 添加操作事件
$(document).keydown(function(event){
switch(event.keyCode) {
case 37: // left
if(moveLeft()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
console.log(board);
break;
case 38: // up
if(moveUp()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
break;
case 39: // right
if(moveRight()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
break;
case 40: // down
if(moveDown()) {
setTimeout("generateOneNumber()", 210);
setTimeout("isgameover()", 300);
}
break;
default: break;
}
return false;
}); function isgameover(){
if(nospace(board) && nomove(board)) {
gameover();
}
} function gameover(){
alert("gameover");
} // 左移
function moveLeft() {
// 判断能否左移
if(!canMoveLeft(board)) {
return false;
} for (var row = 0; row < 4; row++) {
for (var col = 1; col < 4; col++) {
if(board[row][col] != 0) { for (var k = 0; k < col; k++) {
// 左侧为0
if(board[row][k] == 0 && noBlockHorizontal(row, k, col, board)){
// move
showMoveAnimation(row, col, row, k);
board[row][k] = board[row][col];
board[row][col] = 0;
continue;
}
// 左侧等于自己
else if (board[row][ k] == board[row][col] && noBlockHorizontal(row, k, col, board) && !hasConflicted[row][k])
{
// move
showMoveAnimation(row, col, row, k); // add
board[row][k] += board[row][col];
board[row][col] = 0; score += board[row][k];
updateScore(score); hasConflicted[row][k] = true; continue;
}
}
}
}
} setTimeout("updateBoardView()", 200);
return true;
} // 右移
function moveRight() {
// 判断能否右移
if(!canMoveRight(board)) {
return false;
} for (var row = 0; row < 4; row++) {
for (var col = 2; col >= 0; col--) {
if(board[row][col] != 0) { for (var k = 3; k > col; k--) { if(board[row][k] == 0 && noBlockHorizontal(row, col, k, board)){
// move
showMoveAnimation(row, col, row, k);
board[row][k] = board[row][col];
board[row][col] = 0;
continue;
} else if (board[row][k] == board[row][col] && noBlockHorizontal(row, col, k, board) && !hasConflicted[row][k])
{
// move
showMoveAnimation(row, col, row, k); // add
board[row][k] += board[row][col];
board[row][col] = 0; score += board[row][k];
updateScore(score); hasConflicted[row][k] = true; continue;
}
}
}
}
} setTimeout("updateBoardView()", 200);
return true;
} // 上移
function moveUp() {
// 判断能否上移
if(!canMoveUp(board)) {
return false;
} for (var col = 0; col < 4; col++) {
for (var row = 1; row < 4; row++) { if(board[row][col] != 0) { for (var k = 0; k < row; k++) { if(board[k][col] == 0 && noBlockVertical(col, k, row, board)){
// move
showMoveAnimation(row, col, k, col);
board[k][col] = board[row][col];
board[row][col] = 0;
continue;
} else if (board[k][col] == board[row][col] && noBlockVertical(col, k, row, board) && !hasConflicted[k][col])
{
// move
showMoveAnimation(row, col, k, col); // add
board[k][col] += board[row][col];
board[row][col] = 0; score += board[k][col];
updateScore(score); hasConflicted[k][col] = true; continue;
}
}
}
}
} setTimeout("updateBoardView()", 200);
return true;
} // 下移
function moveDown() {
// 判断能否下移
if(!canMoveDown(board)) {
return false;
} for (var col = 0; col < 4; col++) { for (var row = 2; row >= 0; row--) {
if(board[row][col] != 0) { for (var k = 3; k > row; k--) { if(board[k][col] == 0 && noBlockVertical(col, row, k, board)){
// move
showMoveAnimation(row, col, k, col);
board[k][col] = board[row][col];
board[row][col] = 0;
continue;
} else if (board[k][col] == board[row][col] && noBlockVertical(col, row, k, board) && !hasConflicted[k][col])
{
// move
showMoveAnimation(row, col, k, col); // add
board[k][col] += board[row][col];
board[row][col] = 0; score += board[k][col]
updateScore(score); hasConflicted[k][col] = true;
continue;
}
}
}
}
} setTimeout("updateBoardView()", 200);
return true;
}

游戏展示

  普通版地址:http://naughty7878.top/game/2048

  优化版地址:http://naughty7878.top/game/2048plus

游戏优化

  1、随机数的参数,怎么更加准确的找空空位,在随机空位中产生随机数

  2、增加分数时,增加动画。

  3、游戏结束时,动画结束

  4、私人定制游戏,显示时:2-->小白,4-->实习生,8 -->程序猿,16-->项目经理

  5、操作问题,怎么鼠标操作,触摸滑动操作

  6、设备适配的问题,兼容手机等。

  

【Game】2048小游戏的更多相关文章

  1. jQuery实践-网页版2048小游戏

    ▓▓▓▓▓▓ 大致介绍 看了一个实现网页版2048小游戏的视频,觉得能做出自己以前喜欢玩的小游戏很有意思便自己动手试了试,真正的验证了这句话-不要以为你以为的就是你以为的,看视频时觉得看懂了,会写了, ...

  2. C# 开发2048小游戏

    这应该是几个月前,闲的手痒,敲了一上午代码搞出来的,随之就把它丢弃了,当时让别人玩过,提过几条更改建议,但是时至今日,我也没有进行过优化和更改(本人只会作案,不会收场,嘎嘎),下面的建议要给代码爱好的 ...

  3. Swift实战之2048小游戏

    上周在图书馆借了一本Swift语言实战入门,入个门玩一玩^_^正好这本书的后面有一个2048小游戏的实例,笔者跟着实战了一把. 差不多一周的时间,到今天,游戏的基本功能已基本实现,细节我已不打算继续完 ...

  4. 如何在CentOS上安装一个2048小游戏

    如何在centos上安装一个2048小游戏 最近在学习CentOS系统,就琢磨着玩点什么,然后我看到有人在玩2048小游戏,所有我就在想,为啥不装一个2048小游戏搞一下嘞,于是乎,我就开始工作啦 由 ...

  5. js、jQuery实现2048小游戏

    2048小游戏 一.游戏简介:  2048是一款休闲益智类的数字叠加小游戏 二. 游戏玩法: 在4*4的16宫格中,您可以选择上.下.左.右四个方向进行操作,数字会按方向移动,相邻的两个数字相同就会合 ...

  6. 用js实现2048小游戏

    用js实现2048小游戏 笔记仓库:https://github.com/nnngu/LearningNotes 1.游戏简介 2048是一款休闲益智类的数字叠加小游戏.(文末给出源代码和演示地址) ...

  7. 2048小游戏代码解析 C语言版

    2048小游戏,也算是风靡一时的益智游戏.其背后实现的逻辑比较简单,代码量不算多,而且趣味性强,适合作为有语言基础的童鞋来加强编程训练.本篇分析2048小游戏的C语言实现代码. 前言 游戏截图:  游 ...

  8. Docker从0开始之部署一套2048小游戏

    本文记录一下在docker部署一套2048小游戏的过程,在娱乐中熟悉docker的应用部署.docker 安装不在本文讲述之中,参考我的其它博客. 1.获取image镜像. 方法一:daocloud. ...

  9. 使用JS实现2048小游戏

    JS实现2048小游戏源码 效果图: 代码如下,复制即可使用: (适用浏览器:360.FireFox.Chrome.Opera.傲游.搜狗.世界之窗. 不支持Safari.IE8及以下浏览器.) &l ...

  10. 2048小游戏4X4C语言

    */ #include<stdio.h> #include<stdlib.h> #include<conio.h> #include<time.h> v ...

随机推荐

  1. spket插件安装并设置JQuery自动提示(转)

    spket是一个开发JavaScript.jQuery.Ext_js等的开发工具,它可以 是独立的IDE,也可以作为Eclipse的插件使用,下面介绍如何在Eclipse中安装spket插件: 1.首 ...

  2. RecyclerView的单击和长按事件(转)

    转自:http://www.jianshu.com/p/f2e0463e5aef 前言 上一篇文章揭开RecyclerView的神秘面纱(一):RecyclerView的基本使用中,主要讲述了Recy ...

  3. powerdesigenr设置主外键颜色

    使用PowerDesigner时,它默认table的字体大小颜色等非常难看: 如果通过 Symbol ---> Format进行设置,只能对选中的最修改,新建的Table无效. 可以通过如下修改 ...

  4. racktables 后期维护

    一.网站与数据库分离 vim secret.php #$pdo_dsn = 'mysql:host=localhost;dbname=racktables'; #$db_username = 'roo ...

  5. verilog之inout

    1.inout 类型的data信号 写操作有效时(rd_wr_l=0):data端口输入信号,此时data为高阻态,允许对其进行赋值. 读操作有效时(rd_wr_l=1):data端口输出信号,此时d ...

  6. spring上下文快速获取方法

    import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContex ...

  7. xadmin系列之django的url分发的方式

    一.先介绍一下我们自己的urls中是如何进行路由分发的 一.一级路由 urlpatterns = [ url(r'^upload/', views.upload,name="upload&q ...

  8. 34-ssm 最简洁的模板

    见 csdn :https://download.csdn.net/download/qq_39451578/10931448

  9. 如何将python中的List转化成dictionary

    问题1:如何将一个list转化成一个dictionary? 问题描述:比如在python中我有一个如下的list,其中奇数位置对应字典的key,偶数位置为相应的value list : ['品牌', ...

  10. AttributeError: 'WebElement' object has no attribute 'send_keys'

    这个是没问题的代码:用来打开谷歌搜索cheese并退出 from selenium import webdriver from selenium.common.exceptions import Ti ...