拼图欢迎来到程序小院
玩法:
点击右边小格子图根据左边原图进行还原
开始游戏
HTML<div style="margin:0 auto;" id="puzzle-game"></div>
CSS
.puzzle-img img{
width:167px;
height:auto;
position:absolute;
margin-left:120px;
box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9;
}
#puzzle-game{
box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9;
border: 2px solid transparent;
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
}
js
//一:x项目的配置
let gameConfig = {
totalWidth: 500, //总的宽度也就是图片的宽度
totalHeight: 641, //总的高度,也就是图片的高度
rows: 3, //行数
cols: 3, //列数
isVisible: false, //设置当前元素是否隐藏
imgUrl: 'https://www.ormcc.com/uploads/article/298fca6dab61e59f0515aef55728432a.jpg', //图片的路径
blocksArray: [], //放置每一个块的数组
dom: document.querySelector('#puzzle-game') //获取到相应的dom对象
}
gameConfig.blockWidth = gameConfig.totalWidth / gameConfig.cols; //计算每一块的宽度
gameConfig.blockHeight = gameConfig.totalHeight / gameConfig.rows; //计算每一块的高度
gameConfig.blockNums = gameConfig.rows * gameConfig.cols; //总共有多少块
//利用解构获得相关的属性
let {
dom,
totalWidth,
totalHeight,
blockWidth,
blockHeight,
rows,
cols,
blocksArray,
imgUrl,
isVisible
} = gameConfig;
//初始化
init();
function init() {
//初始化外层div
initGameDom();
//初始化内层div
initSmallBlock();
//打乱排序
shuffle();
//玩游戏
play();
//初始化外层大div
function initGameDom() {
setStyle(dom, {
width: totalWidth,
height: totalHeight,
position: 'relative',
})
}
//初始化每个小的div(我们希望,每个小div都是一个对象,
里面包含着关于这个div的所有属性,包括正确的left,top值,
和当前的left,top值)
function initSmallBlock() {
for (let i = 0; i < rows; i ) {
for (let j = 0; j < cols; j ) {
//最后一个元素需要设置隐藏
if ((i == rows - 1) && (j == cols - 1)) {
isVisible = true;
}
blocksArray.push(new Block(j * blockWidth, i * blockHeight, isVisible));
}
}
}
//数组洗牌
function shuffle() {
// blocksArray.sort(() => Math.random() - 0.5);
for (let i = 0; i < blocksArray.length - 1; i ) {
//产生一个随机数,将当前项与随机数的那一项交换left,top值
let index = getRandom(0, blocksArray.length - 2);
exchangeNode(blocksArray[i], blocksArray[index]);
}
//保证与原图一定是不一样的,不然就重新洗过
if (isInOriginal()) {
shuffle();
}
//重新显示
blocksArray.forEach(item => item.show());
}
//
function play() {
//先找 display 为 none的元素
let emptyNode = blocksArray.find(item => item.isVisible);
//遍历数组,为数组中的每一项的dom添加点击事件
blocksArray.forEach(item => {
item.dom.onclick = function () {
//判断一下,如果当前的元素和空的元素在同一行或者同一列,并且相减小于一个宽度,才可以交换
if (emptyNode.top === item.top
&& Math.abs(emptyNode.left - item.left) === blockWidth
|| emptyNode.left === item.left &&
Math.abs(emptyNode.top - item.top) === blockHeight) {
console.log('可以移动')
exchangeNode(emptyNode, item);
if (isInOriginal()) {
setTimeout(() => {
hsycms.tips('tips','恭喜你顺利通过',function(){
location.reload();
},3000)
}, 0);
}
}
}
})
}
//辅助函数
/**
* 产生一个min-max的随机数
* @param {*} min
* @param {*} max
* @returns
*/
function getRandom(min, max) {
return Math.floor(Math.random() * (max 1 - min) min);
}
/**
*
* @param {*} target 需要设置样式的目标
* @param {*} options 需要为目标设置选项的
*/
function setStyle(target, options = {}) {
for (const key in options) {
if (typeof options[key] == 'number') {
options[key] = 'px';
}
target.style[key] = options[key];
}
}
/**
* 交换连个元素的位置
* @param {*} node1
* @param {*} node2
*/
function exchangeNode(node1, node2) {
[node1.left, node2.left] = [node2.left, node1.left];
[node1.top, node2.top] = [node2.top, node1.top];
node1.show();
node2.show();
}
/**
* 根据不同的left,top值产生不同位置的div
* @param {*} left div距离左边的位置
* @param {*} top div距离右边的位置
*/
function Block(left, top, isVisible) {
// 每个小方块就是一个对象,对象里面保存着小方块的
left,top,correctLeft,correctTop,dom,isVisible(是否可见),以及show方法
this.left = left;
this.top = top;
this.correctLeft = this.left;
this.correctTop = this.top;
this.dom = document.createElement('div');
this.isVisible = isVisible;
setStyle(this.dom, {
width: blockWidth,
height: blockHeight,
border: '1px solid #fff',
background: `url("${imgUrl}") -${this.correctLeft}px -${this.correctTop}px`,
position: 'absolute',
cursor: 'pointer',
boxSizing: 'border-box',
display: isVisible ? 'none' : ''
});
dom.appendChild(this.dom);
this.show = function () {
setStyle(this.dom, {
left: this.left,
top: this.top
})
}
}
/**
* 判断每个方块是否在原先的位置上
* @returns
*/
function isInOriginal() {
//循环数组,判断当前位置和正确的位置是否相等
return blocksArray.every(item => item.left
== item.correctLeft
&& item.top == item.correctTop)
}
}
源码
需要源码请关注添加好友哦^ ^
转载:欢迎来到本站,转载请注明文章出处https://ormcc.com/
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved