阿里妹攻略:近期APP游戏化成为新风口,将游戏中一些好玩、吸引用户的娱乐方式或场景应用到应用中,以增加用户粘性,提高DAU效果,以及减少开支。降低。同时,在一些需要对用户进行引导的场景下,游戏化也可以让用户更容易接受和完成引导任务,通过激励的方式促使用户持续沉浸在任务中,形成良性循环。基于这样的想法,闲鱼开发了交互引擎Candy。什么是糖果引擎?Candy是闲鱼技术团队设计研发的引擎:嵌入APP的交互引擎,轻量级,易于开发,性能稳定;渲染系统与Flutter系统高度集成,游戏场景与FlutterUI支持无缝混合;动画系统支持主流格式,友好且易于扩展。本文解释了我们制作此引擎的原因以及我们如何设计它。目前APP内嵌小游戏普遍采用H5小游戏的方式,但这种方式存在一定的隐患,很多应用商店并不推荐。因此,我们需要寻找一种新的、安全的方式来实现APP内嵌小游戏,希望这种方式开发友好、性能稳定、功能齐全;所以我们按照这三点来寻找新的方法。思考我们主要用以下三个思路来讨论APP内嵌的小游戏:原生游戏能力目前在Native的游戏生态开发上还不是特别成熟,如果使用Native开发,必然面临双端二分的问题套代码,开发成本和后续维护成本会比较高。使用游戏引擎,比如Cocos-2dx、Unity等。虽然游戏引擎目前已经非常成熟,但是游戏引擎一般都是用来开发重度游戏,所以引擎体积一般都比较大,引入游戏引擎会导致封装尺寸的显着增加。而且游戏引擎比较复杂,启动引擎需要很长时间,很难秒开游戏页面;游戏引擎加载后,内存消耗会比较大。游戏引擎与APP的通信交互相对繁琐,目前也没有很好的混合栈支持。游戏引擎UI能力较弱,无法处理复杂的APPUI逻辑。如果使用游戏引擎开发嵌入式小游戏,则无法在小游戏页面中集成游戏场景和Feeds等UI。使用Flutter的轻量级交互引擎Flutter本身是基于Skia这种2D渲染引擎的跨终端APP解决方案,自然具备2D渲染能力,所以利用Flutter实现App内嵌的小游戏成为可能。目前Flutter中有一些轻量级的游戏引擎,比如Flame。该引擎支持简单的游戏逻辑和动画功能。同时,最终将整个游戏以Widget的形式嵌入到APP中,可以让小游戏页面的游戏部分和UI部分完美融合。综上所述,我们决定采用Flutter的轻量级交互引擎。火焰?还是自行设计?Flame引擎目前是Flutter生态中比较优秀的小游戏引擎,但是还存在很多问题:游戏系统不够完善:引擎只有Game和Componet,没有Scene和GameObject的概念,会导致游戏对象的复杂嵌套。场面并不友好。引擎完全由Canvas实现,游戏场景无法实现局部刷新,存在性能隐患。缺少GUI系统,很难在场景中嵌套UI。缺少手势事件系统。动画支持格式不主流:Flare支持骨骼动画,DragonBones不支持。粒子动画最近才上线,对主流格式支持不是很友好。资源管理存在内存问题,资源加载后不会释放。缺乏模型适应性。基于这些考虑,我们决定重新设计一个Flutter交互引擎:针对标杆组的EVA引擎和业界的Unity引擎,来完善游戏系统。复用Flutter局部刷新。将FlutterUI重用为GUI。复用Flutter手势管理。实现对主流格式的骨骼动画和粒子动画的支持。复用APP资源库(图片库)。实现全局750适配。其中2-4点本质上是将交互引擎的渲染系统集成到Flutter的渲染系统中。下面的文章将介绍我们的引擎设计,以解决上述问题。Candy引擎设计框架设计首先分析游戏化业务需要哪些能力,分析我们的业务场景,得出游戏化业务需要的能力如图4-1所示:拆解后交互引擎需要有游戏系统、渲染系统、生命周期系统、GUI系统、物理系统、动画系统、资源系统、事件系统(手势管理)。根据我们之前的定位,交互式游戏绘图被集成到Flutter绘图系统中。基于这样的思路,我们可以复用Flutter的UI系统,同时需要整合Flutter和游戏手势管理。最终得到如图4-2所示的框架图:整个交互引擎架构分为四个部分:界面层对外暴露的游戏界面,主要包括创建游戏、创建游戏对象、添加游戏组件和其他接口。一个工厂接口,封装了一些通用的游戏对象和通用的游戏组件。GameSystem游戏世界的管理系统,主要管理Game、Scene、GameObject和Component之间的组织关系,同时控制游戏子系统和渲染系统的启动和关闭。补充了游戏子系统的游戏化能力,主要包括游戏系统调用的生命周期系统、物理系统、动画系统和资源系统。渲染系统负责游戏的渲染。该引擎的渲染系统将与Flutter渲染逻辑高度集成,因此兼容GUI系统和事件系统(手势管理)。游戏系统设计符合Unity。游戏系统有以下四个元素:Game:游戏类,负责整个游戏的管理,Scene的加载管理,以及各个子系统的管理和调度。Scene:游戏场景类,负责游戏场景中各个游戏对象的管理。GameObject:游戏对象类,游戏世界中游戏对象的最小单位,游戏世界中的任何对象都是一个GameObject。Component:游戏组件类,代表游戏对象的能力属性。比如SpriteComponent代表的是精灵组件,它代表了绘制精灵的能力。GameObject通过组合Components让自己拥有各种能力,不同的组合使得GameObjects各不相同。整个游戏系统的组织关系如图4-3所示:生命周期是基于Unity和Flutter的特点。我们设计了如表4-1所示的生命周期,共有8个回调,基本可以满足互动游戏业务开发的需要。渲染系统基于Flutter渲染系统的集成。我们不能用Canvas来管理整个游戏的渲染。我们需要将游戏对象与Flutter渲染对象RenderObject结合起来,如图4-4所示:首先,Game对象数与Flutter的三棵树进行了有效的整合,因此每个GameObject必须对应一个Widget,Element,和渲染对象。融合过程主要需要解决以下问题:游戏的坐标系与Flutter的布局转换融合。处理动态添加和删除游戏对象。动态修改游戏绘制深度的处理。FlutterInspector支持游戏对象。整个渲染集成比较复杂,需要解决很多BadCases。后面会写另一篇文章详细介绍将交互式引擎渲染集成到Flutter渲染系统中的过程,本文不再赘述。由于GUI系统的绘制已经集成到Flutter系统中,GameObjects会对应Widgets,所以我们可以设计一个特殊的GameObject,支持插入一段FlutterWidget树,这样我们就不需要另外实现GUI了,并将FlutterUI重用为GUI。这个逻辑和绘图集成的思路是一致的。只需将插入的Widget树用作GUIWidget的子项,并在GUIRenderObject中打开布局、绘制和hitTest逻辑。下面是我们的GUI的示例代码,开发过程比较简单:constColor(0xFFA9CCE3),borderRadius:constBorderRadius.all(Radius.circular(10.0),),),child:constCenter(child:Text('FlutterUIexample',样式:TextStyle(fontSize:14.0,),),),),行为:HitTestBehavior.opaque,onTap:(){print('UIwasclicked');},),position:Position(100,100),);game.scene.addChild(gui);event在将系统绘图集成到Flutter系统的基础上,我们集成了事件系统,并添加了手势处理组件GestureBoxComponent,如图4-5所示:整个集成过程分为以下几个步骤:GestureBoxComponent将开发者注册手势回调方法注册到手势识别器中。GameObject对应的RenderObject覆盖了hitTest逻辑,按照Flutter规范对点击的hitTest进行处理。使用GestureBoxComponent来确定是否应该消耗点击。GameObject重写handEvent以将点击事件传递给GestureBoxComponent以供消费。GestureBoxComponent收到点击事件后,将其传递给手势识别器进行处理。手势识别器通过将点击传递给手势竞技场开始手势比赛,最后将获胜的手势返回给手势识别器,最后返回并响应手势事件。当然,这一步属于Flutter逻辑。动画系统我们目前的动画主要支持骨骼动画和粒子动画。骨骼动画资源目前支持DragonBones,粒子动画资源目前支持EgretFeather。资源系统交互引擎目前的资源系统比较简单,本文就简单介绍一下。资源系统的设计思路是复用app的资源系统,保证整个app只有一个资源库,减少内存开销,提高资源复用率。资源系统架构如图4-6所示。在游戏系统和资源系统之间增加了一层代理,兼容APP资源系统和口袋资源系统。如果我们不注册APP的资源系统,系统会自动调用口袋底部的资源系统。Pundit资源系统目前分为两部分:Pocket图片库,复用了Flutter的ImageCache,复用了Flutter的内存管理能力。动画JSON资源管理目前只实现JSON读取逻辑。由于JSON的复用性较低,目前没有实现缓存管理。目前资源系统还没有做远程加载和预加载的能力。这部分在我们后续的规划中,后面会写一篇文章分享具体的设计实现。最后这篇文章主要介绍了Candy交互引擎的设计,我们在设计实现过程中遇到了很多问题,比如在Flutter的绘图过程中发现了一定的内存泄露,内存回收没有及时等,后面我们会详细排查和解决这些问题,我们也会对Candy引擎的性能和稳定性做详细的测试和分析。本文作者:燃道阅读原文来自阿里云合作伙伴“阿里科技”,如需转载请联系原作者。
