|
飞花产品3D游戏的探索之路
王潇
高途技术
高途技术 北京高途云集教育科技有限公司 科技让教育更美好 26篇内容
2024年08月21日 10:53
湖北
背景在当今的游戏开发领域,Cocos2d已经成为了一种非常流行的2D游戏开发引擎,它为开发者提供了丰富的工具和资源,使得制作2D游戏变得更加简单和高效。同时在Cocos2D游戏开发领域,我们积累了丰富的经验,成功开发了100多款绘本、互动交互题、趣味复习游戏以及超级飞车等游戏,均采用了Cocos2.4.3版本的引擎库。我们在Cocos2D开发方面已经达到了相当成熟的水平。为了提高教育和娱乐的结合性,塑造出生动趣味的学习环境,使得游戏不再只是消遣,而是成为寓教于乐的有效手段,我们使用cocos3D探索新的游戏开发。Cocos3D是在Cocos2D的基础上,结合了OpenGL ES来开发的。其继承了Cocos2D自由的游戏设计理念,且为开发者提供了在手机设备上运行3D游戏的所有必须功能,包括3D模型渲染、光照、阴影、碰撞检测等。在保证游戏性能的同时,还强化了游戏视觉效果,极大的增强了游戏的趣味性,并且让玩家在游戏中能够有更深的代入感。在Cocos3D中,场景构建主要通过场景编辑器来实现。开发者可以使用场景编辑器创建和编辑3D场景,包括添加和调整3D模型、光照、网格(MeshRenderer)、材质(Material)、粒子效果等。Cocos3D还支持混合渲染技术,即将2D元素和3D元素进行混合渲染,通过混合渲染,开发者可以在3D场景中添加2D元素,如UI、spine、文本等。Cocos3D集成了物理引擎使开发者能够轻松地实现真实物理效果,如碰撞检测、重力、运动学、关节等。开发者可以通过简单的API调用来创建和控制物理对象,并在场景中模拟真实的物理交互。综上所述,Cocos3D游戏开发引擎为丰富少儿游戏化学习的趣味性提供了强大的支持,它不仅可以使学习内容更生动、更具体,还可以提升学习体验的互动性和沉浸感,激发孩子们对学习的兴趣和热情。游戏全景游戏流程:游戏开始时毛豆开车驾驶在道路上。走过两条路的距离我们会出现题目面板(不同于其他的3D场景,题板是需要始终在最上层脱离画面存在的,因此我们使用2D的canvans绘制的题板),随着题板缓缓下落,小精灵给小朋友描述题干语音,出现录音喇叭倒计时,小朋友开始答题,程序收到语音评测反馈后会根据结果判断后续会出拐弯路+反馈路。当答题正确时,出现拐弯路+正确路,走过弯路毛豆则进入正确路段,正确路段上有远景彩虹,星星,蘑菇屋或者小仓鼠,在这个道路上毛豆可以左右移动去和星星发生碰撞反应,被碰到的星星会被收集起来。当答题错误时,出现拐弯路+错误路,走过弯路毛豆则进入错误路段,错误路段上有下着雨的乌云天,泥泞的道路会有小水坑,毛豆的小车可以左右移动躲闪水坑,否则会被撞击。所有题目答完之后毛豆会驶向终点,出现热气球,大门,总结面板同时灌木开花,整个游戏结束。有兴趣的伙伴可以扫描以下二维码观看:技术架构内容实现基于整个游戏,我们首先需要进行界面绘制,界面的绘制我们主要使用了摄像机,灯光,3D模型,2D Canvas。其中:摄像机用于确定游戏场景中的视角和视野范围,决定了玩家在游戏中所看到的画面。在Cocos3D中,摄像机可以控制视角的位置、旋转和投影方式,包括透视投影和正交投影。通过调整摄像机的位置和角度,可以实现不同的游戏视角,如第一人称视角、第三人称视角等。灯光用于模拟游戏场景中的光照效果,影响模型的明暗、色彩和阴影等。在Cocos3D中,常见的灯光类型包括环境光(Ambient Light)、方向光(Directional Light)、点光源(Point Light)和聚光灯(Spotlight)等。不同类型的灯光可以产生不同的光照效果,如环境光提供整体的光照,方向光模拟太阳光,点光源模拟点光源的光照效果等。我们的游戏中使用的是方向光。模型是游戏中的角色、道具、场景等物体的三维表示,由多边形网格组成。在Cocos3D中,模型可以是通过建模软件(如Blender、Maya等)创建的3D模型文件,常见的格式包括OBJ、FBX等(我们使用的是FBX)。模型可以通过导入到Cocos3D项目中,然后在游戏场景中实例化和放置,设置材质、纹理和动画等属性,从而呈现出游戏中的各种角色和场景。我们将界面分为四大部分,分别是:道路容器;角色控制器;题目容器;其他反馈元素。01道路容器:主路,草坪,草坪元素;我们将路分为四种分别是:常规路,拐弯路,正确路,错误路;这四种路分别做了四个prefab,每个prefab内分别对应不同的路面元素。初始化好不同的路面在后期的游戏过程中我们就可以专注于铺路的关系处理,免去计算路面元素的初始化,定位和消失。1.1 路面绘制道路容器内的路面,草坪,草坪元素是用一个用于渲染3D模型的组件MeshRenderer实现,模型的外观使用的是我们制作的材质Material渲染,Material它可以定义模型表面属性(如颜色、纹理、透明度等)的信息。同时MeshRenderer支持光照和阴影效果,可以与光源组件一起使用,以模拟光照和阴影效果。比较有挑战的是路面的坡度效果,我们可以通过编辑器的摄像机画面看下有无坡度的效果对比:坡度的实现方式首先是让路面在游戏中渲染成未受光照影响的几何形状或图像,并通过混合纹理和主颜色来实现着色效果,雾效,之后在微调偏移量参数allOffset的y值来控制远处顶点的偏移量和dist 变量来控制远处顶点的偏移程度实现的。基于此,我们注入一段shader代码到Material的Effect上,该段shader代码通过以下步骤改变路面的渲染效果:获取顶点属性和世界变换矩阵:i. 通过StandardVertInput In获取顶点的标准输入属性,包括位置、法线、切线等。ii.使用CCGetWorldMatrixFull(matWorld, matWorldIT)获取模型的世界变换矩阵和世界变换矩阵的逆转置矩阵,用于将顶点从模型空间变换到世界空间。计算顶点位置:i. 将顶点位置从模型空间变换到世界空间,即vec4 pos = matWorld * In.position。计算法线、切线和副切线:i. 通过世界变换矩阵将法线和切线从局部空间变换到世界空间,并计算副切线(bitangent),这些属性用于后续的光照计算。代码如下:传递纹理坐标和颜色:i. 将顶点的纹理坐标和颜色传递给片段着色器,以便进行纹理采样和颜色计算。传递雾效和阴影信息:i.使用CC_TRANSFER_FOG(pos)和CC_TRANSFER_SHADOW(pos)传递雾效和阴影信息给后续的片段着色器。执行偏移计算:i. 根据距离偏移参数dist和偏移量参数allOffset计算顶点的偏移量,并将偏移后的顶点位置从视图空间变换到投影空间。返回变换后的顶点位置:i. 返回经过世界变换和投影变换后的顶点位置,作为顶点着色器的输出。总的来说,顶点着色器代码主要负责对顶点进行世界空间到裁剪空间的变换,同时计算和传递顶点的法线、切线、副法线、纹理坐标和颜色等信息,片段着色器(unlit-fs)接收顶点着色器传递的属性,并使用主纹理采样获取纹理颜色。接着,它将纹理颜色与主颜色进行混合,并应用雾效,模拟远处物体的视觉模糊效果,输出最终的片段颜色。1.2 动态铺路路分四种:常规路,正确路,拐弯路,错误路;铺路逻辑:在场景道路一共三条的前提下,我们得知两条路之间的定位差为4,我们就认为两条路间的距离是4,初始化超出镜头的路的数量这个变量roadMoveOutCamera=0,因此我们每移动4*(roadMoveOutCamera+1)的间距就该铺路了,并且roadMoveOutCamera要+1。然后我们就需要结合答题来判断我们需要铺的是什么路,每走两条路的距离就来出题并且需要判断当前是否有正在执行的题目或题目反馈,如果没有的话就继续铺常规路并且出题目。当监听到答题反馈后我们就要铺一条拐弯路,紧接着根据反馈的结果来铺正确或者错误的道路,在行进过程中我们要保证反馈道路走三条,之后才能继续铺设常规路。1.3 难点攻克—拐弯前面我们提到过在物体前进过程中有走弯路的场景,因此当我们识别到物体在弯路路口时要让物体走对应的拐弯路,不同于直行路做简单的纵向移动,拐弯路需要在纵向移动的基础上再加上横向的平移。那么我们如何做这个平移呢?有以下几种实现方式我们来对比下他们的表现:实践探索:数学公式:在cocos开发的场景中,我们可以确定弯路所在面的坐标系,基于这个坐标系,我们选取n个样本坐标点录入excel表。Excel 提供了多种拟合函数,例如线性拟合、多项式拟合、指数拟合等。根据我们的数据特点选择多项式拟合的函数来拟合数据,最终生成一个拟合函数,即x = 0.0204 * Math.pow(y, 4) - 0.6978 * Math.pow(y, 3) + 8.733 * Math.pow(y, 2) - 46.825 * y + 90.803;这样我们就可以通过让需要走弯路的物体通过对该函数传入实际物体y坐标来计算出对应的x坐标点。关键帧动画用帧动画实现移动,首先我们对需要做动画的元素添加动画编辑器组件,然后制作动画文件挂载到该Animation上面。我们已知现在页面的移动速率是0.03/帧,走完一条路需要沿z轴方向移动4,计算出总共需要133帧。基于此我们可以得出动画轨迹的帧数范围[0, 133],然后对动画文件设置在0帧的位置为初始位置(0,0,z),133帧的位置为元素走完的位置(2,0,z)这样我们就可以得到一个匀速的物体运动轨迹。考虑到实际运动中物体的速度变化,我们可以添加中间帧来使物体运动更加丝滑。后续实现过程中考虑古诗答题十分灵活,题目数量无法评估,而该方案下每走一条弯路我们就要做一个动画,这个工作量是十分巨大的。如果有一种方式获取到动画文件的帧数据,那我们仅仅需要实现一个动画轨迹就可以根据左右偏移量动态计算出后续物体运动轨迹中0到133帧的物体坐标属性了。这一点也是该方案实现的一个卡点。因此排除了它实际应用的可能性。物理引擎模拟考虑到使用物理引擎的计算量和我们本身使用了物理系统的碰撞检测,再加上物理引擎对性能的要求。这个方案暂不考虑。插值法这是我们最终采用的实现方式,利用引擎能力tween去按照我们设定的起始值去执行运动轨迹,我们只需要调整对应的时间参数和起始点坐标,给他一个运动的轨迹参数即可实现拐弯效果,实现如下。定义路径点:首先,定义一系列路径点,描述元素要走的路径。对于我们的画面,需要定义轨迹的x坐标。计算移动时间:根据路径点位置的x坐标值和角色原始位置的x坐标值,计算出位置差△x,结合移动速率speed,计算出移动这段距离需要的时间duration=△x/speed;更新元素位置:使用tween方法,实现角色移动。tween(node).to(duration, {position: new Vec3(newX, y, z)}, {easing: 'easeInOutCirc'})鉴于我们的弯路不是那种复杂曲线且长度有限,因此插值法实现拐弯的表现还是不错的。02角色控制器:毛豆,碰撞体,小手,大背景;在这个容器中,除了主要的背景之外,所有的元素都是2D渲染元素。这些元素需要随着毛豆的移动而移动,因此将它们放在同一个容器中,以便于进行定位和移动操作。大背景作为3D模型也放在这个容器内,这样做是考虑方便后续道路移动方案的优化(也就是采用毛豆前进的方式)。在游戏中,当毛豆前进时,玩家的视野也会随之移动,而大背景则需要跟随着玩家的视野移动,以模拟真实的场景。我们将其放在一个容器就可以只考虑根节点的位移,这样能够简化移动和渲染的逻辑处理。而我们要在3D场景中使用2D元素,需要给对应的2D节点添加RenderRoot2D组件,以确保2D元素能够正常渲染,并与3D元素协调显示。毛豆做为整个游戏过程的唯一角色,在游戏的不同阶段有如下表现:正常行驶态;驶入弯路前要减速;拐弯路段上:弯路行驶+动作切换;正确路段上:加速行驶+车道切换+星星碰撞+动作切换;错误路段上:减速行驶+车道切换+泥坑碰撞+动作切换;03题目容器:主要是2D画面,用于出题展示;题目容器做为独立画面的一个存在,它与任何一个画面元素都没有关联且要始终在画面最上方。基于此我们将其做为一个画布出现,它拥有独立的摄像机且不会被任何游戏画面元素遮挡题目容器包含小精灵,题板,录音喇叭。小精灵用于播放题干;题板用于展示对应的题目内容,其中在播放题干语音的时候题目文字有逐字标红效果;录音喇叭来采集用户语音,进行语音评测,得到评测结果或者倒计时结束则题板滑动消失。以下是题目容器解析出题全流程:04其他反馈元素:彩虹,乌云,雨,关底大门,热气球,遮罩。该容器内的元素不直接参与游戏流程的交互,仅考虑它们的视觉表现、交互效果和对游戏体验的影响。彩虹是一个彩虹模型,使用渲染技术给它添加适当的纹理和光影效果;创建乌云的效果使用的是spine。雨滴,关底大门,热气球是在场景中添加对应的模型以及相应的光影和音效效果实现的。画面效果:总结和展望3D游戏在开发过程中,遇到了各种挑战和困难,比如:道路材质的制作如何才有弯道效果:详见1.1路面绘制文字在3D场景显示模糊问题:我们的游戏画面有分数面板,题板文字,结束古诗面板的展示,其中题板文字有逐字标红效果,基于此我们使用了label和rich组件来进行文字渲染。在3D场景中直接设置文字的font-size渲染出来文字会很模糊,解决这个问题有两个方式,一是在3D场景中,将文字的font-size设置较大值,然后设置节点的scale来使文字正常显示;二是将label和rich组件放在2D的canvas里面进行绘制。安卓手机图片为什么会成黑色:在使用 Cocos 中的 Texture 时,其大小受到设备的硬件限制。不同的设备具有不同的硬件性能和资源限制,因此对于 Texture 大小的限制也会有所不同。一般来说,移动设备(如手机和平板电脑)的硬件性能相对较低,因此对于 Texture 大小的限制可能会更加严格。常见的限制包括:最大尺寸限制:设备可能会限制 Texture 的最大尺寸,超过这个尺寸的Texture会被裁剪或者无法正常显示。通常,移动设备的最大 Texture 尺寸会在2048*2048或者4096*4096 之间。正常推荐是2048*2048以内。内存限制:设备的内存大小也会限制 Texture 的使用。较大的 Texture 可能会占用大量内存,导致内存不足或者性能下降的问题。通过不断的学习和尝试,最终完成了这个项目,同时我们在Cocos 3D游戏开发领域积累了丰富的经验,为后续产品的丰富性和趣味性实现奠定了基础。在今后的开发中,我们还需要进一步优化游戏的画面效果、改进用户体验,优化性能等,使游戏更加丰富流畅。END
|
|