拼图游戏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只需简单和几个步骤开 ...
随机推荐
- tomcat配置多个项目通过IP加端口号访问
一个tomcat部署多个项目并通过不同的端口访问 第一步:修改 $TOMCAT_HOME\conf\server.xml文件. 复制Service节点,去掉<Connector port=&qu ...
- ThreadPoolTaskExecutor多线程使用,及线程池配置
1.配置 ThreadPoolTaskExecutor bean <?xml version="1.0" encoding="UTF-8"?> &l ...
- L233
Betty was offended because she felt that her friends had ignored her purposefully(deliberately) at t ...
- JVM --- OutOfMemoryError异常
在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有可能发生OutOfMemoryError(OOM)异常. 1.Java堆溢出 Java堆用于存储对象实例,只要不断地创 ...
- c# winform 中DataGridView绑定List<T> 不能显示数据
遇到问题 DataGridView绑定List后,List更新后再次绑定不显示数据 datagridview 绑定数据源的时候 用List是不能显示修改内容的..要用binginglist<T& ...
- dataGridView1.DataSource,解决查询结果不从第一行显示,而是不断往表下面扩展问题
private void 洱海各月出流流量frm_Load(object sender, EventArgs e) { //在查询按钮中用下面这段代码会出现打开数据库出错的现象 MyTable1.Ro ...
- SWIFT模糊效果
首先创建一个模糊效果 let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light) 接着创建一个承载模糊效果的视图let blurView ...
- jenkins系列(11)-自动打tag升级篇
很久以前,小怪分享过一篇jenkins自动打tag的文章(jenkins系列1--自动打tag),经过在项目实战和改进,我们升级了方案,现在和大家分享.,希望大家在工作中能够用起来. 使用步骤: 1. ...
- 线程池、及使用场景、线程安全封装、ConcurrentHashMap应用场景
https://blog.csdn.net/sinbadfreedom/article/details/80467253 :1.HashMap与ConcurrentHashMap的区别与应用场景 h ...
- CODEFORCES 340 XOR and Favorite Number 莫队模板题
原来我直接学的是假的莫队 原题: Bob has a favorite number k and ai of length n. Now he asks you to answer m queries ...