如何在轩辕传奇中快速集成触摸支持

发表于2018-01-27
评论0 1.1k浏览

本文首发于知乎专栏:MACK的游戏开发笔记,欢迎各位关注。


虽然一开始就不看好笔记本的触摸功能,但为了合作推广还是集成触摸功能,并且后续还集成了RealSense3D的体感功能。。。作为一个最高在线过50w的游戏,安全稳定是第一要务。因此采用了dll插件的方式,通过dll的方式支持触摸和体感功能,可随时关闭和打开而不会影响到游戏。另外通过状态机实现了一套操作和手势的框架,也深深的体会到了调手感真是非常痛苦的一件事。

随着Ultrabook 装机量的持续增长,越来越多的玩家使用Ultrabook体验游戏。Ultrabook更轻更薄并且带有触摸屏和各种传感器,例如陀螺仪,加速计,GPS等等,对传统的端游来说也可以引入新的游戏方式和创意。另外SurfacePro为代表,越来越多的Ultrabook更开始支持二合一的使用方式,也就是变形本,这意味着笔记本还可以舍弃鼠标键盘变形为一台平板。但是传统的端游都是采用鼠标键盘操作的,当变到平板模式后基本无法体验游戏。那么如何才能将一款游戏进行优化以便能支持平板模式带给玩家更好的体验呢?这是一个全新的挑战。

2013年我们和Intel一起在轩辕传奇上加入了触摸的支持和优化。使轩辕传奇有幸成为了市场上第一款支持触摸的3DMMORPG。

由于轩辕已经是一款上线项目,为了尽量不对项目造成影响,我们将尝试用最小的改变去获得一个可以接受的结果。以下我开发触屏功能时的一些经验和思考,我的开发环境是Intel的Ultrabook和Win8系统,开发工具是用VS2005。


1.触摸插件集成

那么如何将触摸操作的相关功能集成到游戏中,同时又对项目影响较小呢?首先我采用了插件的方式集成触摸功能,将所有触摸相关的操作底层封装到Dll中实现。在游戏启动时会自动加载触摸插件的Dll,加载后首先调用触摸插件的接口判定当前电脑的硬件和系统是否支持触摸操作并反馈给游戏,如果不支持直接卸载Dll,如果支持那么通过回调和游戏交互实现游戏的触摸功能。这样做的好处是游戏本身的改动非常小,触摸相关的代码绝大部分在Dll中实现;触摸功能仅在支持的环境下有效不会产生任何兼容性等问题;使用插件的方式可以随时打开和关闭。


2.键盘操作

轩辕使用w,a,s,d移动角色,使用数字键去释放技能,使用其他快捷键键去打开WindowsUI,例如背包,技能树,任务,地图等等。而在平板模式下是没有键盘操作的。当然这些操作也可以通过鼠标来完成,但是当我们拿着平板的时候,我们使用两只手去抓住平板的两边,如果有任何在屏幕中间的操作,我们必须松开手用手指来操作。这很明显不是一个好的用户体验。平板模式时和手柄类似,比较容易是用的只有两个拇指,同时操作范围也是平板左下角和右下角拇指覆盖的区域。

仿照目前手机和平板处理方式,将大部分操作用虚拟摇杆和按钮实现。当游戏检测到用户切换到了平板模式的时候,自动显示摇杆和按钮,同时隐藏部分UI。其中屏幕左侧显示虚拟摇杆用来控制角色的移动,右侧有四个用户可自定义的快捷键和一个较大的切换目标按钮。这是因为原始的技能栏在屏幕的底部,这个位置很难用大拇指来按到。这样玩家就可以把需要的任何技能拖到右侧快捷键中,在游戏时可以非常容易的频繁的进行操作。切换目标按钮是非常重要的,因为轩辕大部分技能和操作都是锁敌的,通过使用切换目标按钮我们可以按照一定的规则在周围敌对目标之间切换。

具体效果如下:


3.触摸方式选择

Windows提供了三种方式去支持触摸。WM_POINTER是最常用的API,但它只支持Win8。WM_GESTURE和WM_TOUCH是从Win7带来的并且保持兼容Win8。

