在“游戏”中,单击滑块选择游戏难易,“随意马虎”为3行3列拼图游戏,中间为一个4行4列拼图游戏,“难”为5行5列拼图游戏。
拼块以随机顺序排列,玩家用鼠标单击空缺块四周的来交流它们位置,直到所有拼块都回到原位置。

拼图游戏运行结果如下图所示。

程序设计的思路

HTML5可以把图片整合到网页中。
利用canvas元素可以在这个空缺的画布上添补线条,载入图片文件,乃至动画效果。
这里制作拼图游戏用来展示HTML5 canvas的图片处理能力。

php拼图排版制作HTML5制造的人物拼图游戏 PHP

游戏程序首先显示以精确顺序排列的图片缩略图,根据玩家设置的分割数,将图片分割成相应tileCount行列数的拼块,并按顺序编号。
动态天生一个大小tileCounttileCount的数组boardParts,存放用0,1,2到tileCounttileCount-1的数,每个数字代表一个拼块(例如44的游戏拼块编号如图7-2所示)。

游戏开始时,随机打乱这个数组boardParts,如果boardParts[0]是5则在左上角显示编号是5的拼块。
根据玩家用鼠标点击的拼块和空缺块所在位置,来交流该boardParts数组对应元素,末了判断元素排列顺序来判断是否已经完成游戏。

程序设计的步骤

1. 游戏页面

<!doctype html>

<html>

<head>

<title>拼图游戏</title>

<style>

.picture {

border:1px solid black;

}

</style>

</head>

<body>

<div id=\"大众title\"大众>

<h2>拼图游戏</h2>

</div>

<div id=\"大众slider\"大众>

<form>

<label>随意马虎</label>

<input type=\"大众range\"大众id=\"大众scale\"大众 value=\"大众4\"大众 min=\"大众3\公众 max=\"大众5\公众step=\公众1\公众>

<label>难</label>

<img id=\"大众source\"大众width=\公众120px\公众 height=\"大众120px\"大众 src=\公众defa.jpg\"大众 >

</form>

<br>

</div>

<div id=\"大众main\"大众class=\"大众main\公众>

<canvas id=\"大众puzzle\公众width=\"大众480px\"大众 height=\公众480px\"大众></canvas>

</div>

<scriptsrc=\"大众sliding.js\公众></script>

</body>

</html>

在网页中利用canvas标记用来创建画板。

<canvas width=\"大众480px\公众height=\公众480px\"大众></canvas>

canvas的宽和高利用像素为单位。
如果这两个属于没有被指定,它们的默认的宽度为:300px,高度为:150px。

网页中<div id=\"大众slider\"大众> 包括了另一个 HTML5 标记: range input ,这个标记<inputtype=\"大众range\"大众>可以让用户拖放滑块选择一个数值。
这里设置滑块最小值为 3 ,最大值为5。
滑块值为 3 表明拼图游戏是 3 行 3 列的,滑块值为 4 表明拼图游戏是4行4列的,滑块值为 5表明拼图游戏是 5行5列的。

<img id=\"大众source\公众 width=\"大众120px\公众height=\"大众120px\"大众 src=\"大众defa.jpg\公众 >显示原图defa.jpg的缩小图供玩家参照移动拼块。

2. sliding.js文件

在页面上画图须要利用canvas的高下文环境,通过调用getContext()方法获取高下文环境。

var context =document.getElementById('puzzle').getContext('2d');

我们还须要一个和canvas相同大小的图片'defa.jpg'。

var img = new Image();

img.src = 'defa.jpg';

img.addEventListener('load', drawTiles, false);

//load事宜侦听,即图片加载完成事宜

加入这个'load'事宜是确保图片完成加载后,再把图片放入canvas中。
drawTiles()函数绘制打乱的图块。

var boardSize =document.getElementById('puzzle').width;

//获取画板(画布)的宽度

var tileCount =document.getElementById('scale').value;

//获取滑块的值

boardSize 是 canvas 的宽度,通过 rangeinput 设置拼图的数量 tileCount ,数据范围从3到5(几行几列)。

var tileSize = boardSize / tileCount;

//打算出拼块的大小宽度

末了定义3变量,个中2个Object工具变量,emptyLoc保存空缺拼图的位置(emptyLoc.x,emptyLoc.y),clickLoc记录用户单击的位置(clickLoc.x,clickLoc.y)。
而1个bool变量solved是指拼图是否完成,所有的拼图都找到精确的位置后,设置它为true。

var context =document.getElementById('puzzle').getContext('2d');

var img = new Image();

img.src = 'dimetrodon.jpg';

img.addEventListener('load', drawTiles, false);

//load事宜侦听,即图片加载完成事宜

var boardSize = document.getElementById('puzzle').width;

//获取画板(画布)的宽度

var tileCount =document.getElementById('scale').value;

//获取滑块的值

var tileSize = boardSize / tileCount;

var clickLoc = new Object();

clickLoc.x = 0;

clickLoc.y = 0;

var emptyLoc = new Object();

emptyLoc.x = 0;

emptyLoc.y = 0;

var solved = false;

//拼图是否完成,false为未完成

下面实现拼块的随机排列。

我们利用一个一维数组存储每个拼块的编号。
每一个元素代表一个拼块,初始时元素的数组下标与拼块的编号相同,解释位置精确。
以是须要打乱数组的元素顺序,实现拼块的随机排列。
而数组的元素顺序打乱利用带有排序函数的Array.sort()方法实现。

var boardParts = new Object();

