先看效果:
图片1:用户先上传一张图片,服务器把图片分割好后返回到主页面.
图片2:点击"新游戏"按钮,图片顺序将被打乱,可以点击想移动的图片来移动图片.
图片3:点"看原图"按钮,可以看到游戏拼好后的效果图,双击"效果图",图片隐藏.
我的上一篇文章提到了用javascript实现拼图游戏的方法,但是实现得不是很好. 首先自己手动把一张大的图片等分成16等份,然后去掉右下角的那一块,把剩余 的15块放在4行4列的表格里,打乱他们的顺序,就可以模拟拼图游戏了。但是手 动分割图片很不方便,如果能够自动分割图片就好了。javascript能力有限,暂 时还不能做那么高级的事情。不过php或者jsp能帮我们这个忙,所以对这个拼图 程序进行了一些改进和扩充,给它带了个php实现的后台,负责切割图片。这样 用户只要自己上传一张图片过去,服务器就能够自动把它切割好,返回到前台, 前台的核心功能仍然用javascript实现。另外,改进了移动图片功能模块的实现。 以前用的是IE系统拖动来移动图片,所以只能在windows下的IE浏览器中使用, 现在发现用系统拖动有个很不好的地方,就是用户使用起来太麻烦,并且也看不 到拖动的轨迹,还不如直接用点击事件来触发拖动。
先来说明一下源文件的组织结构(源文件位置:game文件夹):
css文件夹:包含style.css,用来控制界面外观. image文件夹:包含movepic,uploadpic,icon三个子文件夹 movepic文件夹:存放分割好的图片 uploadpic文件夹:存放上传的图片 icon文件夹:包含close.jpg(关闭按钮) js文件夹:包含control.js,所有的控制脚本都在该文件里 do_cut_pic.php:负责接受上传图片和切割图片的功能模块 (切割功能由被include的resizeresizeJPG.php实现) move_interface.php:游戏主界面模块 resizeJPG.php:具体实现切割图片的功能模块(被do_cut_pic.php include) uploadpic.php:上传图片界面 playGame.php:主程序,include:uploadpic.php ,do_cut_pic.php,move_interface.php 三个文件
对程序功能的解释在源程序里可以看到,在这里我就不做过多的叙述.
我们现在从用户访问的入口playGame.php开始,来看一下源程序:
playGame.php(位置:game/playGame.php):
php
include
'
uploadpic.php
'
;
//
导入上传图片的模块
?>
php
include
'
do_cut_pic.php
'
;
//
导入处理图片模块
?>
php
include
'
move_interface.php
'
;
//
倒入输出模块
?>
uploadpic.php(位置:game/uploadpic.php):
do_cut_pic.php(位置:game/do_cut_pic.php):
php
//
处理上传文件模块
$location
=
"
./image/uploadpic/
"
;
$imgName
=
""
;
$max_size
=
1000000
;
$event
=
"
图片上传成功!
"
;
$resize_width
=
400
;
$resize_height
=
400
;
$cut_pic_width
=
100
;
$cut_pic_height
=
100
;
if
(
!
empty
(
$_FILES
[
'
mypic
'
][
'
name
'
])
&&
!
$_FILES
[
'
mypic
'
][
'
name
'
]
==
""
){
if
(
$_FILES
[
'
mypic
'
][
'
size
'
]
<
$max_size
){
move_uploaded_file
(
$_FILES
[
'
mypic
'
][
'
tmp_name
'
]
,
$location
.
$_FILES
[
'
mypic
'
][
'
name
'
]) or
$event
=
"
上传图片失败
"
;
$imgName
=
$location
.
$_FILES
[
'
mypic
'
][
'
name
'
];
include
'
resizeJPG.php
'
;
//
导入切割图片模块、
}
else
{
$event
=
"
图片太大,上传失败!
"
; } }
?>
resizeJPG.php(位置:game/resizeJPG.php):
php
$imgfile
=
$imgName
;
$percent
=
0.25
;
list
(
$width
,
$height
)
=
getimagesize
(
$imgfile
);
$change_precent
=
1
;
$pic_max_size
=
500
;
if
(
$width
>
$pic_max_size
){
$change_precent
=
$pic_max_size
/
$width
; }
elseif
(
$height
>
$pic_max_size
){
$change_precent
=
$pic_max_size
/
$height
; }
$resize_width
=
$width
*
$change_precent
;
$resize_height
=
$height
*
$change_precent
;
$source
=
imagecreatefromjpeg(
$imgfile
);
$resize_pic
=
imagecreatetruecolor(
$resize_width
,
$resize_height
); imagecopyresized(
$resize_pic
,
$source
,
0
,
0
,
0
,
0
,
$resize_width
,
$resize_height
,
$width
,
$height
);
$cut_pic_width
=
$resize_width
*
$percent
;
$cut_pic_height
=
$resize_height
*
$percent
;
$cut_pic
=
imagecreatetruecolor(
$cut_pic_width
,
$cut_pic_height
);
$k
=
1
;
for
(
$i
=
0
;
$i
<
4
;
$i
++
){
for
(
$j
=
0
;
$j
<
4
;
$j
++
){ imagecopyresized(
$cut_pic
,
$resize_pic
,
0
,
0
,
$j
*
$cut_pic_width
,
$i
*
$cut_pic_height
,
$cut_pic_width
,
$cut_pic_height
,
$cut_pic_width
,
$cut_pic_height
); imagejpeg(
$cut_pic
,
'
image/movepic/
'
.
$k
.
'
.jpg
'
);
//
echo "";
$k
++
; }
//
echo "
";
} imagedestroy(
$source
); imagedestroy(
$resize_pic
); imagedestroy(
$cut_pic
);
?>
move_interface.php(位置:game/move_interface.php):
php
$here_html
=<<<
here_html_mark
<
link rel
=
"
stylesheet
"
type
=
"
text/css
"
href
=
"
css/style.css
"
/>
<
form action
=
""
name
=
"
f1
"
id
=
"
f1
"
method
=
"
post
"
>
<
table border
=
"
1
"
cellspacing
=
"
0
"
cellpadding
=
"
0
"
style
=
"
border-width:1px;border-style:solid;border-color:#cccccc
"
align
=
"
center
"
>
<
tr
>
<
td
><
div id
=
"
div1
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/1.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div2
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/2.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div3
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/3.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div4
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/4.jpg
"
>
div
>
td
>
tr
>
<
tr
>
<
td
><
div id
=
"
div5
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/5.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div6
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/6.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div7
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/7.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div8
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/8.jpg
"
>
div
>
td
>
tr
>
<
tr
>
<
td
><
div id
=
"
div9
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/9.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div10
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/10.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div11
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/11.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div12
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/12.jpg
"
>
div
>
td
>
tr
>
<
tr
>
<
td
><
div id
=
"
div13
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/13.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div14
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/14.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div15
"
onclick
=
"
handleClick(this)
"
><
img src
=
"
image/movepic/15.jpg
"
>
div
>
td
>
<
td
><
div id
=
"
div16
"
onclick
=
"
handleClick(this)
"
>
div
>
td
>
tr
>
table
>
div
>
form
>
<
div id
=
"
controlDiv
"
>
<
br
>
<
table align
=
"
center
"
>
<
tr
><
td
><
input type
=
"
button
"
id
=
"
newGame
"
value
=
"
新游戏
"
onclick
=
"
createNewGame()
"
/>
td
>
tr
>
<
tr
><
td
><
input type
=
"
button
"
id
=
"
finalImg
"
value
=
"
看原图
"
onclick
=
"
showFinalImg()
"
/>
td
>
tr
>
table
>
div
>
<
div id
=
"
showFinalImg
"
ondblclick
=
"
closeShowFinalImg()
"
>
<
div id
=
"
closeImg
"
style
=
"
position:absolute;right:0px;top:0px
"
onclick
=
"
closeShowFinalImg()
"
>
<
img src
=
"
imageiconclose.jpg
"
>
div
>
<
br
>
<
br
>
<
center
>
<
img src
=
"
$imgName
"
width
=
"
$resize_width
"
height
=
"
$resize_height
"
>
center
>
div
>
here_html_mark;
echo
$here_html
;
?>
style.css(位置:game/css/style.css):
#controlDiv
{
right
:
10px
;
top
:
200px
;
width
:
100px
;
height
:
100px
;
background-color
:
#cccccc
;
position
:
absolute
;
}
#showFinalImg
{
position
:
absolute
;
background-color
:
#cccccc
;
left
:
0px
;
right
:
0px
;
top
:
0px
;
bottom
:
0px
;
width
:
800px
;
height
:
600px
;
border-style
:
solid
;
border-width
:
1px
;
border-color
:
#cccccc
;
z-index
:
99
;
FILTER
:
alpha(opacity=85)
;
-moz-opacity
:
0.9
;
display
:
none
;
}
control.js(位置:game/js/control.js):
/*
* *版本:v1.0 *作者:nedvedheqing *完成时间:2007.12.4 *Email:[email protected] *Blog:http://blog.csdn.net/nedvedheqing
*/
//
全局变量oDropTarget,用于引用放置目标,oRelatedTarget用于引用被移动的目标
var
oDropTarget
=
null
;
var
oRelatedTarget
=
null
;
/*
* *新建游戏 *表格中的15张图片就用1-15之间的数字进行命名
*/
function
createNewGame(){
var
array
=
createRandomArray();
//
array中存放了1-15之间的15个数字,并且随机打乱他们的顺序
for
(
var
i
=
1
;i
<
16
;i
++
){
var
oDiv
=
document.getElementById(
"
div
"
+
i);
var
imgUrl
=
"
image/movepic/
"
+
array[i
-
1
]
+
"
.jpg
"
; oDiv.innerHTML
=
'
'
+
imgUrl
+
'
">
'
; }
var
oDiv16
=
document.getElementById(
"
div16
"
); oDiv16.innerHTML
=
""
; setMoveEnable(); }
//
产生一个随机存放1-15之间数字的数组
function
createRandomArray(){
var
array
=
new
Array();
for
(
var
i
=
1
;i
<
16
;i
++
){ array.push(i); } array.sort(mysort);
//
对数组进行随机排序,mysort是随机排序的策略
return
array; }
//
随机排序的策略
function
mysort(a,b){
var
tmp
=
Math.round(Math.random());
//
生成一个随机数并取整,tmp为0/1
return
tmp
?
a
-
b:b
-
a;
//
根据0或1进行升/降排序
}
//
设置哪些层里的图片是可以移动的
function
setMoveEnable(){
for
(
var
k
=
1
;k
<=
16
;k
++
){
//
首先设置所有层的moveEnable属性为false(即所有的层都不可以移动);
var
oDiv
=
document.getElementById(
"
div
"
+
k); oDiv.moveEnable
=
false
; }
for
(
var
i
=
1
;i
<=
16
;i
++
){
var
oDiv
=
document.getElementById(
"
div
"
+
i);
if
(oDiv.innerHTML
==
""
){
//
找出哪个层里没有放置图片
oDropTarget
=
oDiv;
//
放置目标即为没有图片的层
/*
* *设置放置目标正左方,正右方,正上方,正下方相邻层里的图片可以移动 *前提是该层存在,后面有相应的判断
*/
oDivEnable1
=
document.getElementById(
"
div
"
+
eval(i
-
1
)); oDivEnable2
=
document.getElementById(
"
div
"
+
eval(i
+
1
)); oDivEnable3
=
document.getElementById(
"
div
"
+
eval(i
-
4
)); oDivEnable4
=
document.getElementById(
"
div
"
+
eval(i
+
4
));
for
(
var
j
=
1
;j
<=
4
;j
++
){
var
oDivEnable
=
eval(
"
oDivEnable
"
+
j);
if
(oDivEnable
!=
null
){ oDivEnable.moveEnable
=
true
; } }
switch
(oDiv.id){
//
第4层vs第5层,第8层vs第9层,第12层vs第13层不能互为放置目标和可移动层
case
"
div4
"
:document.getElementById(
"
div5
"
).moveEnable
=
false
;
break
;
case
"
div5
"
:document.getElementById(
"
div4
"
).moveEnable
=
false
;
break
;
case
"
div8
"
:document.getElementById(
"
div9
"
).moveEnable
=
false
;
break
;
case
"
div9
"
:document.getElementById(
"
div8
"
).moveEnable
=
false
;
break
;
case
"
div12
"
:document.getElementById(
"
div13
"
).moveEnable
=
false
;
break
;
case
"
div13
"
:document.getElementById(
"
div12
"
).moveEnable
=
false
;
break
; } } } }
//
处理click事件
function
handleClick(oDiv){
if
(oDiv.moveEnable
==
true
){
//
如果被点击层的moveEnable属性为true,那么就和放置目标交换图片
oRelatedTarget
=
oDiv;
var
str1
=
oDropTarget.innerHTML;
var
str2
=
oRelatedTarget.innerHTML; oDropTarget.innerHTML
=
str2; oRelatedTarget.innerHTML
=
str1; setMoveEnable();
//
重新设置各层的moveEnable属性
} }
//
弹出显示最终效果的层,为的是让用户预览图象拼成功后的效果
function
showFinalImg(){
var
oDiv
=
document.getElementById(
"
showFinalImg
"
); oDiv.style.display
=
"
block
"
; }
//
关闭显示最终效果的层
function
closeShowFinalImg(){
var
oDiv
=
document.getElementById(
"
showFinalImg
"
); oDiv.style.display
=
"
none
"
; }
//
检测上传图片的类型,只允许上传JPG文件
function
checkImgType(){
var
mypic
=
document.getElementById(
"
mypic
"
);
var
oForm
=
document.getElementById(
"
uploadForm
"
);
if
(mypic.value
==
""
||
mypic.value
==
null
){ window.alert(
"
请选择要上传的图片!本系统只接受JPG格式的图片!
"
);
return
; }
var
regStr
=/
(.jpg)$
/
;
var
flag
=
regStr.test(mypic.value);
if
(flag){ oForm.submit(); }
else
window.alert(
"
你上传的文件格式有错误!本服务器只允许上传JPG格式的图象文件!
"
); }
源文件下载:
javascript拼图游戏(带服务端)
拼图游戏(单机测试版)