因为我们希望使用Win7的触摸电脑在玩轩辕传奇时也能有优秀的触摸体验,我们首先否定了WM_POINTER。

WM_GESTURE是一个最简单的API,使用起来非常方便和简单,可以直接返回各种系统定义的手势,支持鼠标左右键,我们不需要额外的开发。我们一开始也是选择了WM_GESTURE,并实现了通过缩放,双指拖动,旋转等各种手势来调整Camera,通过使用PressAndTap来开启放大镜等。因为是系统手势,手感非常好,实现也很简单。但是当当需要和虚拟手柄结合的时候问题来了,因为默认的WM_GESTURE只能实现系统手势,此外不能支持多点操作。

而我们希望玩家可以在移动的时候切换敌人,释放技能,调整Camera等等,这些必须需要同时支持摇杆操作,按键操作,需要多点触摸。我们还需要实现一些特殊的手势例如五指缩放。为了给玩家带来最好的体验,我们最终采用了WM_TOUCH来实现多点触摸。


4.WM_TOUCH触摸支持

WM_TOUCH是一个更高级的API,在和用户的交互上它可以给我们提供更强大的能力。然而不同于WM_GESTURE直接告诉我们玩家做的是什么手势,WM_TOUCH仅仅反馈原始的触摸点。因此必须从头开始对所有的触摸点自行处理,通过触摸插件实现之前的各种手势判定并加入新的自定义手势。

前面说过不管用哪种方法,Windows都会默认将点击操作处理成鼠标消息,这样我们就必须先屏蔽掉系统的默认操作,例如由用户触摸产生的鼠标左右键消息。我们通过GetMessageExtraInfo这个API获得一个鼠标消息是由鼠标才产生还是由触摸产生,如果是触摸产生那么屏蔽掉。然后当我们取得用户原始的触摸点之后,我们首先判断触摸点是否在虚拟手柄上,如果在虚拟手柄上则直接转化为手柄的响应点击操作。如果不在虚拟手柄上则通过一套状态机对原始点进行处理,获得当前触摸操作是否手势。如果是手势则执行响应的手势操作,例如缩放,旋转,五指缩放等等。如果不是手势再进一步判断用户操作是否是对应Windows的鼠标操作,例如单指点击对应鼠标左键点击,单指长按拖动对应拖曳,如果单指长按不动(0.2秒)是鼠标右键等。对这些操作,我们在得到状态之后直接模拟Windows消息,无缝的兼容了鼠标和触摸。同时玩家也可以一边通过摇杆移动,一边按技能按键或者敌人切换按键进行操作了。

在实现了所有的手势,虚拟手柄的多点操作以及各种鼠标操作之后,我们又花了大量时间对触摸手感进行了调整,保证和Windows的默认手势手感相近,给用户带来完美体验。


5.特殊手势支持

在游戏中有许多的窗口,例如背包,技能树,任务等等。我们可以通过快捷键或者点击打开他们。但大多数的窗口不是经常用到,其中背包最经常被使用。因此我们定义自定义手势去完成打开关闭背包以及Esc关闭等操作。

五指手势也是在触摸插件中通过状态机判断,当发现用户是五指缩放操作时则会调用OnStarExpand和OnStarCollapse这两个回调函数,在这两个函数中通过模拟Windows的按键消息来实现背包和Esc的快捷键处理,即兼容了原有快捷键操作又做到了最小程度的修改。

实例代码如下:

BOOL TouchCallBack::OnStarExpand(float _fX, float _fY)

::SendMessage(m_hWnd, WM_KEYDOWN, 'B', 0);

::SendMessage(m_hWnd, WM_KEYUP, 'B', 0);

return TRUE;

BOOL TouchCallBack::OnStarCollapse(float _fX, float _fY)

::SendMessage(m_hWnd, WM_KEYDOWN, VK_ESCAPE, 0);

::SendMessage(m_hWnd, WM_KEYUP, VK_ESCAPE, 0);

return TRUE;


6.游戏内UI动态模式切换

