一、 需求背景


  随着《轩辕传奇》不删档公测的进行,团队希望提高通过游戏客户端向玩家投放新版本内容和运营活动宣传的敏捷程度和丰富度。


  我们选择了在游戏客户端中内嵌浏览器打开相关宣传Web网页的方式实现上述目标,但由于该功能实现后会大大提高玩家在游戏中打开Web网页的操作时间,因此项目组向我们客户端团队提出两个要求:


1. 实现从Web页面内超链接或按钮等元素操作游戏内容的功能(寻路、打开商城查找商品、打开新功能界面等)


2. 所打开的Web页面UI需要与游戏UI一致的体验,可以被更高优先级或者后弹出的UI界面遮挡

  


《轩辕传奇》四月上线的活动和运营宣传内嵌Web页面

二、 困难点分析


  首先,对于如何内嵌Web网页的问题,我们在之前内嵌充值页面时已经实现了IE浏览器的嵌入并长期正常运行。同时也为了稳定可靠和满足开发进度要求,我们仍然选择了通过ATL接口集成IE浏览器来显示宣传Web网页的功能,这点不存在困难。


  接着,要实现Web网页内元素操作调用客户端其他功能,就是需要实现html的DOM元素或者JavaScript与客户端C++代码的交互。对此,我们实现了两种技术方案的支持:,开放安全且少量的功能供Web调用,该功能也得到了较好的实现。


  最后,我们需要实现Web页面窗口与其他游戏内UI窗口的相互覆盖显示功能,这里面临了一个真正的困难。我们知道,在一个Windows应用程序中嵌入一个IE浏览器是通过在主程序窗口中创建一个子窗口的方式实现的,当我们将游戏画面渲染在主窗口中时,子窗口的内容会显示在主窗口,也就是游戏画面之上。因此就会造成IE浏览器中的Web页面内容覆盖在游戏其他UI窗口之上的现象。我们观察了市场上的若干知名网游,他们一般采用两种方法来处理这种Web页的显示:将包含Web的UI提至其他所有UI之上显示,或者干脆弹出独立的Windows窗口显示Web页。二这两种方式都是我们无法接受的,试想一下:如果玩家从活动宣传Web页中点击一个NPC寻路链接或者商城商品链接后,NPC寻路确认框或者商城界面被Web页遮挡住无法看到无法操作,这是多么悲惨的用户体验,更不用说还需要在两个Windows窗口中来回切换的奇葩体验了。但我们决定迎难而上解决这个问题,将内嵌Web页面的UI窗口和其他UI窗口带给玩家以一致的体验!

三、 解决问题的“小魔术”


  要实现内嵌Web页面的UI窗口和其他UI窗口自然地相互覆盖,必然需要将Web页面的内容按照我们游戏UI层次的规则在正确的时候渲染到游戏存上。当内嵌的IE浏览器既不按照我们指定的时间渲染也不将内容渲染到我们的后缓存上,于是接管网页渲染控制成为了我们的努力目标。我们重新将思考回到了内嵌IE的方案优化上。


 想要控制Web页面的渲染次序,我们应该如何做呢?将Web页面渲染到一张纹理上,然后将这个纹理贴在UI窗口上,随UI窗口的Render过程显示出来。


  如何获得一张纹理?从我们对内嵌的IE子窗口上截个图就能获得一张完美的Web页面纹理!这个想法瞬间触动了我们,但如何实现既能获得IE子窗口的截图又能不显示IE子窗口本身呢?我们发现即将发布的活动Web页面都是不包含动画内容的图文混排页面,既然不包括动画内容,当用户不操作这个Web页面时,其画面状态是不发生变化的,于是我们创新地想出了一个方案——在玩家面前玩个大变IE浏览器的小魔术:仅在玩家需要操作浏览器内页面的时候显示IE窗口,其他时候,通过游戏UI系统渲染玩家最后一刻看到IE内的页面的截图。


  经过实践测试,对于即将发布的Web页面在轩辕客户端中采用上述方法处理后,用户无法察觉上述变化的发生,但却成功实现了所需求的Web页面与其他UI窗口层叠的功能。至此,游戏内嵌Web页面与其他游戏UI窗口在显示、交互和功能体验上已经实现很高的一致性。

 当IE所在的UI被玩家操作时,显示的是真实的IE浏览器


 
  当玩家从Web页面中点开游戏内容链接后,IE窗口隐藏,原IE位置渲染最后一刻的Web页截图。可以看到此时商城界面等已经覆盖到了活动网页之上

四、 总结


  我们对用户体验最优化的追求从不停止,这种追求让我们从多种角度去审视技术,去发现它最简单但最关键的本质,并巧妙利用之以为提升用户体验所用。