initBoard();

//初始化拼块,并随机排列

function initBoard() {

boardParts = new Array(tileCount tileCount);

for (vari = 0; i < tileCount tileCount; i++) {

boardParts[i] = i;

}

shift(); //拼块的随机排列

}

function sortNumber(a,b) {//随机排序函数

returnMath.random() > 0.5 ? -1 : 1;

}

function shift() { //拼块的随机排列

boardParts.sort(sortNumber);

emptyLoc.x = 0;

emptyLoc.y = 0;

solved =false;

}

以上就实现拼块的随机放置。
但是真正显示拼块在屏幕上是 drawTiles()函数。
drawTiles()函数显示各个拼块。
这个函数判断是否是空缺拼图的位置(emptyLoc.x,emptyLoc.y),不是则调用drawImage()绘制相应图块。

drawImage() 最常用的是传入三个参数:image工具,以及图片相对付画布的x,y坐标。
drawImage(image, x, y);

还可以加入两个参数用于设置图片的宽和高:

drawImage(image, x, y, width, height);

最繁芜的drawImage函数有9个参数,按顺序分别为:图片工具,图片x坐标,图片y坐标,图片宽,图片高,目标x坐标,目标y坐标,目标宽和目标高。
后四个参数紧张是为了截取原图部分用来显示。
这里把boardParts记录的拼块显示在(itileSize,jtileSize)处。

//绘制所有拼块

function drawTiles() {

context.clearRect(0, 0, boardSize, boardSize);

for (vari = 0; i < tileCount; i++) {

for(var j = 0; j < tileCount; j++) {

var n = boardParts[i tileCount + j];

//打算出编号为n的拼块在原图的位置坐标(行列号)

var x = parseInt(n / tileCount);

//丢弃小数部分, 保留整数部分

var y = n % tileCount;

console.log(x + \公众:\公众 + Math.floor(n / tileCount) +\"大众:\"大众 + y);

if (i!= emptyLoc.x||j!= emptyLoc.y||solved==true) {

//不是空缺拼图的位置且游戏未结束

//或者if( !(i==emptyLoc.x&&j== emptyLoc.y&&solved==false))可能更随意马虎明白

//将编号为n的拼块显示在(i tileSize, j tileSize)处

context.drawImage(img, x tileSize, y tileSize, tileSize, tileSize,

i tileSize, j tileSize, tileSize, tileSize);

}

}

}

}

以下是事宜定义。

首先为滑块定义触发事宜,当它改变了,我们要重新打算拼块的数量和大小。
滑块被移动时触发onchange事宜,事宜中计算拼块宽度大小,重新初始化画布,显示各个拼块。

document.getElementById('scale').onchange =function() {

tileCount =this.value;

tileSize =boardSize / tileCount;//打算拼块宽度大小

initBoard();//重新初始化拼块,并随机排列

drawTiles();//显示各个拼块

};

还要追踪鼠标经由的拼块以及哪个拼块被单击。
画板中移动鼠标的onmousemove事宜中,打算出鼠标所在网格坐标clickLoc.x,clickLoc.y。

document.getElementById('puzzle').onmousemove =function(e) {

clickLoc.x= Math.floor((e.pageX - this.offsetLeft) / tileSize);

clickLoc.y= Math.floor((e.pageY - this.offsetTop) / tileSize);

};

画布中单击鼠标的onmousemove事宜中,打算出鼠标所在网格坐标clickLoc.x,clickLoc.y与空块位置间隔,如果间距为1则移动被单击的拼块。

document.getElementById('puzzle').onclick =function() {

if(distance(clickLoc.x, clickLoc.y, emptyLoc.x, emptyLoc.y) == 1) {

slideTile(emptyLoc, clickLoc);//交流被单击的拼块与空块位置

drawTiles();//显示各个拼块

}

if (solved){//如果成功

setTimeout(function() {alert(\"大众你成功了!\"大众);}, 500);

}

};

function distance(x1, y1, x2, y2) {

returnMath.abs(x1 - x2) + Math.abs(y1 - y2);

}

把稳有一些浏览器会在重画画布之前弹出对话框,为了防止它的发生,一定要用延迟。

setTimeout(function() {alert(\"大众你成功了!\公众);}, 500);

这句便是延迟0.5秒后,再弹出提示框\"大众你成功了!\公众。

slideTile(emptyLoc, clickLoc)是移动被单击的拼块clickLoc到空块位置emptyLoc。
移动拼图的做法是:交流对应的boardParts元素,然后把单击位置设置成空块位置。

function slideTile(emptyLoc, clickLoc) {

if(!solved) {

vart;

t=boardParts[emptyLoc.x tileCount+emptyLoc.y];

boardParts[emptyLoc.xtileCount+emptyLoc.y]=boardParts[clickLoc.xtileCount+clickLoc.y];

boardParts[clickLoc.x tileCount + clickLoc.y] = t;

emptyLoc.x = clickLoc.x; //emptyLoc重新记录空缺块位置

emptyLoc.y = clickLoc.y;

checkSolved();//检讨是否成功

}

}

一旦拼图移动了,我们还要检讨一下拼图是否全部在精确的位置。
checkSolved()检讨是否成功。
如果有一个拼块禁绝确函数就会返回false,否则返回true。

function checkSolved() {

var flag= true;

for (vari = 0; i < tileCount tileCount; i++) {

if(boardParts[i] != i) //判断元素排列顺序

flag = false;

}

solved =flag;

}

至此我们完成拼图游戏的设计。