拼图游戏js
实现算法:
1. JavaScript动态生成拼图:通过生成16个div,且除最后一个div不使用背景图片以外,其他div都设置拼图图片为背景。然后通过调整background-position来实现效果图中的拼图效果;
2. 打乱拼图:定义一个大小为15的数组,且其中的值依次为1-15,然后通过定义一个比较函数,利用sort(cmp)实现随机打乱,也就生成了一个随机数组,然后根据这个数组改变类名,定义拼图分块的位置;
function cmp() {
return 0.5-Math.random();
}
1
2
3
但是,生成的拼图不一定能恢复到原来的样子,必须进行验证,如果没有通过验证,则需要重新生成随机数组,对于这个验证,可以详见这篇博文: 15迷问题的证明(15 puzzle)
3 .非常重要:id用来代表图片的特定位置,如第一行第一个,第二行第三个等,然后通过类来定义left与top属性,即可以通过改变类名来实现元素的移动。
4. 元素的移动:需要判断点击的方格是否与空方格相邻,可以通过offsetTop与offsetLeft属性进行比较判断,然后通过交换被点击方格与空白方格的类名来实现;
5. 检查是否结束游戏:生成拼图时,id与position是一一对应的,因此只需要判断所有元素是否都一一对应,如果都一一对应,游戏结束,否则,继续。
代码如下:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Fifteen_puzzle</title>
<link rel="stylesheet" type="text/css" href="CSS/puzzle.css">
<script type="text/javascript" src="JS/puzzle.js"></script>
</head>
<body>
<h1> 拼图游戏 </h1>
<div id="result"></div>
<div id="picture"></div>
<div id="restart">重新开始</div>
<div id="change_image">更换图片</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CSS:
/* 大布局定位 */
html, body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
}
/* 元素居中 */
body {
text-align: center;
}
/* 结果显示 */
#result {
width: 200px;
height: 50px;
font-size: 40px;
color: red;
font-family: Courier, "Andale Mono", Arial, sans-serif;
}
#picture, #restart, #result, #change_image {
margin-top: 30px;
margin-left: auto;
margin-right: auto;
}
/* 拼图容器 */
#picture {
position: relative;
width: 350px;
height: 355px;
margin-bottom: 30px;
}
/* 重新开始按钮 */
#restart, #change_image {
cursor: pointer;
width: 120px;
height: 40px;
line-height: 40px;
background-color: #4286F5;
box-shadow: 3px 4px 15px black;
color: white;
font-size: 18px;
opacity: 0.7;
}
#restart:hover, #change_image:hover {
opacity: 1;
transform: scale(1.1);
}
/* 图片分块 */
.picture_part0 {
background: url("../Image/1.jpg") no-repeat;
}
.picture_part1 {
background: url("../Image/2.jpg") no-repeat;
}
.picture_part0, .picture_part1 {
transition-duration: 0.2s;
position: absolute;
border: solid 1px #969696;
display: inline-block;
width: 83px;
height: 83px;
margin-bottom: -4px;
opacity: 0.9;
}
.picture_part:hover {
opacity: 1;
transform: scale(1.05);
}
/* 类名 position_x 代表了位置 */
.position_1, .position_2, .position_3, .position_4 {
top: 0px;
}
.position_5, .position_6, .position_7, .position_8 {
top: 85px;
}
.position_9, .position_10, .position_11, .position_12 {
top: 170px;
}
.position_13, .position_14, .position_15, .position_16 {
top: 255px;
}
.position_1, .position_5, .position_9, .position_13 {
left: 0px;
}
.position_2, .position_6, .position_10, .position_14 {
left: 85px;
}
.position_3, .position_7, .position_11, .position_15 {
left: 170px;
}
.position_4, .position_8, .position_12, .position_16 {
left: 255px;
}
/* id _position_x 代表每一个分块 */
#_position_1 {
background-position: 0px 0px;
}
#_position_2 {
background-position: -85px 0px;
}
#_position_3 {
background-position: -169px 0px;
}
#_position_4 {
background-position: -253px 0px;
}
#_position_5 {
background-position: 0px -84px;
}
#_position_6 {
background-position: -85px -84px;
}
#_position_7 {
background-position: -169px -84px;
}
#_position_8 {
background-position: -253px -84px;
}
#_position_9 {
background-position: 0px -168px;
}
#_position_10 {
background-position: -85px -168px;
}
#_position_11 {
background-position: -169px -168px;
}
#_position_12 {
background-position: -253px -168px;
}
#_position_13 {
background-position: 0px -252px;
}
#_position_14 {
background-position: -85px -252px;
}
#_position_15 {
background-position: -169px -252px;
}
#_position_16 {
opacity: 0;
background-position: -253px -252px;
background-image: none;
}
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
JavaScript:
/*
项目:拼图游戏
*/
window.onload = function() {
create_pic();
document.getElementById("restart").addEventListener("click", random_pos);
document.getElementById("change_image").addEventListener("click", change_img);
};
/* 检查产生的随机数列是否是合理的,因为有可能出现恢复不到原图的情况 */
function check_random_isValid() {
var count = 0;
for (var i = 0; i < 16; i++) {
for (var j = i+1; j < 16; j++) {
if (random_arr[j] < random_arr[i]) {
count++;
}
}
}
return count%2===0;
}
/* 产生拼图 */
function create_pic() {
picture = document.getElementById("picture");
for (var i = 1; i <= 16; i++) {
var part = document.createElement("div");
part.addEventListener("click", pic_move);
part.className = "picture_part" + count + " position_"+i;
picture.appendChild(part);
part.id = "_position_"+i;
}
}
/* 改变图片 */
var count = 0;
function change_img(event) {
if (count < 1) count++;
else return;
for (var i = 0; i < 16; i++) {
picture.childNodes[i].className += " picture_part" + count;
}
}
/* 产生随机数列定义位置 */
function random_pos(event) {
document.getElementById("result").innerText = "";
/* 产生随机数列前先将拼图块对应的位置复位 */
for (var k = 1; k <= 16; k++) {
document.getElementById("_position_"+k).className="picture_part"+count+" position_"+k;
}
var part = document.getElementById("picture").childNodes;
random_arr = [];
for (var j = 0; j < 15; j++) {
random_arr[j] = j+1;
}
/* 利用sort和cmp进行随机打散 */
function cmp() { return 0.5-Math.random(); }
while(1) {
random_arr.sort(cmp);
if (check_random_isValid()) {
break;
}
}
/* 通过更改类名来改变位置 */
for (var i = 0; i < 15; i++) {
part[i].className = "picture_part" + count + " position_" + random_arr[i];
}
}
/* 点击图片触发的事件处理器 */
function pic_move(event) {
var blank_pic_offset = document.getElementById("_position_16");
var blank_pic_offset_top = blank_pic_offset.offsetTop;
var blank_pic_offset_left = blank_pic_offset.offsetLeft;
var _offset_top = this.offsetTop;
var _offset_left = this.offsetLeft;
/* 判断点击的图片块是否与空格块相邻 */
if ((Math.abs(blank_pic_offset_top-_offset_top) == 85 && blank_pic_offset_left == _offset_left) ||
(Math.abs(blank_pic_offset_left-_offset_left) == 85 && blank_pic_offset_top == _offset_top)) {
var str = blank_pic_offset.className;
blank_pic_offset.className = this.className;
this.className = str;
check(); // 检查是否还原原图
}
}
/* 检查是否还原原图 */
function check() {
for (var i = 1; i <= 16; i++) {
var item = document.getElementById("_position_"+i);
if (item.className != "picture_part" + count +" position_"+i &&
item.className != "picture_part0" + " position_" + i + " picture_part1") {
document.getElementById("result").innerText = "Continue...";
return;
}
}
document.getElementById("result").innerText = "You Win!";
}
拼图游戏js的更多相关文章
- 拼图游戏(js,C#,java三种语言)
<html> <head> <meta charset="utf-8"> <style type="text/css" ...
- 利用Vue.js实现拼图游戏
之前写过一篇<基于Vue.js的表格分页组件>的文章,主要介绍了Vue组件的编写方法,有兴趣的可以访问这里进行阅读:http://www.cnblogs.com/luozhihao/p/5 ...
- Vue.js实现拼图游戏
Vue.js实现拼图游戏 之前写过一篇<基于Vue.js的表格分页组件>的文章,主要介绍了Vue组件的编写方法,有兴趣的可以访问这里进行阅读:http://www.cnblogs.com/ ...
- html+css+js实现网页拼图游戏
代码地址如下:http://www.demodashi.com/demo/14449.html 项目描述 使用 html+js+css 实现一个网页拼图游戏,可支持简单,中等,困难三种难度. 演示效果 ...
- 原生JS实现拼图游戏
最近无聊,练练原生JS:实现拼图游戏.两种玩法:第一种是单击元素进行交换位置:第二种是拖拽元素进行位置交换.首先需要上传图片并进行回显(需要用到FileReader):下面是部分截图: 可以自行设置切 ...
- Flexbox + js实现滑动拼图游戏
滑动拼图就是把一张图片分成几等份,打乱顺序(下图),然后通过滑动拼凑成一张完整的图片. 要实现一个拼图游戏,需要考虑怎样随机的打乱顺序,怎样交换两张图片的位置,等等.但是,使用了Flexbox布局以后 ...
- JavaScript写一个拼图游戏
拼图游戏的代码400行, 有点多了, 在线DEMO的地址是:打开: 因为使用canvas,所以某些浏览器是不支持的: you know: 为什么要用canvas(⊙o⊙)? 因为图片是一整张jpg或 ...
- 微信小程序开发的游戏《拼图游戏》
微信小程序开发的游戏<拼图游戏> 代码直接考进去就能用 pintu.js // pintu.js Page({ /** * 页面的初始数据 */ data: { }, initGame: ...
- 一款html拼图游戏详解
本文是爱编程原创翻译,转载请看清文末的转载要求,谢谢合作! 游戏介绍 这篇文章是献给web游戏开发者用简单的开发工具开发一款游戏.此文介绍了用html.css.javascript只需简单和几个步骤开 ...
随机推荐
- 解决WinForm(C#)中MDI子窗体最大化跑偏的问题
“用MDI方式打开一个子窗口体后,总是不能最大化显示,明明子窗口体的WindowState设置为Maximized?”,相信有很多人会遇到这的样问题,请按下面的方法设置即可使MDI子窗体最大化: 1. ...
- kbmMW TkbmMWHashSHA256与Delphi 10.2 THashSHA2算出相同的结果
procedure TForm2.Button3Click(Sender: TObject); var hashed:string; begin hashed:=TkbmMWHashSHA256.Ha ...
- Android输入法框架系统(下)
程序焦点获取事件导致输入法显示 从上面可以知道程序获得焦点时,程序端会先间接的调用IMMS的startInput将焦点View绑定到输入法,然后会调用IMMS的windowGainFocus函数,这个 ...
- MySQL主从数据一致性检验
MySQL主从数据一致性检验 检查主从数据一致性,我们使用pt-table-checksum ,pt-table-checksum是percona-tools一个工具,用来校验主从库数据是不是一致. ...
- Swift中格式化日期
Swift语言中格式化日期跟其它编程语言很相似: var dformatter = NSDateFormatter() dformatter.dateFormat = "yyyy年MM月dd ...
- OC基础:内存(内存管理) 分类: ios学习 OC 2015-06-25 16:50 73人阅读 评论(0) 收藏
自动释放池: @autoreleasepool { } 内存管理机制 谁污染,谁治理 垃圾回收机制:gc(Garbage collection),由系统管理内存,开发人员不需要管理. OC ...
- Android PopupWindow中EditText获取焦点自动弹出软键盘
公司的项目中要求在点击搜索的时候弹出一个搜索框,搜索框中有一个EditText,用于数据搜索关键字,要求在弹出PopupWindow的时候自动弹出软键盘,原以为只要写上着两行代码可以搞的问题: Inp ...
- 关于Gson无法将匿名类转化为json字符串的问题
在使用gson过程中,一般会将数据存在一个对象模型中,使用gson将模型转换成json字符串用于数据交互. 代码形如: ArrayList<String> list = new Array ...
- 【c++基础】如何获取工程项目当前路径
工程项目当前路径 #include <direct.h> int main( ) { ]; _getcwd(buffer, ); std::cout << buffer < ...
- 【opencv基础】cv::Point类型与行列的关系
关系 row == height == Point.y col == width == Point.x Mat::at(Point(x, y)) == Mat::at(y,x) 参考 1.博客: 完