响应用户输入

DinS          Written on 2017/12/21

游戏必须能够与玩家互动,让我们来看看Urho3D是如何处理用户输入的。
现在的游戏接受四种输入:键盘、鼠标、游戏手柄、触摸,根据平台不同支持的输入有不同。因为Urho3D是跨平台的所以对四种输入都提供了支持。
本专题从简出发,只探讨键盘和鼠标。另外两种大同小异,更多内容可去官网查看。

一、键盘输入

键盘输入是相对好处理的,因为变化不是很多。
一共有两个事件处理键盘:E_KEYUP: a key was released.  E_KEYDOWN: a key was pressed.
比如我们在Start()里注册键盘事件:

大图点这里

写法跟其他事件一样,然后实现回调函数:

跟其他事件也一样,可以按F12查看其他的键是如何表示的。

注意实际上这里有两种key。KEY是通常所说的键盘上的key,而SCANCODE是由SDL定义的key,进一步可以看出:

KEY本质上是用SDL定义的,不过我们使用的时候直接用KEY就足够了。

上面回调函数实现的功能是按ESC键退出,试一试。
这个过程没法截图,总之是可以实现的。

处理不同的按键就是在事件里不断加if判断即可。

二、鼠标输入

鼠标因为灵活性大,处理起来难一点。
有多种维度来处理鼠标,可以直接使用Input子系统,也可以使用UI子系统;可以在子系统的事件中处理,也可以在对象中处理。因此说更加灵活。
依照一贯的原则,先从最简单的入手。

1.input子系统

尽管处理键盘时没有看到input子系统的身影,不过事件E_KEYDOWN就是input子系统提供的事件,同理鼠标也有对应事件:
E_MOUSEBUTTONUP: a mouse button was released.
E_MOUSEBUTTONDOWN: a mouse button was pressed.
E_MOUSEMOVE: the mouse moved.
E_MOUSEWHEEL: the mouse wheel moved.

用法跟键盘事件类似。不过这里有一个前提问题:我们都看不见鼠标,这是为什么呢?
鼠标有是否可见和模式两种属性设置。
默认是不可见,原因是因为Urho3D中使用自定义鼠标样式需要通过UI子系统,设置为可见走的是操作系统样式。
鼠标模式有4种,最常用的是MM_ABSOLUTE,这也是默认模式。在该模式下,如果鼠标不可见就会限制在应用程序的窗体内。如果可见就可以自由移动。
在Start()中加入如下代码:

大图点这里

再运行,发现终于可以看到鼠标了。然后仿照键盘事件加入如下代码:

大图点这里

大图点这里

效果是按下鼠标左键,然后日志里输出内容。
运行后点左键,然后退出看日志:

确实捕获到了鼠标左键点击事件。

但是有个很大的问题,这个问题来自于键盘和鼠标截然不同的性质。
对于键盘来说,总体上说每个按键的效果是固定的,而且都属于全局性这个感觉,用input来处理没有问题。
但是对于鼠标来讲,我们一般而言不关注按键本身,而是关注在哪里按下的键,地点不同对于效果有截然不同的影响,使用input系统做这个很困难,我们需要的是对象自己的鼠标事件。

2.对象鼠标事件

实际上在上一节讲解事件时我们已经注册了一个对象鼠标事件,功能就是点击图片后在日志中输出点击的坐标,然后退出。
不过如果你去试一下,会发现点击后没有任何反应,为什么?
这是因为sprite默认设置的enabled状态是false,此时不会响应鼠标事件。为什么默认是false?因为常理上讲按钮通常用来响应用户点击,图片只是显示内容用的。于是我们要显式设置:

大图点这里

于是只要我们点击该图片,就会执行HandleClosePressed事件。
运行exe:

点击右下角图标,退出,检查日志:

确实有内容。不过这里又引出额外的一个注意事项:发现上面还有一条输出,这是我们试验input子系统时做的。
这说明一个道理:input和对象事件并行不悖,会同时响应鼠标事件。这个在做逻辑处理时要记住。

上面顺带提到了按钮。这里就先不详细说明了,等放到UI专题做进一步探讨。

3.关于场景中的鼠标响应

上面讲解的对象鼠标事件仅仅限于UI元素,对场景中的对象注册鼠标事件没有作用。这样设计有一定的原因,交互一般都通过UI层进行,所以鼠标点击都在UI层截获。
场景是给玩家展示游戏内容,并非直接与用户交互,如果想直接操作场景对象怎么办呢?只能通过某种方式绕行了,感兴趣的可以看《2D场景-实现鼠标选中场景物体》。不过这个属于高级内容。


至此urho3d的基本概念和使用方法已经介绍完毕,利用这些可以制作简单的游戏了。

但是仅仅有这些还不够,下面进入中级内容,中级内容对于制作好游戏是必不可少的,先来看看《文字与国际化》。