HTML5游戏开发中的⽤户交互(⿏标,键盘,触摸屏)操作
当涉⾜ HTML5 游戏世界时,⼈们很容易低估管理键盘、⿏标和基于触摸的输⼊的复杂性。本⽂将探讨⽤来处理基于 HTML Canvas 的游戏中⽤户交互的⼀些基本技术。学习如何处理键盘和⿏标事件,如何阻⽌ 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 坐标。
1. 计算页⾯上的 Canvas DOM 元素的 (x,y) 位置。
2. 确定⿏标相对于整个⽂档的全局位置。
3. 要将原点 (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
};
<('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
});
⾮常规的浏览器⾏为
在计算机游戏中,您通常不希望任何默认浏览器⾏为⼲扰您的操作。例如,您不希望拖动⿏标来执⾏⽂本选择,通过单击⿏标右键来打开上下⽂菜单,或者滚动⿏标滚轮来上下翻页。
图 3 给出了⼀个在⽤户单击并拖动浏览器中的⼀个图像时可能出现的情况的⽰例。尽管从总体上讲,默认浏览器⾏为对拖放应⽤程序很有⽤,但这不是您的游戏中想要的⾏为。
图 3. 拖动图像时的默认浏览器⾏为
在所有事件处理函数中,添加⼀个
preventDefault()
⾏,并从该函数返回 false。清单 3 中的代码将完成此任务,防⽌发⽣默认操作和事件发⽣。
清单 3. 阻⽌默认⾏为
<('click', function(e) {
e.preventDefault();
var mouse = {
英语发音器x: e.pageX - canvasPosition.x,
y: e.pageY - canvasPosition.y
}
//do something with mouse position here
return false;
});
即使对于清单 3 中的代码,当⽤户在 DOM 元素上发起⼀个拖动事件时,您仍然可能遇到多种不合意的副作⽤,⽐如 I 型光标外观、⽂本选择等。拖动事件问题在图像上通常更常见,⼀种不错的想法是将它也应⽤于 Canvas 元素,以阻⽌拖动和选择。清单 4 给出了⼀个通过添加少量 CSS 来阻⽌选择的 CSS 规则。
清单 4. 阻⽌选择的建议样式
image, canvas {
user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-webkit-touch-callout: none;
-webkit-user-drag: none;
}
覆盖桌⾯⾏为
⼀般来讲,⼀个不错的想法是覆盖拖动和选择事件,确保浏览器的默认拖动和选择⾏为不会出现。
清单 5 中的代码特意未使⽤ jQuery 来附加事件。jQuery 没有正确处理
ondragstart
和
onselectstart
事件(如果使⽤ jQuery 来附加事件,事件处理函数可能从不触发)。
清单 5. 取消拖动和选择事件
var canvasElement = ElementById('my_canvas');
// do nothing in the event handler except canceling the event
if (e && e.preventDefault) { e.preventDefault(); }
if (e && e.stopPropagation) { e.stopPropagation(); }
return false;
}
// do nothing in the event handler except canceling the event
if (e && e.preventDefault) { e.preventDefault(); }
if (e && e.stopPropagation) { e.stopPropagation(); }
return false;
}
覆盖移动⾏为
在移动设备上,阻⽌⽤户缩放和平移浏览器窗⼝通常很重要(缩放和平移常常是移动浏览器处理触摸⼿势的默认⾏为)。
您可以将
user-scalable=no
添加到
viewport
元标记来阻⽌缩放⾏为。例如:
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1" />
要禁⽤使⽤⼿势对⽂档或窗⼝的所有移动,可以将清单 6 中的事件附加到 document.body ⽂件中。这会从根本上取消⽤户在点击 Canvas 或游戏区域外任何位置时的所有默认浏览器⾏为。
清单 6. 取消移动设备窗⼝移动
uchstart = function(e) {
if (e && e.preventDefault) { e.preventDefault(); }
if (e && e.stopPropagation) { e.stopPropagation(); }
return false;
}
uchmove = function(e) {
if (e && e.preventDefault) { e.preventDefault(); }
if (e && e.stopPropagation) { e.stopPropagation(); }
return false;
}
传播到游戏对象
长城m3报价对于您希望捕获的每种事件类型,只需向 Canvas 附加⼀个事件。例如,如果您需要捕获单击和⿏标移动事件,只需向 Canvas 附加⼀个单击事件和⼀个⿏标移动事件。这些事件只需附加⼀次,所以通常会在初始化应⽤程序期间附加这些事件。
如果您需要将事件捕获的所有有⽤信息都传播给在 Canvas 上呈现的对象,则必须为系统构建您⾃⼰的逻辑。在本例中,这样⼀个系统会负责将单击或⿏标移动事件传播到关注其中某个事件的处理的所有游戏对象。
当每个游戏对象获知其中⼀个事件后,该游戏对象⾸先需要确定该单击或⿏标移动事件是否与它们有关。如果有关,那么该游戏对象需要确定⿏标坐标是否在它⾃⼰的边界内。
传播战略
您的具体战略将会取决于游戏类型。例如,2D 磁贴集可能具有与 3D 空间不同的战略。
以下步骤给出了⼀个可⽤于简单 2D 应⽤程序的简单实现。
1. 检测⽤户的⿏标是否单击了 Canvas 区域内的位置。
2. 通知所有游戏对象,在⼀组给定的坐标上发⽣了⼀个单击事件。
3. 对于每个游戏对象,在⿏标坐标和游戏对象的边框之间执⾏⼀次命中测试,确定⿏标坐标是否接触到该对象。
简单传播⽰例
单击事件处理函数可能类似于清单 7。该⽰例假设您已设置了某种类型的结构来跟踪⼀个空间中的所有游戏对象。所有游戏对象的位置和尺⼨存储在⼀个名为
gameObjectArray
的变量中。
清单 7. 单击事件处理函数向游戏对象传播
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论