内容介绍 1.1 学习内容 本项目是基于 HTML+CSS+JavaScript 实现网页版的拼图游戏。实现过程中将用到 HTML5,CSS3 及 JavaScript 相关知识。完成这个项目,可以进一步扎实前端基础知识。
九宫格拼图相信大家都玩过了,看似简单的小游戏,但实现起来其实并不那么简单。在以前,写程序是程序员的专利,只有他们才能做出一个软件来。但是现在不同了。科技的进步和经济的发展,使得每个人都可以使用计算机。特别是 HTML5 和 CSS3 的流行,使得制作一个基本的游戏变得简单。
下面我们就来做一个九宫格拼图。它的玩法是移动空格块旁边的方块,使得它们按照方块上面标的数字顺序排好。最终的效果:
1.2 实验知识点 本实验涉及以下知识点:
1.3 实验环境 1.4 适合人群 本项目难度一般,适合刚学完前端基础(HTML+CSS+JavaScript)的同学作为练手项目。
1.5 代码获取 附件:
项目原理 根据下面的效果图来观察思考,我们要做的就是设置一个大 DIV 用来包裹里面的小 DIV,然后在里面设置 8 个小 DIV,从 1 开始给他们编号。右边设置两个按钮,点击开始的时候开始计时,完成拼图后停止计时,并弹出一个框,提示完成了。重来按钮是当用户觉得当前有难度的时候,点击重来可以重新开始一个新的拼图,把所有方块打乱顺序,然后开始计时。
我们的重点就是当鼠标点击其中一个方块时,要判断当前方块是否可移动,如果可移动,则移动到相应的位置,如不可移动,则不做任何事。当移动完一块后,要判断是否完成拼图。
我们把那个大 DIV 想象成一个盒子,它有九个位置,从 1 开始,到 9 编号,他们的位置和编号都是不会变的。把里面的 8 个小 DIV 想象成 8 个小盒子,给他们设置 top 和 left 就可以控制他们的位置。每个小 DIV 从 1 开始到 8 编号。他们的位置是可以随意改变的。所以当小 DIV 的编号和大 DIV 的编号全部重合时,就完成了拼图。
所以重点就只有一个了。那就是如何判断是否可移动。这个也简单。我们设置一个一维数组变量,用来保存大 DIV 它里面装的小 DIV 的编号。如果大 DIV 没有小方块,也就表面它是空白块,那么就设为 0。如果当前大 DIV 有小 DIV,那就设置为小 DIV 的编号。然后再设置一个二维数组变量,用来保存大 DIV 的可移动编号。也就是保存这个大 DIV 它所有的可去的位置。比如大 DIV 编号为 2 的,它只能向 1 号,3 号,5 号这三个方向移动。又比如 5,它能向 2、4、6、8 这四个方向移动。我们循环遍历这个变量,如果对应的方向它 没有方块,也就是值为 0,那么它就可以往这个方向移动了。
环境准备 1.准备相关开发工具
2.建立下面的目录结构:
puzzle |__puzzle.html |__puzzle.css |__puzzle.js
实现步骤 1.编写布局 在puzzle.html 中我们有下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <!DOCTYPE html > <html lang ="zh-CN" > <head > <meta charset ="UTF-8" /> <title > Puzzle</title > <link rel ="stylesheet" type ="text/css" href ="puzzle.css" /> <script type ="text/javascript" src ="puzzle.js" > </script > </head > <body > <div id ="container" > <div id ="game" > <div id ="d1" onclick ="move(1)" > 1</div > <div id ="d2" onclick ="move(2)" > 2</div > <div id ="d3" onclick ="move(3)" > 3</div > <div id ="d4" onclick ="move(4)" > 4</div > <div id ="d5" onclick ="move(5)" > 5</div > <div id ="d6" onclick ="move(6)" > 6</div > <div id ="d7" onclick ="move(7)" > 7</div > <div id ="d8" onclick ="move(8)" > 8</div > </div > <div id ="control" > <p > <rowspan id ="timeText" > 总用时</rowspan > <rowspan id ="timer" > </rowspan > </p > <p > <rowspan id ="start" onclick ="start()" > 开始</rowspan > <rowspan id ="reset" onclick ="reset()" > 重来</rowspan > </p > </div > </div > </body > </html >
布局文件就写完了。这里为了简化逻辑,更易编写代码,我们把所有操作都封装了。只要执行 move(2),就是点击了编号为 2 的小方块,后面的一系列操作都完成了。
2.编写样式 布局写完了,现在我们为游戏编写样式,使得它更漂亮。在这一步,大家就可以自己自由发挥了,你可以写出自己的风格,让游戏更漂亮。也可以添加更多的元素来装饰你的游戏。但是注意了,游戏 DIV 的大小如果改变了,一定要记得修改 js 代码,稍后我们会详细讲解。
puzzle.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 * { padding : 0 ; margin : 0 ; border : 0 ; }body { width : 100% ; height : 100% ; }#container { position : relative; width : 620px ; height : 450px ; margin : 0 auto; margin-top : 100px ; border-radius : 1px ; }#game { position : absolute; width : 450px ; height : 450px ; border-radius : 5px ; display : inline-block; background-color : #ffe171 ; box-shadow : 0 0 10px #ffe171 ; }#game div { position : absolute; width : 149px ; height : 149px ; box-shadow : 1px 1px 2px #777 ; background-color : #20a6fa ; color : white; text-align : center; font-size : 150px ; line-height : 150px ; cursor : pointer; -webkit-transition : 0.3s ; -moz-transition : 0.3s ; -ms-transition : 0.3s ; -o-transition : 0.3s ; transition : 0.3s ; }#game div :hover { color : #ffe171 ; }#control { width : 150px ; height : 450px ; display : inline-block; float : right; }#control rowspan { height : 25px ; font-size : 20px ; color : #222 ; margin-top : 10px ; }#start { display : inline-block; font-size : 28px ; width : 100px ; height : 28px ; background-color : #20a6fa ; color : #ffe171 ; text-shadow : 1px 1px 2px #ffe171 ; border-radius : 5px ; box-shadow : 2px 2px 5px #4c98f5 ; text-align : center; cursor : pointer; }#reset { display : inline-block; font-size : 28px ; width : 100px ; height : 28px ; background-color : #20a6fa ; color : #ffe171 ; text-shadow : 1px 1px 2px #ffe171 ; border-radius : 5px ; box-shadow : 2px 2px 5px #4c98f5 ; text-align : center; cursor : pointer; }#d1 { left : 0px ; }#d2 { left : 150px ; }#d3 { left : 300px ; }#d4 { top : 150px ; }#d5 { top : 150px ; left : 150px ; }#d6 { top : 150px ; left : 300px ; }#d7 { top : 300px ; }#d8 { left : 150px ; top : 300px ; }
好了,样式也编写好了。最后再编写一个 js 控制代码,我们的拼图就可以用了。编写样式的时候大家还是先根据我这里的来,等完成了整个游戏,了解游戏逻辑的时候你们再自己发挥想象力去更改样式,不然可能会出现未知的错误。
完成这步,打开 puzzle.html
应该能看到下面的效果了:
3.控制代码的编写 puzzle.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 var time = 0 ;var pause = true ;var set_timer;var d = new Array (10 );var d_direct = new Array ( [0 ], [2 , 4 ], [1 , 3 , 5 ], [2 , 6 ], [1 , 5 , 7 ], [2 , 4 , 6 , 8 ], [3 , 5 , 9 ], [4 , 8 ], [5 , 7 , 9 ], [6 , 8 ] );var d_posXY = new Array ( [0 ], [0 , 0 ], [150 , 0 ], [300 , 0 ], [0 , 150 ], [150 , 150 ], [300 , 150 ], [0 , 300 ], [150 , 300 ], [300 , 300 ] ); d[1 ] = 1 ; d[2 ] = 2 ; d[3 ] = 3 ; d[4 ] = 4 ; d[5 ] = 5 ; d[6 ] = 6 ; d[7 ] = 7 ; d[8 ] = 8 ; d[9 ] = 0 ;function move (id ) { var i = 1 ; for (i = 1 ; i < 10 ; ++i) { if (d[i] == id) break ; } var target_d = 0 ; target_d = whereCanTo(i); if (target_d != 0 ) { d[i] = 0 ; d[target_d] = id; document .getElementById('d' + id).style.left = d_posXY[target_d][0 ] + 'px' ; document .getElementById('d' + id).style.top = d_posXY[target_d][1 ] + 'px' ; } var finish_flag = true ; for (var k = 1 ; k < 9 ; ++k) { if (d[k] != k) { finish_flag = false ; break ; } } if (finish_flag == true ) { if (!pause) start(); alert('congratulation' ); } }function whereCanTo (cur_div ) { var j = 0 ; var move_flag = false ; for (j = 0 ; j < d_direct[cur_div].length; ++j) { if (d[d_direct[cur_div][j]] == 0 ) { move_flag = true ; break ; } } if (move_flag == true ) { return d_direct[cur_div][j]; } else { return 0 ; } }function timer ( ) { time += 1 ; var min = parseInt (time / 60 ); var sec = time % 60 ; document .getElementById('timer' ).innerHTML = min + '分' + sec + '秒' ; }function start ( ) { if (pause) { document .getElementById('start' ).innerHTML = '暂停' ; pause = false ; set_timer = setInterval (timer, 1000 ); } else { document .getElementById('start' ).innerHTML = '开始' ; pause = true ; clearInterval (set_timer); } }function reset ( ) { time = 0 ; random_d(); if (pause) start(); }function random_d ( ) { for (var i = 9 ; i > 1 ; --i) { var to = parseInt (Math .random() * (i - 1 ) + 1 ); if (d[i] != 0 ) { document .getElementById('d' + d[i]).style.left = d_posXY[to][0 ] + 'px' ; document .getElementById('d' + d[i]).style.top = d_posXY[to][1 ] + 'px' ; } if (d[to] != 0 ) { document .getElementById('d' + d[to]).style.left = d_posXY[i][0 ] + 'px' ; document .getElementById('d' + d[to]).style.top = d_posXY[i][1 ] + 'px' ; } var tem = d[to]; d[to] = d[i]; d[i] = tem; } }window .onload = function ( ) { reset(); };
好了,所有代码都已经编写完成了。现在点击桌面上的 puzzle.html
文件,使用 浏览器 打开,就能看到效果了。点击上面的方块就可以移动。
总结 通过此项目,我们利用 HTML5 + CSS3 + JavaScript,实现了一个简单的拼图游戏。
这里说明一下,因为实验中使用的随机打乱方块的算法非常简单,但是存在 bug,有 50% 的概率生成的顺序是无法复原的,这个时候就只能点击重新开始。