以下是 jQuery鼠标拖拽拼图游戏js代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery鼠标拖拽拼图游戏 </title>
<link rel="stylesheet" href="css/puzzleGame.css" />
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<!-- 以下两个js文件,一个是面向过程开发(process),一个是面向对象开发(object),修改引入文件既可以切换不同开发代码 -->
<!-- <script src="js/puzzleGame_process.js"></script> -->
<script type="text/javascript" src="js/puzzleGame_object.js"></script>
</head>
<body>
<div id="wrap">
<div id="left">
<ul>
<li id="start">
开始游戏:<span>开始</span>
</li>
<li id="level">
难度选择:<span>3x3</span>
</li>
<li id="gameRule">
游戏介绍:
<p>1、点击游戏难度以更改</p>
<p>2、点击开始游戏,打乱图片</p>
<p>3、交换图片位置,复原图片</p>
</li>
</ul>
</div>
<div id="right">
<div id="imgArea"></div>
</div>
</div>
</body>
</html>
JS代码(puzzleGame_object.js):
/*重要备注:imgOrigArr 和 imgRanfArr这两个数组分别存放正确顺序排列和乱序排列的碎片信息数组结构:arr[碎片节点下标] = 碎片显示位置 */
/** * [puzzleGame 向puzzleGame对象中添加属性] * @param{
[json格式]}
param [图片 路径+名称] * @return [无] */
var puzzleGame = function(param){
/************* 参数处理 ******************/
this.img = param.img || '';
//待操作的图片/************* 节点 ******************/
this.btnStart = $('#wrap #left ul #start span');
//开始游戏按钮this.btnLevel = $('#wrap #left ul #level span');
//难度选择按钮this.imgArea = $('#wrap #right #imgArea');
//图片显示区域this.imgCells = '';
//用于记录碎片节点的变量/************* 变量 ******************/
this.imgOrigArr = [];
//图片拆分后,存储正确排序的数组this.imgRandArr = [];
//图片打乱顺序后,存储当前排序的数组this.levelArr = [[3,3],[4,4],[6,6]];
//存储难度等级的数组this.levelNow = 0;
//表示当前难度等级的变量,与难度数组结合使用//图片整体的宽高this.imgWidth = parseInt(this.imgArea.css('width'));
this.imgHeight = parseInt(this.imgArea.css('height'));
//拆分为碎片后,每一块碎片的宽高this.cellWidth = this.imgWidth/this.levelArr[this.levelNow][1];
this.cellHeight = this.imgHeight/this.levelArr[this.levelNow][0];
this.hasStart = 0;
//记录有是否开始的变量,默认fasle,未开始this.moveTime = 400;
//记录animate动画的运动时间,默认400毫秒//调用初始化函数,拆分图片,绑定按钮功能this.init();
}
/** * [prototype 在puzzleGame对象中添加方法,用json格式表示] * @type{
Object}
*/
puzzleGame.prototype ={
/** * [init 初始化特效设置] * @return [无] */
init:function(){
this.imgSplit();
this.levelSelect();
this.gameState();
}
,/** * [imgSplit 将图片拆分为碎片] * @param obj [图片,路径+名称] * @param cellW [碎片宽度] * @param cellH [碎片高度] * @return [记录正确排序的数组] */
imgSplit:function(){
this.imgOrigArr = [];
//清空正确排序的数组//必须清空图片区域的碎片代码,否则每一次拆分图片是与之前拆分的累积//例如第一次拆分3x3,插入了9个div,但没有清空,第二次拆分4x4,此时是在前9个div之后再插入14个div,共9+16个divthis.imgArea.html("");
var cell = '';
//记录单个图片碎片的变量for(var i=0;
i<this.levelArr[this.levelNow][0];
i++){
for(var j=0;
j<this.levelArr[this.levelNow][1];
j++){
//将碎片所属div的下标存入数组,用于最终校验是否排序完成this.imgOrigArr.push(i*this.levelArr[this.levelNow][1]+j);
cell = document.createElement("div");
cell.className = "imgCell";
$(cell).css({
'width':(this.cellWidth - 2) + 'px','height':(this.cellHeight - 2) + 'px','left':j * this.cellWidth + 'px','top':i * this.cellHeight + 'px',"background":"url('"+this.img+"')",'backgroundPosition':(-j)*this.cellWidth + 'px ' + (-i)*this.cellHeight + 'px'}
);
this.imgArea.append(cell);
}
}
this.imgCells = $('#wrap #right #imgArea div.imgCell');
//碎片节点}
,levelSelect:function(){
var len = this.levelArr.length;
var self = this;
this.btnLevel.bind('mousedown',function(){
$(this).addClass('mouseOn');
}
).bind('mouseup',function(){
$(this).removeClass('mouseOn');
}
).bind('click',function(){
//判断是否在游戏中if(self.hasStart){
if(!confirm('您已经在游戏中,确定要改变游戏难度么?')){
return false;
}
else{
self.hasStart = false;
self.btnStart.text('开始');
}
}
//内容改变self.levelNow ++;
if(self.levelNow >= len){
self.levelNow = 0;
}
//显示的难度改变$(this).text(self.levelArr[self.levelNow][0] + 'x' + self.levelArr[self.levelNow][1]);
//图片重新拆分(先重新计算宽高)self.cellWidth = self.imgWidth/self.levelArr[self.levelNow][1];
self.cellHeight = self.imgHeight/self.levelArr[self.levelNow][0];
self.imgSplit();
}
);
}
,/** * [gameStart 开始/回复 游戏的函数] * @return [无] */
gameState:function(){
var self = this;
this.btnStart.bind('mousedown',function(){
$(this).addClass('mouseOn');
}
).bind('mouseup',function(){
$(this).removeClass('mouseOn');
}
).bind('click',function(){
if(self.hasStart == 0){
//不在游戏中//开始游戏后部分值、样式设置$(this).text('复原');
self.hasStart = 1;
//打乱图片self.randomArr();
self.cellOrder(self.imgRandArr);
//图片事件self.imgCells.css({
'cursor':'pointer'}
).bind('mouseover',function(){
$(this).addClass('hover');
}
).bind('mouseout',function(){
$(this).removeClass('hover');
}
).bind('mousedown',function(e){
/*此处是图片移动*/
$(this).css('cursor','move');
//所选图片碎片的下标以及鼠标相对该碎片的位置var cellIndex_1 = $(this).index();
var cell_mouse_x = e.pageX - self.imgCells.eq(cellIndex_1).offset().left;
var cell_mouse_y = e.pageY - self.imgCells.eq(cellIndex_1).offset().top;
$(document).bind('mousemove',function(e2){
self.imgCells.eq(cellIndex_1).css({
'z-index':'40','left':(e2.pageX - cell_mouse_x - self.imgArea.offset().left) + 'px','top':(e2.pageY - cell_mouse_y - self.imgArea.offset().top) + 'px'}
);
}
).bind('mouseup',function(e3){
//被交换的碎片下标var cellIndex_2 = self.cellChangeIndex((e3.pageX-self.imgArea.offset().left),(e3.pageY-self.imgArea.offset().top),cellIndex_1);
//碎片交换if(cellIndex_1 == cellIndex_2){
self.cellReturn(cellIndex_1);
}
else{
self.cellExchange(cellIndex_1,cellIndex_2);
}
//移除绑定$(document).unbind('mousemove').unbind('mouseup');
}
);
}
).bind('mouseup',function(){
$(this).css('cursor','pointer');
}
);
}
else if(self.hasStart == 1){
if(!confirm('已经在游戏中,确定要回复原图?')){
return false;
}
//样式恢复$(this).text('开始');
self.hasStart = 0;
//复原图片self.cellOrder(self.imgOrigArr);
//取消事件绑定self.imgCells.css('cursor','default').unbind('mouseover').unbind('mouseout').unbind('mousedown');
}
}
);
}
,/** * [randomArr 生成不重复的随机数组的函数] * @return [无] */
randomArr:function(){
//清空数组this.imgRandArr = [];
var order;
//记录随机数,记录图片放置在什么位置for(var i=0,len=this.imgOrigArr.length;
i<len;
i++){
order = Math.floor(Math.random()*len);
if(this.imgRandArr.length > 0){
while(jQuery.inArray(order,this.imgRandArr) > -1){
order = Math.floor(Math.random()*len);
}
}
this.imgRandArr.push(order);
}
return;
}
,/** * [cellOrder 根据数组给图片排序的函数] * @param arr [用于排序的数组,可以是正序或乱序] * @return [无] */
cellOrder:function(arr){
for(var i=0,len=arr.length;
i<len;
i++){
this.imgCells.eq(i).animate({
'left':arr[i]%this.levelArr[this.levelNow][1]*this.cellWidth + 'px','top':Math.floor(arr[i]/this.levelArr[this.levelNow][0])*this.cellHeight + 'px'}
,this.moveTime);
}
}
,/** * [cellChangeIndex 通过坐标,计算被交换的碎片下标] * @param x [鼠标x坐标] * @param y [鼠标y坐标] * @param orig [被拖动的碎片下标,防止不符合碎片交换条件时,原碎片返回] * @return [被交换节点在节点列表中的下标] */
cellChangeIndex:function(x,y,orig){
//鼠标拖动碎片移至大图片外if(x<0 || x>this.imgWidth || y<0 || y>this.imgHeight){
return orig;
}
//鼠标拖动碎片在大图范围内移动var row = Math.floor(y/this.cellHeight),col = Math.floor(x/this.cellWidth),location=row*this.levelArr[this.levelNow][1]+col;
var i=0,len=this.imgRandArr.length;
while((i<len) && (this.imgRandArr[i] != location)){
i++;
}
return i;
}
,/** * [cellExchange 两块图片碎片进行交换] * @param from [被拖动的碎片] * @param to [被交换的碎片] * @return [交换结果,成功为true,失败为false] */
cellExchange:function(from,to){
var self = this;
//被拖动图片、被交换图片所在行、列var rowFrom = Math.floor(this.imgRandArr[from]/this.levelArr[this.levelNow][1]);
var colFrom = this.imgRandArr[from]%this.levelArr[this.levelNow][1];
var rowTo = Math.floor(this.imgRandArr[to]/this.levelArr[this.levelNow][1]);
var colTo = this.imgRandArr[to]%this.levelArr[this.levelNow][1];
var temp = this.imgRandArr[from];
//被拖动图片下标,临时存储//被拖动图片变换位置this.imgCells.eq(from).animate({
'top':rowTo*this.cellHeight + 'px','left':colTo*this.cellWidth + 'px'}
,this.moveTime,function(){
$(this).css('z-index','10');
}
);
//表交换图片变换位置this.imgCells.eq(to).css('z-index','30').animate({
'top':rowFrom*this.cellHeight + 'px','left':colFrom*this.cellWidth + 'px'}
,this.moveTime,function(){
$(this).css('z-index','10');
//两块图片交换存储数据self.imgRandArr[from] = self.imgRandArr[to];
self.imgRandArr[to] = temp;
//判断是否完成全部移动,可以结束游戏if(self.checkPass(self.imgOrigArr,self.imgRandArr)){
self.success();
}
}
);
}
,/** * [cellReturn 被拖动图片返回原位置的函数] * @param index [被拖动图片的下标] * @return [无] */
cellReturn:function(index){
var row = Math.floor(this.imgRandArr[index]/this.levelArr[this.levelNow][1]);
var col = this.imgRandArr[index]%this.levelArr[this.levelNow][1];
this.imgCells.eq(index).animate({
'top':row*this.cellHeight + 'px','left':col*this.cellWidth + 'px'}
,this.moveTime,function(){
$(this).css('z-index','10');
}
);
}
,/** * [checkPass 判断游戏是否成功的函数] * @param rightArr [正确排序的数组] * @param puzzleArr [拼图移动的数组] * @return [是否完成游戏的标记,是返回true,否返回false] */
checkPass:function(rightArr,puzzleArr){
if(rightArr.toString() == puzzleArr.toString()){
return true;
}
return false;
}
,/** * [success 成功完成游戏后的处理函数] * @return [description] */
success:function(){
//取消样式和事件绑定for(var i=0,len=this.imgOrigArr.length;
i<len;
i++){
if(this.imgCells.eq(i).has('mouseOn')){
this.imgCells.eq(i).removeClass('mouseOn');
}
}
this.imgCells.unbind('mousedown').unbind('mouseover').unbind('mouseout');
this.btnStart.text('开始');
this.hasStart = 0;
alert('恭喜您,成功完成本次游戏!');
}
}
/* 加入图片,运行代码 */
$(function(){
var pg = new puzzleGame({
'img':'images/man.jpg'}
)}
);
CSS代码(puzzleGame.css):
@charset "utf-8";*{padding:0;margin:0;}
li{list-style:none;}
body{background-color:#F7F7F7;}
#wrap{width:530px;height:320px;margin:50px auto;}
/* 左侧选项栏 */
#wrap #left{float:left;width:200px;height:300px;padding-top:20px;font-size:18px;}
#wrap #left ul{width:200px;height:300px;}
/* 开始游戏与难度选择的统一样式 */
#wrap #left ul li{width:190px;height:50px;line-height:50px;padding-left:10px;position:relative;}
#wrap #left ul li span{display:block;width:80px;height:40px;line-height:40px;text-align:center;cursor:pointer;margin:5px 20px 0 0;background:#FFF8DC;border-right:solid 1px #aaa;border-bottom:solid 1px #aaa;position:absolute;top:0;left:100px;}
#wrap #left ul li span.mouseOn{border-right:none;border-bottom:none;border-top:solid 1px #aaa;border-left:solid 1px #aaa;}
/* 游戏规则样式 */
#wrap #left ul li#gameRule p{height:30px;font-size:15px;}
/* 右侧图片 */
#wrap #right{float:left;width:310px;height:300px;padding:10px 0 0 10px;}
#wrap #right #imgArea{width:300px;height:300px;position:relative;}
#wrap #right #imgArea div.imgCell{float:left;width:73px;height:73px;border:1px solid #fff;border-radius:4px;position:absolute;z-index:10;box-shadow:0px 0px 8px #fff;transition-property:background-position;transition-duration:300ms;transition-timing-function:ease-in-out;}
#wrap #right #imgArea div.hover{filter:alpha(opacity=80);opacity:.8;box-shadow:0px 0px 8px #000;z-index:20;*border:1px solid #09F;}