前面提到我们游戏可以在运行时基于Ultrabook 的物理状态动态切换UI。当用户变现为平板模式时,我们自动打开虚拟摇杆同时隐藏左下角和右下角的部分UI(同时也提供按键供玩家手动切换)。而当用户又切换会笔记本模式时,我们又会自动关闭虚拟摇杆界面,重新显示左下角和右下角的UI,用户体验更棒了。

看上去好神气:)微软已经提供了接口去支持这种操作。已经有公开的APIs和通知给开发者们,同时也有标准的硬件规范给OEM厂商使用。除了模式变化,还可以获得是否Metro界面,平板横屏竖屏等信息,并进行更详细的优化。


代码如下:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

switch (message)

case WM_SETTINGCHANGE:

if (wcscmp(TEXT("ConvertibleSlateMode"), (TCHAR *) lParam) == 0) //Convertible Ultrabook

BOOL bSlateMode = (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0);

if (bSlateMode == True) //Slate mode, display the Touch overlay UI

else //Laptop mode, hide the touch overlay UI

else if (wcscmp(TEXT("SystemDockMode"), (TCHAR *) lParam) == 0) //Dockable Ultrabook

BOOL bDocked = (GetSystemMetrics(SM_SYSTEMDOCKED) != 0);

if (bDocked == True) //dock mode, display the Touch overlay UI

else //undocked mode, hide the touch overlay UI


……………….

不过请注意的是,不是所有的发售的可变形的Ultrabook都支持这种模式检测。它需要OEM厂商支持,需要安装一个设备驱动。对于不支持的硬件我们是直接显示一个切换按钮让玩家手工操作。


7.传感器支持

所有新的Ultrabooks都支持传感器,包括罗盘,加速计,GPS等。那么我们可以使用这些传感器去开发一些新的用户体验提供给玩家吗?答案是肯定的,现在它们不再是手机和平板的特性了。例如在轩辕中,我们利用加速计去检测玩家的Shake操作。当Shake时,在游戏中会释放一个弑神也就是超必杀,非常酷,不过要小心别摔了。

想要支持Shake操作,我们可以通过系统API来获得这个事件,不过有时Shake的API不太敏感或者过于敏感,每个系统都有不同。我们主要是通过获得加速计的xyz数据来判断是否Shake。下面是实例代码:

BOOL ShakeHappened(x,y,z)

x, y, z are the data of accelerometer sensor

if ( (fabs(x) >1.6)|| (fabs(y) >1.6)|| (fabs(z) >1.6))

if ((nowtime - timer1)>1000)//用来清除上次(1秒钟以前)累计的无效count次数

timer1 = timeGetTime();

counter = 1;

else if (((nowtime - timer1)<1000))//在1秒内发生的超过1.6阈值的情况,算成是同一次shake,统计到count上

timer1 = timeGetTime();

counter ++;


if ((counter > 1) && ((nowtime - lastshaketime) > 1500))//设定count累计为2(可调),同时,距离上次shakecount有1.5秒时间才算一次shake发生

lastshaketime = timeGetTime();

shakecounter ++;

counter = 0;

return TRUE;

return FALSE


总结

最终在轩辕传奇中加入了触摸支持和传感器支持,同时对鼠标键盘的支持也没有任何影响,现在玩家可以舒服的躺在沙发上来一局了。整个触摸功能的加入几乎没有影响现有代码,绝大部分的代码都在Dll中,可以很方便的打开关闭或者更新,而对不支持触摸操作的电脑来说更是没有任何影响。同时整个开发过程也比较短,美术策划的工作量非常非常小,性价比很高。

当然必须承认的是,由于游戏一开始没有往触摸的方向设计,UI上的各个按钮都很小,特别是在一些高分辨率的机器上,这使得玩家点击操作会有一定错误率影响到游戏体验,这也是难以避免的,后续可能还会利用摇杆来进行一些选择操作。

此外,Ultrabook的装机量还较小,Win8系统也有很多瑕疵,但这未必不是未来的发展方向。特别是新出的BayTrail处理器,功耗非常低。例如在2000块级别的华硕T100平板上也可以流畅体验轩辕,而该笔记本的厚度仅有10.2mm,550g,完全就是ipad级别的,在平板上运行端游是非常有前景的。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论