本文主要是介绍Cocos Creator 2D摄像机 [Lv.2] 截图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- 摘要
- 环境
- 资源
- 准备工作
- 正式开始
- 对工程做一些修改
- 如何互动
- 通过`RenderTexture` + `SpriteFrame`来实现小视图
- 截图
- 划重点
摘要
本文在Cocos Creator 2D摄像机 [Lv.1] 小视图
所完成的工程的基础上进行修改,并增加截图功能。
环境
- Cocos Creator 2.4.4
资源
- 官方Demo(capture_to_native)
- 本文Demo(CaptureScreenDemo)
准备工作
- Cocos Creator 2D摄像机 [Lv.1] 小视图 所完成的工程。
正式开始
对工程做一些修改
资源管理器
拷贝MiniMapDemo
场景,重命名为CaptureScreenDemo
。
拷贝MiniMapController.js
脚本,重命名为CaptureScreenController.js
。
层级管理器
- 将
CaptureScreenController.js
脚本,挂载在CaptureScreenController
节点上。
之后节点相关的设置请参考工程中的设置,文中不再赘述。
如何互动
截图功能需要通过RenderTexture
实现。
将摄像机照到的图像,渲染到RenderTexture
上,然后从RenderTexture
上读取出图像数据。
我们将通过右键点击,来触发截图功能。
通过RenderTexture
+ SpriteFrame
来实现小视图
创建一个sprite
,用来显示小视图,默认的SpriteFrame
删除掉。
在CaptureScreenController.js
中实现功能。
...
let _texture = null // RenderTexturecc.Class({...properties: {...smallView: cc.Sprite, // 小视图。},onLoad () {..._texture = new cc.RenderTexture()_texture.initWithSize(_canvasWidth, _canvasHeight, cc.gfx.RB_FMT_S8)this.camera.targetTexture = _texture // 将摄像机的渲染重定向到 RenderTexture 上。// spriteFrame 的 texture 指定为 RenderTexture ,// 再把 spriteFrame 添加到 smallView 上,// 这样摄像机照到的图像就能通过 smallView 显示出来了。let spriteFrame = new cc.SpriteFrame()spriteFrame.setTexture(_texture)this.smallView.spriteFrame = spriteFrame}, ...
});
将节点挂载到脚本对应变量上。
运行起来,看看效果,
小视图怎么这么小,而且还倒过来了。
小视图很小是由于camera.rect
发挥的作用。原先是以整个屏幕作为根本,设置的rect
。现在将targetTexture
定向到了smallView
上,由于smallView
已经设置了需要的大小,所以重置camera.rect
,让其按照默认的位置和尺寸显示就可以了。
显示倒过来的问题,我们可以通过设置smallView
的scaleY = -1
来解决。
同时还有一点,我们要将smallView
的分组设置为brush
。反正不能放在default
分组里,否则小视图又会被摄像机渲染出来。
运行起来,看看效果,
已经能正常显示了。但是又发现个小问题,小视图边框(黄线)的显示不太正常。
这是由于原先通过camera.rect
实现时,小视图边框是通过camera.rect
计算出来的。现在通过smallView
来显示,我们就需要通过其Node
的属性来计算小视图的边框。
在CaptureScreenController.js
中修改calCameraDisplayRect
函数的实现。
calCameraDisplayRect: function () {let cameraPos = this.smallView.node.getPosition() // 根据 smallView 的位置来计算。let cameraAnchor = cc.Vec2(this.smallView.node.anchorX, this.smallView.node.anchorX)let cameraSize = {width: this.smallView.node.width, height: this.smallView.node.height}// 绘制的矩形以左下角为原点。return new cc.Rect(cameraPos.x - cameraAnchor.x * cameraSize.width, cameraPos.y - cameraAnchor.y * cameraSize.height, cameraSize.width, cameraSize.height)},
运行起来,看看效果,
一切都正常了。
截图
在CaptureScreenController.js
中实现功能。
...
cc.Class({...onLoad () {...// 鼠标释放事件,通过右键点击鼠标截图。this.node.on(cc.Node.EventType.MOUSE_UP, this.onMouseUp, this)...}, ...onMouseUp (event) {let mouseType = event.getButton()if (mouseType === cc.Event.EventMouse.BUTTON_RIGHT) { // 鼠标右键释放。this.captureScreen() // 截图。}}, ...captureScreen () {this.camera.render() // 手动渲染摄像机。let picData = _texture.readPixels() // 从 RenderTexture 中读取图像数据。// 图像默认 Y 轴是颠倒的,需要翻转一下 Y 轴。picData = this.filpYImage(picData, _texture.width, _texture.height)this.saveFile(picData) // 存储图像。}, saveFile (picData) {if (CC_JSB) {// 存储到可写路径下。let filePath = jsb.fileUtils.getWritablePath() + 'render_to_sprite_image.png'// 存储图像。let success = jsb.saveImageData(picData, _texture.width, _texture.height, filePath)if (success) {cc.log("save image data success, file: " + filePath)}else {cc.error("save image data failed!")}}}, // This is a temporary solutionfilpYImage (data, width, height) {// create the data arraylet picData = new Uint8Array(width * height * 4) // 每个像素 4 字节。let rowBytes = width * 4for (let row = 0; row < height; row++) {let srow = height - 1 - rowlet start = srow * width * 4 // 从最后一行开始递减。let reStart = row * width * 4 // 从第一行开始递增。// save the piexls datafor (let i = 0; i < rowBytes; i++) {picData[reStart + i] = data[start + i]}}return picData},
})
运行起来,看看效果,
成功生成了截图文件。
划重点
- 通过
RenderTexture
+SpriteFrame
来实现小视图。 Camera.render()
->RenderTexture.readPixels()
->filpYImage()
->jsb.fileUtils.getWritablePath()
->jsb.saveImageData()
。
这篇关于Cocos Creator 2D摄像机 [Lv.2] 截图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!