代码地址如下:
http://www.demodashi.com/demo/14449.html

项目描述

使用 html+js+css 实现一个网页拼图游戏,可支持简单,中等,困难三种难度。

演示效果

在浏览器直接打开网页即可运行,有三种难度可以选择, 完成拼图会显示所用的时间和步数。

项目结构

  1. Puzzle
  2. ├── chilian.jpg
  3. ├── fifteen.css
  4. ├── fifteen.html
  5. └── fifteen.js

文件夹中只有四个文件,拼图所用的原图以及3个代码文件。

项目实现

1. 显示拼图

拼图的大小是4x4,总共16格,其中有一格是空的,用于移动。html的主体代码如下,拼图区域只需要使用一个div,后续再在js里使用循环构建16个小方块

  1. <body>
  2. <h1>拼图游戏</h1>
  3. <div id="statu">
  4. <img src="chilian.jpg" id="smallPic"><br/>
  5. <label>时间: </label><span id="time">00:00</span>
  6. <label>步数: </label><span id="step">0</span><br/>
  7. <select>
  8. <option selected="selected" value="1">简单模式</option>
  9. <option value="2">中等模式</option>
  10. <option value="3">困难模式</option>
  11. </select>
  12. </div>
  13. <div id="fifteen"></div>
  14. <button id="restart">重新开始</button>
  15. </body>

使用js创建小方块后再插入到fifteen的div中,先将16个存在DocumentFragment中, 最后再一次性添加到html中,页面只需渲染一次, 提高性能

  1. // 创建 4x4 的拼图
  2. function createPuzzle() {
  3. // 先将16个小div存在DocumentFragment, 页面只需渲染一次, 提高性能
  4. var frag = document.createDocumentFragment();
  5. for (var i = 1; i <= 4; ++i) {
  6. for (var j = 1; j <= 4; ++j) {
  7. if (i == 4 && j == 4) {
  8. var empty = document.createElement("div");
  9. empty.setAttribute('id', 'empty');
  10. empty.setAttribute('class', 'row4 col4');
  11. frag.appendChild(empty);
  12. break;
  13. }
  14. var pic = document.createElement("div");
  15. pic.setAttribute("id", "pic" + ((i - 1) * 4 + j));
  16. pic.setAttribute("class", "row" + i + " col" + j);
  17. frag.appendChild(pic);
  18. }
  19. }
  20. document.getElementById("fifteen").appendChild(frag);
  21. }

最后生成小方块的html如下:

  1. <div id="fifteen">
  2. <div id="pic1" class="row1 col1"></div>
  3. <div id="pic2" class="row1 col2"></div>
  4. <div id="pic3" class="row1 col3"></div>
  5. <div id="pic4" class="row1 col4"></div>
  6. <div id="pic5" class="row2 col1"></div>
  7. <div id="pic6" class="row2 col2"></div>
  8. <div id="pic7" class="row2 col3"></div>
  9. <div id="pic8" class="row2 col4"></div>
  10. <div id="pic9" class="row3 col1"></div>
  11. <div id="pic10" class="row3 col2"></div>
  12. <div id="pic11" class="row3 col3"></div>
  13. <div id="pic12" class="row3 col4"></div>
  14. <div id="pic13" class="row4 col1"></div>
  15. <div id="pic14" class="row4 col2"></div>
  16. <div id="pic15" class="row4 col3"></div>
  17. <div id="empty" class="row4 col4"></div>
  18. </div>

有个小方块之后,怎样每格显示不同的图片,有一种方法是可以将大图片等分切割成16张小图篇,但这种方法很麻烦,需要切图,而且代码文件夹里就需要使用到16张图片,这里使用css实现切图,所有的小图都是同一张图片,不需要切割。

