学习如何处理键盘和鼠标事件,如何阻止 Web 浏览器的默认事件行为,以及如何向游戏对象的某种逻辑表示传播事件。此外,还将学习如何处理 iPhone 和 iPad 等移动设备上与设备无关的(device-agnostic)输入。
令拥有 Flash 或 Silverlight 背景的开发人员感到惊讶的是,为 HTML5 Canvas 编写的应用程序在处理用户输入方面并没有什么特立独行之处。实质上,从启用了 JavaScript 的 Web 浏览器诞生之初开始,HTML 用户输入就涉及到使用内置于浏览器中的事件处理系统;HTML5 在检测和处理用户输入方面没有任何特殊之处。例如,浏览器提供了低级反馈来表明用户单击的坐标 (x,y),就这么简单。
处理用户交互与其他任何低级游戏架构没什么不同。没有内置的抽象来通知您用户何时与已在 Canvas 上呈现的一个具体对象进行了交互。这对您希望处理这些事件的方式提供了强大的低级控制力度。只要您可以避免各种浏览器缺陷,最终就能根据一个独特应用程序来调优事件处理,从而实现最高效率 —而不是受到特定实现的禁锢。
在本文中,将会学习处理基于 HTML Canvas 的游戏中的用户交互的一些技术。文中的示例演示了如何处理键盘、鼠标和基于触摸的事件。向游戏对象传播事件的战略和移动兼容性也会有所涉及。
事件类型
用户交互完全由浏览器的传统事件监听器模型处理。HTML5 的出现并不新鲜;它采用了与自 Netscape Navigator 诞生初期就已经使用的事件模型。
实质上,可以将交互式应用程序或游戏视为处理用户输入的浏览器事件模型与处理图形输出的 Canvas 的结合。除非您亲自将它们结合在一起,二者之间没有逻辑关系。
您将利用事件监听器可附加到 <canvas>元素自身的事实。因为 <canvas>元素是一个块级元素,从浏览器的角度讲,这与将事件监听器附加到 <div>或其他任何块级元素上没有任何区别。
键盘事件
监听和处理的最简单的事件类型是键盘事件。它们不依赖于 Canvas 元素或用户的鼠标位置。键盘事件只需您在文档级别上监听按键、释放和按住事件。
监听键盘事件
事件监听器模型可能因为浏览器实现不同而各不相同,所以实现模型的最快捷的方式是使用一个库来规范化事件的处理。以下示例使用了 jQuery 绑定事件。这通常是最简单的开始方式,但考虑到 jQuery 在兼容遗留浏览器方面涉及的工作量水平,性能可能会受到影响。另一个流行的库(专为加速跨浏览器键盘事件处理而编写)是 Kibo。
清单 1 演示了对键事件的监听,以及如何基于按下的键而采取适当的措施。
清单 1. 处理键盘事件
$(document.body).on('keydown',
function(e) { switch (e.which) { // key code for left arrow case 37: console.log('left arrow key pressed!'); break; // key code for right arrow case 39: console.log('right arrow key pressed!'); break; } });
如果应用程序在一个 Web 浏览器的环境中运行,那么一定要牢记一些有意义的键盘组合键。尽管定义某些常见组合键的行为来替换它们的默认浏览器行为(比如 Ctrl+R)在技术上是可行的,但这种做法受到了强烈反对。
鼠标事件
鼠标事件比键盘事件更复杂。您必须知道 Canvas 元素在浏览器窗口中的位置,以及用户光标的位置。
监听鼠标事件
使用 e.pageX和 e.pageY特性,很容易获得鼠标相对于整个浏览器窗口的位置。在本例中,原点 (0,0) 将位于整个浏览器窗口的左上角。
当用户光标未在 Canvas 区域中时,您通常不会太关心用户输入。因此,最好考虑将原点 (0,0) 放在 Canvas 元素的左上角。在理想情况下,您希望在与 Canvas 区域相关的局部坐标系统内工作,而不希望在与整个浏览器窗口相关的全局坐标系统中工作。
鼠标事件战略
执行以下步骤,将全局窗口坐标转换为局部 Canvas 坐标。
计算页面上的 Canvas DOM 元素的 (x,y) 位置。 确定鼠标相对于整个文档的全局位置。 要将原点 (0,0) 放在 Canvas 元素的左上角,并有效地将全局坐标转换为相对坐标,需要了解第 2 步中计算的全局鼠标位置与第 1 步中计算的 Canvas 位置之间的区别。
图 1 给出了您需要捕获的有关全局坐标系统的信息示例。
图 1. 鼠标位置、全局坐标
图 2 显示了将鼠标位置转换为局部坐标后的结果。
图 2. 转换为局部坐标后的鼠标位置
清单 2 给出了确定局部鼠标坐标的方法。它假设您已经在标记中定义了一个 Canvas 元素,如下所示:<canvas id="my_canvas"></canvas>。
清单 2. 处理鼠标事件
var canvas = $('#my_canvas'); // calculate position of the canvas DOM element on the page var canvasPosition = { x: canvas.offset().left, y: canvas.offset().top }; canvas.on('click', function(e) { // use pageX and pageY to get the mouse position // relative to the browser window var mouse = { x: e.pageX - canvasPosition.x, y: e.pageY - canvasPosition.y } // now you have local coordinates, // which consider a (0,0) origin at the // top-left of canvas element });