在这篇文章中,我将做一个滑动拼图的游戏用来展示HTML5 canvas的图片处理能力。
在网页中使用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);
最复杂的drawImage函数有9个参数,按顺序分别为:图片对象,图片x坐标,图片y坐标,图片宽,图片高,目标x坐标,目标y坐标,目标宽和目标高。后四个参数主要是为了截取原图部分用来显示,比如局部放大、剪切等。以上就是图像处理的方法,让我们做一个练习。
上面的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();
setBoard()的作用是初始化看板,要模拟显示这个画板,我们使用一个二维数组。不过用JavaScript创建这样数组的过程不是很优雅,我们先定义一个平面数组,每个数组再定义一个数组。这个拼图游戏,每一个元素都是一个对象,它带有x和y坐标记录所在的网格位置。因此每个对象有两个坐标,第一个坐标是数组坐标,表示它在画板的位置,另外的坐标是对象的x,y属性,它记录着拼图图片的位置。当这两个坐标相同了就说明位置正确。
为了达到目的,我们在初始化的时候把它们的位置互换。这样拼图就不在正确的位置了。
- function setBoard() {
- boardParts = new Array(tileCount);
- for (var i = 0; i
- boardParts[i] = new Array(tileCount);
- for (var j = 0; 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;
所有的拼图都找到正确的位置后,设置它为true。
现在我们需要一些和解决拼图相关的方法
首先为rang input定义触发事件,当它改变了,我们要重新计算拼图的数量和大小
- 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);
- }
当一个拼图被点击时,我们要知道它的四周是否可以移动。判断的方法是当前位置到空白位置的总距离为1时就可以移动。
简单点说就是x相同要判断y的距离是否为1,y相同要判断x的距离是否为1。
- 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
- {
- for (var j = 0; j
- tileCount; ++j)
- {
- if
- (boardParts[i][j].x != i || boardParts[i][j].y != j)
- {
-
- flag =
- false;
-
- }
- }
-
- }
- solved = flag;
- }
如果有一个拼图不正确函数就会返回false,否则返回true。
最后,重绘被点击的拼图到新的位置。
- function drawTiles() {
- context.clearRect ( 0 , 0 , boardSize , boardSize );
- for (var i = 0; i
- for (var j = 0; 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);
- }
- }
- }
- }
当画拼图时,这个函数可以防止填充画板时匹配空的位置,因为在游戏中用户可以选择不同的难度。
转自天地会

HTML中的H5标签是第五级标题,用于标记较小的标题或子标题。1)H5标签帮助细化内容层次,提升可读性和SEO。2)结合CSS可定制样式,增强视觉效果。3)合理使用H5标签,避免滥用,确保内容结构逻辑性。

HTML5构建网站的方法包括:1.使用语义化标签定义网页结构,如、、等;2.嵌入多媒体内容,使用和标签;3.应用表单验证和本地存储等高级功能。通过这些步骤,你可以创建一个结构清晰、功能丰富的现代网页。

通过合理的H5代码结构可以让页面在众多内容中脱颖而出。1)使用语义化标签如、、等组织内容,使结构清晰。2)通过CSS布局如Flexbox或Grid控制页面在不同设备上的呈现效果。3)实现响应式设计,确保页面在不同屏幕尺寸上自适应。

HTML5(H5)与旧版本HTML的主要区别包括:1)H5引入了语义化标签,2)支持多媒体内容,3)提供离线存储功能。H5通过新标签和API增强了网页的功能和表现力,如和标签,提高了用户体验和SEO效果,但需注意兼容性问题。

H5和HTML5的区别在于:1)HTML5是网页标准,定义结构和内容;2)H5是基于HTML5的移动网页应用,适用于快速开发和营销。

HTML5的核心特性包括语义化标签、多媒体支持、表单增强和离线存储与本地存储。1.语义化标签如、等提高了代码可读性和SEO效果。2.多媒体支持通过和标签简化了嵌入媒体内容的过程。3.表单增强引入了新的输入类型和验证属性,简化了表单开发。4.离线存储和本地存储通过ApplicationCache和localStorage等提高了网页性能和用户体验。

html5isamajorrevisionofthehtmlStandardThatRevolutionsWebDevelopmentBybyIntroDucingNewSemanticeLementSemelementsandAndCapabilities.1)itenhancesCodereAdabilityAndSeowitability andSeowithelientsLike,and.2)

H5的高级技巧包括:1.利用进行复杂图形绘制,2.使用WebWorkers提升性能,3.通过WebStorage增强用户体验,4.实现响应式设计,5.利用WebRTC实现实时通信,6.进行性能优化和最佳实践。这些技巧帮助开发者构建更动态、互动和高效的Web应用。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Dreamweaver Mac版
视觉化网页开发工具