因为使用到的图片大小是352x352,所以16等分后是88x88,将小方块的大小设置为86x86,每张小图间刚好多出一条2px的间隔,不会显得太紧凑。每个小方块使用绝对定位,背景图片都是大图,通过设置每个方块的背景图片偏移量,显示出一副完整的图片。

  1. #fifteen div{
  2. width: 86px;
  3. height: 86px;
  4. border: 1px solid #CCCCCC;
  5. margin: 1px;
  6. background-image: url(chilian.jpg);
  7. background-repeat: no-repeat;
  8. position: absolute;
  9. -webkit-transition: all 0.4s;
  10. -moz-transition: all 0.4s;
  11. -ms-transition: all 0.4s;
  12. -o-transition: all 0.4s;
  13. transition: all 0.4s;
  14. }
  15. .row1 {top: 0px;}
  16. .row2 {top: 88px;}
  17. .row3 {top: 176px;}
  18. .row4 {top: 264px;}
  19. .col1 {left: 0px;}
  20. .col2 {left: 88px;}
  21. .col3 {left: 176px;}
  22. .col4 {left: 264px;}
  23. #pic1 {background-position: -0px 0px;}
  24. #pic2 {background-position: -88px 0px;}
  25. #pic3 {background-position: -176px 0px;}
  26. #pic4 {background-position: -264px 0px;}
  27. #pic5 {background-position: 0px -88px;}
  28. #pic6 {background-position: -88px -88px;}
  29. #pic7 {background-position: -176px -88px;}
  30. #pic8 {background-position: -264px -88px;}
  31. #pic9 {background-position: 0px -176px;}
  32. #pic10 {background-position: -88px -176px;}
  33. #pic11 {background-position: -176px -176px;}
  34. #pic12 {background-position: -264px -176px;}
  35. #pic13 {background-position: 0px -264px;}
  36. #pic14 {background-position: -88px -264px;}
  37. #pic15 {background-position: -176px -264px;}
  38. #fifteen #empty {border: none; background: none;}

2. 打乱拼图

在生成打乱的拼图时,随机打乱的拼图不一定可以还原,可能会出现无解的情况,有一种打乱的方法可以确保生成的拼图永远有解:每次交换3张图片的位置, 最后的拼图一定是可还原的,比如将ABC三张图的位置交换为BCA,这算一次交换,可以选择任意三张图,交换任意次,最后生成的拼图肯定都是有解可还原的。

在打乱拼图的时候,分别打乱右下角的3张,8张,以及全部15张图片,可以生成不同难度的拼图,增加趣味性。

  1. // 初始化图片位置, 3 种不同难度
  2. function initPos(difficulty) {
  3. var arr = [];
  4. if (difficulty == 1)
  5. arr = [10, 11, 14];
  6. else if (difficulty == 2)
  7. arr = [5, 6, 7, 9, 10, 11, 13, 14];
  8. else arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
  9. // 随机打乱数组
  10. arr.sort(function () {
  11. return Math.random() - 0.5;
  12. });
  13. // 每次交换3张图片的位置, 最后的拼图一定是可还原的
  14. // 难度越大, 交换的图片数越多
  15. for (i = 0; i < difficulty * 3; i += 3) {
  16. var temp = global.pics[arr[i]].className;
  17. global.pics[arr[i]].className = global.pics[arr[i + 1]].className;
  18. global.pics[arr[i + 1]].className = global.pics[arr[i + 2]].className;
  19. global.pics[arr[i + 2]].className = temp;
  20. }
  21. }

移动拼图

只有点击空白格相邻的图片才能进行移动,移动的时候,将点击图片的class和空白格的class进行交换,因为不同的class背景图片不同,而且css中添加了动画效果,因此交换class后页面上看起来就是图片发生了移动。

判断拼图是否完成时只有判断每个div的class是否与一开始的对应,如果全部相同证明每张图片都回到了起始位置,拼图完成。

  1. global.pics[i].onclick = function () {
  2. if (!global.start) // 未开始游戏, 不移动
  3. return;
  4. var clickPos = this.className.match(/[0-9]/g); // 被点击的图片坐标
  5. var emptyPos = empty.className.match(/[0-9]/g); // 空白格的坐标
  6. // 如果点击图片的坐标合法, 与空白格相邻,和空白格交换
  7. if (isValid(clickPos, emptyPos)) {
  8. var temp = this.className;
  9. this.className = empty.className;
  10. global.empty.className = temp;
  11. ++global.step.innerHTML;
  12. // 判断是否完成拼图
  13. if (isDone())
  14. success();
  15. }
  16. };

其他说明

完整实现请下载代码,注释清晰,推荐使用谷歌浏览器或火狐浏览器打开,有问题可以评论或联系我html+css+js实现网页拼图游戏

代码地址如下:
http://www.demodashi.com/demo/14449.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

