I recently made a simple mobile jigsaw puzzle game. The code is simple and easy to understand. I won’t say much nonsense. Let everyone prove everything!
Let's look at the renderings first:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title><meta name="viewport" id="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"><style type="text/css">html,body,ul,li,ol,dl,dd,dt,p,h1,h2,h3,h4,h5,h6,form,fieldset,legend,img{margin:0;padding:0}body{background: pink;}#picbox{width: 300px;height: 300px;background: url('img/300.jpg');position: relative;margin: 50px auto;}.pic{width: 97px;height: 97px;float: left;background: url('img/300.jpg');position: absolute;transition: all 0.5s ease 0s;}.controller{text-align: center;position: relative;}#times{position: absolute;color: red;top: 15px;left: 300px;font-size: 20px;}</style></head><body><div class='controller'><h1>Jigsaw puzzle</h1><button id='go'>go</button><span id='times'></span></div><div id='picbox'><div data-index='1' style='background-position:0px 0px;left:0px;top:0px;'></div><div data-index='2' style='background-position:-100px 0px;left:100px;top:0px;'></div><div data-index='3' style='background-position:-200px 0px;left:200px;top:0px;'></div><div data-index='4' style='background-position:0px -100px;left:0px;top:100px;'></div><div data-index='5' style='background-position:-100px -100px;left:100px;top:100px;'></div><div data-index='6' style='background-position:-200px -100px;left:200px;top:100px;'></div><div data-index='7' style='background-position:0px -200px;left:0px;top:200px;'></div><div data-index='8' style='background-position:-100px -200px;left:100px;top:200px;'></div><script>var picbox=document.getElementById('picbox');var pic=document.querySelectorAll('.pic');var picWidth=pic[0].offsetWidth;var picHeight=pic[0].offsetHeight;var picboxWidth=picbox.offsetWidth;var picboxHeight=picbox.offsetHeight;var go=document.getElementById('go');var times=document.getElementById('times');//Time. Used to extend var dx,dy,newLeft,newtop,startTime,endTime;go.addEventListener('touchstart',function(){startTime=Date.parse(new Date()); //Get the number of milliseconds from the expiration January 1, 1970 to the current time. This method is not common. Here is a trial for (var i = 0; i < pic.length; i++) {pic[i].style.display="block"; //Set the display puzzle, the game starts}picbox.style.background="#fff"; for(var i=0;i<20;i++){ //Stochastic disruption of var a = Math.floor(Math.random()*9);var b = Math.floor(Math.random()*9);if(a != b){random(a,b);}}})for(var i=0;i<pic.length;i++){pic[i].addEventListener('touchstart',function(e){this.style.zIndex=100; //Set the z-index value of the drag element so that it is on the top.dx=e.targetTouches[0].pageX-this.offsetLeft; //Record the position when the horizontal state of triggering the drag changes dy=e.targetTouches[0].pageY-this.offsetTop; //Record the position when the vertical state of triggering the drag changes this.startX=this.offsetLeft;//Record the position when the current initial state level changes this.startY=this.offsetTop;//The difference between the values obtained by offsetTop, etc. is that the former does not contain px, and the latter has pxthis.style.transition='none';});pic[i].addEventListener('touchmove',function(e){newLeft=e.targetTouches[0].pageX-dx; //Record the position when the horizontal state of the dragging changes newtop=e.targetTouches[0].pageY-dy;if(newLeft<=-picWidth/2){ //Restrict the boundary code block, the drag area cannot exceed half of the boundary newLeft=-picWidth/2;}else if(newLeft>=(picboxWidth-picWidth/2)){newLeft=(picboxWidth-picWidth/2);}if(newtop<=-picHeight/2){newtop=-picWidth/2;}else if(newtop>=(picboxHeight-picHeight/2)){newtop=(picboxHeight-picHeight/2);}this.style.left=newLeft+'px'; this.style.top=newtop+'px'; //Set left,top} of the target element;pic[i].addEventListener('touchend',function(e){this.style.zIndex=0;this.style.transition='all 0.5s ease 0s'; //Add css3 animation effect this.endX=e.changedTouches[0].pageX-dx; this.endY=e.changedTouches[0].pageY-dy; //Record the position at the end of the slide, compare it with the entry element, and judge who to exchange var obj=change(e.target,this.endX,this.endY); //Calling the exchange function if(obj==e.target){ //If the exchange function returns itself obj.style.left=this.startX+'px';obj.style.top=this.startY+'px';}else{ //Otherwise var _left=obj.style.left;obj.style.left=this.startX+'px';this.style.left=_left;var _top=obj.style.top;obj.style.top=this.startY+'px';this.style.top=_top;var _index=obj.getAttribute('data-index');obj.setAttribute('data-index',this.getAttribute('data-index'));this.setAttribute('data-index',_index); //The exchange function part can be extracted }});pic[i].addEventListener('transitionend',function(){if(isSuccess()){console.log('Success!'); //There is a bug in the listening event here, and multiple events will be added.}else{// pic[i].removeEventListener('transitionend');}})}function change(obj,x,y){ //The exchange function determines whether the drag element's position has entered the original 1/2 of the target. Here, it is absolutely worthwhile for(var i=0;i<pic.length;i++){ //It is also necessary to determine whether it is the current element itself. Exclude yourself if(Math.abs(pic[i].offsetLeft-x)<=picWidth/2&&Math.abs(pic[i].offsetTop-y)<=picHeight/2&&pic[i]!=obj)return pic[i]; }return obj; //Return the current }function random(a,b){ //Random disrupt the function, where the exchange part can be extracted and encapsulated var aEle = pic[a];var bEle = pic[b];var _left ;_left = aEle.style.left;aEle.style.left = bEle.style.left;bEle.style.left = _left;var _top ;_top = aEle.style.top;aEle.style.top = bEle.style.top;bEle.style.top = _top;var _index;_index = aEle.getAttribute("data-index");aEle.setAttribute("data-index",bEle.getAttribute("data-index") );bEle.setAttribute("data-index",_index);}function isSuccess(){ //The criteria for judging success var str=''for(var i=0;i<pic.length;i++){str+=pic[i].getAttribute('data-index');}if(str=='123456789'){return true;}return false;}var time;setInterval(function(){ //Timed function, u...To be continued.endTime=Date.parse(new Date());times.innerHTML=(endTime-startTime)/1000||'';},1000)</script></body></html>There are many ways to optimize the code, such as adding timing functions, game success effects and sound effects, custom events for sliding fingers, left and right strokes, up and down strokes, further packaging, etc. Uh, when you think about it, you can't help but want to try to knock on the code. . The editor will continue to update you later. Let’s come here today. I hope you like it!