12.JavaScript实现拼图游戏源码
程序员文章站
2022-06-27 20:30:04
目前代码没有放到GitHub上,之后会放出链接 1.目录结构: 2.index.html文件:
目前代码没有放到github上,之后会放出链接
1.目录结构:
2.index.html文件:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>document</title> </head> <body> <div class="clearfix"> <!-- 拼图游戏 --> <div style="float:left;" class="picture-puzzle"> </div> <!-- 对比图片 --> <div style="float:right;"> <img src="./image/dog.jpg" alt=""> </div> </div> <script src="./js/index.js"></script> </body> </html>
3.index.js文件:
// 游戏参数 var gameconfig = { width: 589, //整张图片的宽度 height: 416, //整张图片的高度 row: 3, //小方块的行数 cols: 3, //小方块的列数 imageurl: "./image/dog.jpg", //图片的路径 dom: document.getelementsbyclassname("picture-puzzle")[0], //游戏容器的dom isover: false, //游戏是否结束 minstep: 30,//打乱拼图的最小步数 maxstep: 100//打乱拼图的最大步数 // ishavesolution: false //游戏是否有解 } gameconfig.piecewidth = gameconfig.width / gameconfig.row; //每个小块的宽度 gameconfig.pieceheight = gameconfig.height / gameconfig.cols; //每个小块的高度 var blocks = []; //存储每个小块的信息 //小方块构造函数 function block(row, cols) { // this.sequencenumber; //方块的编号从1到(row*cols)-1;空白格编号为0 this.width = gameconfig.piecewidth; //宽 this.height = gameconfig.pieceheight; //高 this.correctrow = row; //小方块所在正确的行数,用来判断方块行数是否正确 this.correctcols = cols; //小方块所在正确的列数,用来判断方块列数是否正确 this.row = row; //小方块当前所在行数 this.cols = cols; //小方块当前所在列数 this.isdisplay = false; //是否是空白块:true.是;false:否; this.div = document.createelement("div"); this.div.style.width = gameconfig.piecewidth + "px"; this.div.style.height = gameconfig.pieceheight + "px"; this.div.style.background = `url("${gameconfig.imageurl}") -${this.correctcols * this.width}px -${this.correctrow * this.height}px`; this.div.style.border = "1px solid #fff"; this.div.style['box-sizing'] = "border-box"; this.div.style.position = "absolute"; this.show = function () { //展示小方块显示的位置 this.div.style.left = this.cols * gameconfig.piecewidth + "px"; this.div.style.top = this.row * gameconfig.pieceheight + "px"; } this.show(); if (row === gameconfig.row - 1 && cols === gameconfig.cols - 1) { //最后一方块隐藏 this.div.style.display = "none"; this.isdisplay = true; //是否是空白块:true.是;false:否; } gameconfig.dom.appendchild(this.div); this.iscorrect = function () { //判断方块当前位置的行列是否等于正确位置的行列 if (this.row === this.correctrow && this.cols === this.correctcols) { return true; } return false; } } //初始化游戏 function init() { //1.初始化游戏容器宽度 initgamedom(); //2.初始化每个小方块基本信息 initblocksarray(); //3.乱序拼图可解的算法没有看懂,只能程序自动走100步 // while (!gameconfig.ishavesolution) { randomsort(); // } //4.注册点击事件 registerevent(); //初始化游戏容器 function initgamedom() { gameconfig.dom.style.width = gameconfig.width + "px"; gameconfig.dom.style.height = gameconfig.height + "px"; gameconfig.dom.style.border = "2px solid #ccc"; gameconfig.dom.style.position = "relative"; } //初始化小方块数组信息 function initblocksarray() { for (var i = 0; i < gameconfig.row; i++) { for (var j = 0; j < gameconfig.cols; j++) { // 每个小块的基本信息 var block = new block(i, j); blocks.push(block); } } // blocks.foreach(function (item, index) { // item.sequencenumber = index + 1; // }); // blocks[gameconfig.row * gameconfig.cols - 1].sequencenumber = 0; //最后一个空白块编号为0 } //把小方块打乱顺序 function randomsort() { var step = getrandom(gameconfig.minstep, gameconfig.maxstep);//随机在[30,100)区间里取出一个数,作为打乱拼图的步数 console.log(step); //程序自走step步,将拼图顺序打乱 for (var i = 0; i < step; i++) { // 找到空白块所在的行和列 var blankblock = blocks.filter(function (item) { return item.isdisplay; }); for (var j = 0; j < blocks.length; j++) { //判断是否可以交换,横坐标相同则纵坐标相差1||纵坐标相同则横坐标相差为1 if (blocks[j].row === blankblock[0].row && math.abs(blocks[j].cols - blankblock[0].cols) === 1 || blocks[j].cols === blankblock[0].cols && math.abs(blocks[j].row - blankblock[0].row) === 1) { exchangeblocks(blocks[j], blankblock[0]); continue; //交换一次后进入下个循环,保障交换次数为step次 } } } // for (var i = 0; i < (gameconfig.row * gameconfig.cols - 1); i++) { // //1.产生一个随机数 // //2.将当前小方块信息和随机选中的小方块信息互换,最后一个空白块位置不变 // var index = getrandom(0, blocks.length - 2); // //交换数据 // exchangeblocks(blocks[i], blocks[index]); // } blocks.foreach(function (item) { item.show(); }); //判断拼图是否有解 // havesolution(); } //判断乱序的拼图是否有解 // function havesolution() { // var count = 0; // //计算逆序列个数,逆序数:前面的编号大于后面的编号的个数 // for (var i = 0; i < blocks.length; i++) { // for (var j = i + 1; j < (blocks.length - 1 - i); j++) { // console.log(i, j, blocks[i].sequencenumber); // if (blocks[i].sequencenumber > blocks[j].sequencenumber) { // count++; // } // } // } // console.log(count); // //计算空白块编号为0所在的位置 // var blankblock = gameconfig.row * gameconfig.cols - 1; // //奇偶性不同则无解 // gameconfig.ishavesolution = (count % 2 != blankblock % 2) ? false : true; // console.log(gameconfig.ishavesolution); // } //为方块注册事件 function registerevent() { //找到空白块 var isdisplayblock = blocks.find(function (item) { return item.isdisplay; }); blocks.foreach(function (item) { item.div.onclick = function () { if (gameconfig.isover) { //游戏结束,则不在继续以下操作 return; } //判断是否可以交换,横坐标相同则纵坐标相差1||纵坐标相同则横坐标相差为1 if (item.row === isdisplayblock.row && math.abs(item.cols - isdisplayblock.cols) === 1 || item.cols === isdisplayblock.cols && math.abs(item.row - isdisplayblock.row) === 1) { exchangeblocks(item, isdisplayblock); } //游戏结束 iswin(); } }); } //交换两个方块的位置 function exchangeblocks(b1, b2) { var temp = b1.row; b1.row = b2.row; b2.row = temp; var temp = b1.cols; b1.cols = b2.cols; b2.cols = temp; // var temp = b1.sequencenumber; // b1.sequencenumber = b2.sequencenumber; // b2.sequencenumber = temp; b1.show(); b2.show(); } //游戏结束 function iswin() { var wrongblocks = blocks.filter(function (item) { //筛选出位置错误的方块 return !item.iscorrect(); }); if (wrongblocks.length === 0) { //所有方块都在正确位置 gameconfig.isover = true; //游戏结束 blocks.foreach(function (item) { item.div.style.display = "block"; item.div.style.border = "none"; }); } } //-------------通用函数----begin-----------// //返回一个[min,max)区间的随机数 function getrandom(min, max) { return math.floor(math.random() * (max - min)) + min; } //-------------通用函数----end-----------// } init();
代码中都有简单注释,有什么问题请在评论中提出,这里只讲解拼图初始化时打乱拼图顺序所用的方法。
在网上找了好多拼图的可解算法,都没有看太懂,若读者知道或有实现方法,请赐教。
我这里使用randomsort()方法,让正确的顺序自动走一定的步数去打乱拼图的顺序。
4.图片文件
可以从网上随意找一张图片放到1中的image文件夹下,记得更改图片名称和路径(imageurl),和图片的width和height
上图中是游戏的参数配置,可以自己修改下row,cols,minstep,maxstep看下效果
效果展示:
上一篇: vue 数据双向绑定 个人实现版
下一篇: C打印楼梯,同时在楼梯上方打印两个笑脸
推荐阅读
-
jQuery+Ajax+PHP实现“喜欢”评级功能附源码下载
-
PHP strtotime函数用法、实现原理和源码分析
-
浅谈谁都能看懂的单点登录(SSO)实现方式(附源码)
-
自定义GridView并且实现拖拽(附源码)
-
Android中实现多行、水平滚动的分页的Gridview实例源码
-
ThinkPHP6源码:从Http类的实例化看依赖注入是如何实现的
-
Python Django框架实现商城项目源码加设计文档和注释
-
jQuery插件FusionWidgets实现的Bulb图效果示例【附demo源码下载】
-
jQuery插件FusionWidgets实现的Cylinder图效果示例【附demo源码】
-
jQuery插件FusionWidgets实现的AngularGauge图效果示例【附demo源码】