JS快速实现移动端拼图游戏


Posted in Javascript onSeptember 05, 2016

最近做的一个简陋的手机端拼图游戏,代码简单易懂,废话不多说了,让大家证明一切吧!

先看下效果图:

JS快速实现移动端拼图游戏

<!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>拼图游戏</h1>
<button id='go'>go</button>
<span id='times'></span>
</div>
<div id='picbox'>
<div class="pic" data-index='1' style='background-position:0px 0px;left:0px;top:0px;'></div>
<div class="pic" data-index='2' style='background-position:-100px 0px;left:100px;top:0px;'></div>
<div class="pic" data-index='3' style='background-position:-200px 0px;left:200px;top:0px;'></div>
<div class="pic" data-index='4' style='background-position:0px -100px;left:0px;top:100px;'></div>
<div class="pic" data-index='5' style='background-position:-100px -100px;left:100px;top:100px;'></div>
<div class="pic" data-index='6' style='background-position:-200px -100px;left:200px;top:100px;'></div>
<div class="pic" data-index='7' style='background-position:0px -200px;left:0px;top:200px;'></div>
<div class="pic" data-index='8' style='background-position:-100px -200px;left:100px;top:200px;'></div>
<div class="pic" data-index='9' style='background-position:-200px -200px;left:200px;top:200px;'></div>
</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');//定时。用于扩展
var dx,dy,newLeft,newtop,startTime,endTime;
go.addEventListener('touchstart',function(){
startTime=Date.parse(new Date()); //获取到期1970年1月1日到当前时间的毫秒数,这个方法不常见,这里为试用
for (var i = 0; i < pic.length; i++) {
pic[i].style.display="block"; //设置显示拼图,游戏开始
}
picbox.style.background="#fff";
for(var i=0;i<20;i++){ //随机打乱
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; //设置拖拽元素的z-index值,使其在最上面。
dx=e.targetTouches[0].pageX-this.offsetLeft; //记录触发拖拽的水平状态发生改变时的位置
dy=e.targetTouches[0].pageY-this.offsetTop; //记录触发拖拽的垂直状态发生改变时的位置
this.startX=this.offsetLeft;//记录当前初始状态水平发生改变时的位置
this.startY=this.offsetTop;//offsetTop等取得的值与this.style.left获取的值区别在于前者不带px,后者带px
this.style.transition='none';
});
pic[i].addEventListener('touchmove',function(e){
newLeft=e.targetTouches[0].pageX-dx; //记录拖拽的水平状态发生改变时的位置
newtop=e.targetTouches[0].pageY-dy;
if(newLeft<=-picWidth/2){ //限制边界代码块,拖拽区域不能超出边界的一半
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'; //设置目标元素的left,top
});
pic[i].addEventListener('touchend',function(e){
this.style.zIndex=0;
this.style.transition='all 0.5s ease 0s'; //添加css3动画效果
this.endX=e.changedTouches[0].pageX-dx;
this.endY=e.changedTouches[0].pageY-dy; //记录滑动结束时的位置,与进入元素对比,判断与谁交换
var obj=change(e.target,this.endX,this.endY); //调用交换函数
if(obj==e.target){ //如果交换函数返回的是自己
obj.style.left=this.startX+'px';
obj.style.top=this.startY+'px';
}else{ //否则
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); //交换函数部分,可提取
}
});
pic[i].addEventListener('transitionend',function(){
if(isSuccess()){
console.log('成功了!'); //此处监听事件有bug,会添加上多次事件。
}else{
// pic[i].removeEventListener('transitionend');
}
})
}
function change(obj,x,y){ //交换函数,判断拖动元素的位置是不是进入到目标原始1/2,这里采用绝对值得方式
for(var i=0;i<pic.length;i++){ //还必须判断是不是当前原素本身。将自己排除在外
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; //返回当前
}
function random(a,b){ //随机打乱函数,其中交换部分,可以提取出来封装
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(){ //判断成功标准
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(){ //定时函数,额。。。待续。
endTime=Date.parse(new Date());
times.innerHTML=(endTime-startTime)/1000||'';
},1000)
</script>
</body>
</html>

代码还有很多可以优化的地方,比如增加定时功能,游戏成功效果和声音特效,手指滑动的自定义事件,左划右划,上划下划,进一步的封装等,额,这样一想又忍不住想试试敲敲代码了。。后续小编在给大家持续更新吧,今天先到这里,希望大家能够喜欢!

Javascript 相关文章推荐
Extjs在exlipse中设置自动提示的方法
Apr 07 Javascript
jQuery+html5实现div弹出层并遮罩背景
Apr 15 Javascript
js+css实现上下翻页相册代码分享
Aug 18 Javascript
javascript学习小结之prototype
Dec 03 Javascript
Javascript中的神器——Promise
Feb 08 Javascript
兼容浏览器的js事件绑定函数(详解)
May 09 Javascript
JavaScript 上传文件(psd,压缩包等),图片,视频的实现方法
Jun 19 Javascript
JS中跳出循环的示例代码
Sep 14 Javascript
JS实现面向对象继承的5种方式分析
Jul 21 Javascript
React Router V4使用指南(精讲)
Sep 17 Javascript
Vue的全局过滤器和私有过滤器的实现
Apr 20 Javascript
vue中组件通信详解(父子组件, 爷孙组件, 兄弟组件)
Jul 27 Javascript
jQuery实现的tab标签切换效果示例
Sep 05 #Javascript
Vue.js每天必学之构造器与生命周期
Sep 05 #Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
Sep 05 #Javascript
JS查找字符串中出现次数最多的字符
Sep 05 #Javascript
node网页分段渲染详解
Sep 05 #Javascript
js对象浅拷贝和深拷贝详解
Sep 05 #Javascript
JS实现隐藏同级元素后只显示JS文件内容的方法
Sep 04 #Javascript
You might like
php判断输入不超过mysql的varchar字段的长度范围
2011/06/24 PHP
深入理解curl类,可用于模拟get,post和curl下载
2013/06/08 PHP
PHP字符串比较函数strcmp()和strcasecmp()使用总结
2014/11/19 PHP
PHP简单获取上月、本月、近15天、近30天的方法示例
2017/07/03 PHP
如何判断图片地址是否失效
2007/02/02 Javascript
简单实用的js调试logger组件实现代码
2010/11/20 Javascript
JQuery以JSON方式提交数据到服务端示例代码
2014/05/05 Javascript
jquery实现个人中心导航菜单效果和美观都非常不错
2014/09/02 Javascript
jQuery获得包含margin的outerWidth和outerHeight的方法
2015/03/25 Javascript
Angularjs制作简单的路由功能demo
2015/04/14 Javascript
JavaScript判断页面加载完之后再执行预定函数的技巧
2016/05/17 Javascript
jquery 无限极下拉菜单的简单实例(精简浓缩版)
2016/05/31 Javascript
使用vue.js实现联动效果的示例代码
2017/01/10 Javascript
js正则表达式验证密码强度【推荐】
2017/03/03 Javascript
jQuery插件FusionCharts绘制2D双折线图效果示例【附demo源码】
2017/04/14 jQuery
详解AngularJS ui-sref的简单使用
2017/04/24 Javascript
JavaScript原型链与继承操作实例总结
2018/08/24 Javascript
JS字符串和数组如何实现相互转化
2020/07/02 Javascript
微信小程序实现单个或多个倒计时功能
2020/11/01 Javascript
vue+Element-ui前端实现分页效果
2020/11/15 Javascript
[06:07]DOTA2-DPC中国联赛3月5日Recap集锦
2021/03/11 DOTA
Python使用PyGreSQL操作PostgreSQL数据库教程
2014/07/30 Python
python requests爬取高德地图数据的实例
2018/11/10 Python
python实现邮件发送功能
2019/08/10 Python
python numpy数组中的复制知识解析
2020/02/03 Python
python线程join方法原理解析
2020/02/11 Python
详解pytorch中squeeze()和unsqueeze()函数介绍
2020/09/03 Python
Python 高效编程技巧分享
2020/09/10 Python
Wedgwood美国官网:英国骨瓷,精美礼品及家居装饰
2018/02/17 全球购物
行政专员的岗位职责
2014/03/10 职场文书
六一儿童节演讲稿
2014/05/23 职场文书
国际贸易毕业生自荐书
2014/06/22 职场文书
党性心得体会
2014/09/03 职场文书
党员群众路线学习心得体会
2014/11/04 职场文书
Nest.js参数校验和自定义返回数据格式详解
2021/03/29 Javascript
python3实现Dijkstra算法最短路径的实现
2021/05/12 Python