HTML5技术之图像处理:一个滑动的拼图游戏
HTML5有许多功能特性可以把多媒体整合到网页中。使用canvas元素可以在这个空白的画板上填充线条,载入图片文件,甚至动画效果。
在这篇文章中,我将做一个滑动拼图的游戏用来展示HTML5 canvas的图片处理能力。
在网页中使用canvas标签用来创建画板
<canvas width="480px" height="480px"></canvas>
canvas的宽和高使用像素为单位。如果这两个属于没有被指定,他们的默认的宽度为:300px,高度为:150px。
在图板画图需要使用canvas的上下文环境,通过脚本调用getContext()方法获取上下文环境。W3C定义它为二维,更确切的说是2d。所以初始化上下文环境如果如下方法:document.getElementById("vanvas").getContext("2d");
下一步要做的是在画板上显示图片,API只提供drawImage()一种方法。但是有三种调用方式。最常用的是传入三个参数:image对象,以及图片相对于画板的x,y坐标。
drawImage(image, x, y);
还可以加入两个参数用于设置图片的宽和高
drawImage(image, x, y, width, height);
<div id="slider"> <form> <label>Easy</label> <input type="range" id="scale" value="4" min="3" max="5" step="1"> <label>Hard</label> </form> <br> </div> <div id="main" class="main"> <canvas id="puzzle" width="480px" height="480px"></canvas> </div>
上面的DIV包括了另一个HTML5标签:range input,这个标签可以让用户拖放滑块选择一个数值。回头我们再说在拼图中如何与range input交互。到目前为止ie和firefox并不支持这个标签。
现在就像我上面说过,想要在canvas上绘图,我们需要context。var context = document.getElementById("puzzle").getContext("2d");
对了我们还需要一个图片,使用例子里自带的,或者找一个和canvas相同大小的图片都行。
var img = new Image(); img.src = 'http://www.brucealderman.info/Images/dimetrodon.jpg'; img.addEventListener('load', drawTiles, false);
加入这个事件是确保图片完成加载后,再把图片放入canvas中。
下面我们通过range input设置拼图的数量,数据范围从3到5(几行几列)。var boardSize = document.getElementById('puzzle').width; var tileCount = document.getElementById('scale').value;
有了上面两个数值就可以计算一个拼图的大小了
var tileSize = boardSize / tileCount;
OK我们开始创建画板
var boardParts = new Object; setBoard();
function setBoard() { boardParts = new Array(tileCount); for (var i = 0; i < tileCount; ++i) { boardParts[i] = new Array(tileCount); for (var j = 0; j < tileCount; ++j) { boardParts[i][j] = new Object; boardParts[i][j].x = (tileCount - 1) - i; boardParts[i][j].y = (tileCount - 1) - j; } } emptyLoc.x = boardParts[tileCount - 1][tileCount - 1].x; emptyLoc.y = boardParts[tileCount - 1][tileCount - 1].y; solved = false; }
我们必须追踪空白拼图的位置还要记录用户点击的位置
var clickLoc = new Object; clickLoc.x = 0; clickLoc.y = 0; var emptyLoc = new Object; emptyLoc.x = 0; emptyLoc.y = 0;
var solved = false;
document.getElementById('scale').onchange = function() { tileCount = this.value; tileSize = boardSize / tileCount; setBoard(); drawTiles(); };
还要追踪鼠标经过的拼图以及哪个拼图被点击
document.getElementById('puzzle').onmousemove = function(e) { clickLoc.x = Math.floor((e.pageX - this.offsetLeft) / tileSize); clickLoc.y = Math.floor((e.pageY - this.offsetTop) / tileSize); }; document.getElementById('puzzle').onclick = function() { if (distance(clickLoc.x, clickLoc.y, emptyLoc.x, emptyLoc.y) == 1) { slideTile(emptyLoc, clickLoc); drawTiles(); } if (solved) { alert("You solved it!"); } };
if (solved) { setTimeout(function() {alert("You solved it!");}, 500); }
function distance(x1, y1, x2, y2) { return Math.abs(x1 - x2) + Math.abs(y1 - y2); }
function slideTile(toLoc, fromLoc) { if (!solved) { boardParts[toLoc.x][toLoc.y].x = boardParts[fromLoc.x][fromLoc.y].x; boardParts[toLoc.x][toLoc.y].y = boardParts[fromLoc.x][fromLoc.y].y; boardParts[fromLoc.x][fromLoc.y].x = tileCount - 1; boardParts[fromLoc.x][fromLoc.y].y = tileCount - 1; toLoc.x = fromLoc.x; toLoc.y = fromLoc.y; checkSolved(); } }
function checkSolved() { var flag = true; for (var i = 0; i < tileCount; ++i) { for (var j = 0; j < tileCount; ++j) { if (boardParts[i][j].x != i || boardParts[i][j].y != j) { flag = false; } } } solved = flag; }
function drawTiles() { context.clearRect ( 0 , 0 , boardSize , boardSize ); for (var i = 0; i < tileCount; ++i) { for (var j = 0; j < tileCount; ++j) { var x = boardParts[i][j].x; var y = boardParts[i][j].y; if(i != emptyLoc.x || j != emptyLoc.y || solved == true) { context.drawImage(img, x * tileSize, y * tileSize, tileSize, tileSize, i * tileSize, j * tileSize, tileSize, tileSize); } } } }
时间有限难免有翻译不正确的地方,请谅解。下面是源代码(使用Chrome打开呦)
下载地址:http://download.csdn.net/detail/dragoo1/8859295
转自:http://bbs.9ria.com/thread-112666-1-1.html