html+css+js实现网页拼图游戏的更多相关文章

  1. #3使用html+css+js制作网页 番外篇 使用python flask 框架 (II)

    #3使用html+css+js制作网页 番外篇 使用python flask 框架 II第二部 0. 本系列教程 1. 登录功能准备 a.python中操控mysql b. 安装数据库 c.安装mys ...

  2. #3使用html+css+js制作网页 番外篇 使用python flask 框架 (I)

    #3使用html+css+js制作网页 番外篇 使用python flask 框架(I 第一部) 0. 本系列教程 1. 准备 a.python b. flask c. flask 环境安装 d. f ...

  3. #3使用html+css+js制作网页 番外篇 制作接收php

    使用html+css+js制作网页 番外篇 制作接收php 本系列链接 基础 php语法 例子 本系列链接 #1使用html+css+js制作网站教程 准备 #2使用html+css+js制作网站教程 ...

  4. #3使用html+css+js制作网页 制作登录网页

    #3使用html+css+js制作网页 制作登录网页 本系列链接 2制作登录网页 2.1 准备 2.1.1 创建文件夹 2.1.2 创建主文件 2.2 html部分 2.2.1 网站信息 2.2.2 ...

  5. 用 Flask 来写个轻博客 (28) — 使用 Flask-Assets 压缩 CSS/JS 提升网页加载速度

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 Flask-Assets 将 Flask-Assets 应用 ...

  6. Flexbox + js实现滑动拼图游戏

    滑动拼图就是把一张图片分成几等份,打乱顺序(下图),然后通过滑动拼凑成一张完整的图片. 要实现一个拼图游戏,需要考虑怎样随机的打乱顺序,怎样交换两张图片的位置,等等.但是,使用了Flexbox布局以后 ...

  7. 尝试用Vue.js开发网页小游戏的过程

    准备 首先去官方下载并安装VSCODE,下载地址 https://code.visualstudio.com/.安装后打开会发现是英文版的,需要去安装插件来汉化.具体是在扩展插件搜索chinese,选 ...

  8. 用html+css+js做打地鼠小游戏

    html 代码 first.html <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  9. 原生JS实现拼图游戏

    最近无聊,练练原生JS:实现拼图游戏.两种玩法:第一种是单击元素进行交换位置:第二种是拖拽元素进行位置交换.首先需要上传图片并进行回显(需要用到FileReader):下面是部分截图: 可以自行设置切 ...

随机推荐

  1. 《STL源代码剖析》---stl_set.h阅读笔记

    SET是STL中的标准容器,SET里面的元素会依据键值自己主动排序,它不像map那样拥有实值value和键值key的相应,set仅仅有实值.SET的底层实现时RB-tree,当插入到RB-tree中后 ...

  2. Access control configuration prevents your request from being allo

    我发现在在XP环境下我输入网易的220.181.28.42也找不到网页,就跟在LINUX下一样 都揭示: 错误 您所请求的网址(URL)无法获取 --------------------------- ...

  3. Python Post img

    from poster.encode import multipart_encode from poster.streaminghttp import register_openers import ...

  4. DAO,Service接口与实现类设计

    DAO接口 为每个DAO声明接口的好处在于 1. 可以在尚未实现具体DAO的时候编写上层代码,如Service里对DAO的调用 2. 可以为DAO进行多实现,例如有JDBCDAO实现,MyBatisD ...

  5. 【BZOJ】【1007】【HNOI2008】水平可见直线

    计算几何初步 其实是维护一个类似下凸壳的东西?画图后发现其实斜率是单调递增的,交点的横坐标也是单调递增的,所以排序一下搞个单调栈来做就可以了…… 看了hzwer的做法…… /************* ...

  6. 混沌数学之Duffing(杜芬)振子

    杜芬振子 Duffing oscillator是一个描写强迫振动的振动子,由非线性微分方程表示 杜芬方程列式如下: 其中 γ控制阻尼度 α控制韧度 β控制动力的非线性度 δ驱动力的振幅 ω驱动力的圆频 ...

  7. Spring 事务模板

    最近项目开发中需要用到单机事务,因为项目中使用了Spring和Mybatis框架,所以通过Spring来进行事务的管理,并且记录一下事务配置的过程 第一步:配置DataSource <!-- 发 ...

  8. 第三章 LinkedList源码解析

    一.对于LinkedList需要掌握的八点内容 LinkedList的创建:即构造器 往LinkedList中添加对象:即add(E)方法 获取LinkedList中的单个对象:即get(int in ...

  9. Unity的延迟管线

    unity buildin deferred pipeline rt0 albedo rt1 spec rt2 normal rt3 emissive rt4 shadowmask rt3的使用方式 ...

  10. Android下拉刷新-SwipeRefreshLayout

    现在市面上新闻类的App基本上都有下拉刷新,算是一个标配吧,网上关于下拉刷新的博客也有很多,实现方式可以使用开源的PullToRefresh,自定义ListView,或者可以直接使用LineLayOu ...