前言
在某一些类型的游戏,如果鉴宝类的游戏、找茬类的游戏、射击瞄准类的游戏等,对于游戏场景中某个部分进行放大缩小,是必不可少的功能,那么如何实现放大镜的效果呢?
思路
核心部分,是对于摄像机(Camera)的运用。首先,需要了解摄像机的原理,和现实生活中的照相机一样,相机是用来拍摄的,在游戏中,相当于是人的眼睛,用于观察游戏世界。相机拍摄之后的画面,生成的照片,也就是 Texture,最终会显示在屏幕上。
实现放大镜效果,需要创建一个单独的摄像机,用于将局部的细节进行放大,然后调整相机的缩放比例,使局部细节的部分放大或者缩小。最后配合 Mash 组件将额外的部分进行裁剪,只留下我们想要的局部细节部分。
扩展部分
摄像机目前提供 2种模式: ORTHO 和 PERSPECTIVE 。ORTHO 是正交投影模式,也叫做"平行投影"。原理是将图像通过平行光投影到画面上,主要用于拍摄 2D 画面。PERSPECTIVE 是透视投影,它是锥形的成像模式,是从某个投影中心将物体投影到单一投影面上所得到的透视图,成像效果远小近大,与人眼观察物体时的视觉效果非常接近,主要用于拍摄 3D 画面。
简单理解,当设置为 ORTHO 模式的 Camera 是正交相机,也就是 2D 相机。当设置为 PERSPECTIVE 模式的 Camera 是透视相机,也就是 3D 相机。
多个相机内容叠加?怎么管理?
这个需要结合 Camera 的 Visibility 和节点的 Layer 共同决定的分组渲染。当相机启用的情况下,如果节点 A 的 Layer 设置为 UI_2D,如果相机 C 的 Visibility 里面的 UI_2D 有勾选,那么这个相机 C 会渲染这个节点 A 。如果相机 C 的 Visibility 里面的 UI_2D 没有勾选,那么这个相机 C 不会渲染这个节点 A。
多个相机内容渲染,如何决定哪个相机先渲染?
相机 Camera 里面有 priority 优先级属性。这个数值越小,越先渲染。比如相机 A 的 priority 为 0, 相机 B 的 priority 为 1。那么相机 A 的渲染内容会先渲染,然后渲染相机 B 的渲染内容。但是因为绘制顺序的缘故,当我们最终看绘制结果的时候,会看到相机 B 的渲染内容是盖在相机 A 的渲染内容上的。
相机内容怎么清除?
相机提供了多种的 Clear Flags 设置。DONT_CLEAR 是不清除相机的内容。DEPTH_ONLY 是只清空深度。SOLID_COLOR 是会清空颜色、深度与模板缓冲。SKYBOX 是启用天空盒,只清空深度。
如果有设置清空颜色,那么会使用 Clear Color 去清空没有被该相机渲染的部分。
实现步骤
- 添加一个放大镜的 UI,并添加一个 Sprite 组件用于放大镜的内容显示。在 Sprite 组件上添加一个 Mask 组件,用于将裁剪多余的显示内容。
- 添加一个专门用于渲染放大镜 UI 的摄像机 CameraMag。添加一个用于渲染地图和放大镜的摄像机 CameraBg。为什么需要 3个摄像机?Camera 是用于渲染地形的,最终我们会将 Camera 渲染的内容进行放大或者缩小,最终会渲染到放大镜中渲染的内容。CameraMag 只是用于渲染放大镜的UI。因为我们需要将放大镜的UI和地图拆分成不同的层级,所以我们让 CameraMag 只渲染放大镜的 UI,而放大镜的 UI 的 Layer 设置为单独的 magnifier。
- 通过代码
initCamera (){
const visibleRect = view.getVisibleSize();
let rendertex = new RenderTexture();
rendertex.initialize({ width: visibleRect.width, height:visibleRect.height });
let sp = new SpriteFrame();
this.cameraNode.getComponent(Camera)!.targetTexture = rendertex;
sp.texture = rendertex;
this.spriteNode.getComponent(Sprite)!.spriteFrame = sp;
this.spriteNode.setScale(this.scaleFactor, this.scaleFactor, 1);
}
通过新建 RenderTexture ,之后将 RenderTexture 设置到相机的 targetTexture 上,那么该相机全部的渲染内容都会渲染到 RenderTexture 上。之后我们将 RenderTexture 挂载到放大镜的 Sprite 组件上进行显示。
- 添加一些进度条,进行倍数的调节。
总结
放大镜的效果,是不是很容易掌握。主要还是需要理解 相机的原理,RenderTexture 以及分组渲染等。
参考示例
https://gitee.com/yeshao2069/CocosCreatorDemos/tree/v3.7.x/demo/2d/Creator3.7.0_2D_Magnifier