当前位置:首页 » 《资源分享》 » 正文

2021-09-11_小小虎哥的博客

13 人参与  2021年10月13日 08:43  分类 : 《资源分享》  评论

点击全文阅读


实现Cocos截图功能

    • 相关介绍
    • cocos截图的原理
    • 代码介绍
      • 原生平台截图

相关介绍

关于cocos截图方案,其实官方给出了对应的案例(js)。大家应该也参考过,但我个人认为官方案例不太适合直接在项目中使用,一方面截图很慢,亲测大概需要3-4s左右,所以我做了一写小的改动,并使用ts实现了对应的功能,希望能给大家带来一定的帮助。

cocos截图的原理

关于截图的原理。**一般情况下,无论是cocos还是unity 都是通过将场景内摄像机当前帧拍摄到的画面数据,保存在某个指定的文件路径下,但我们需要的时候,访问该路径,从而实现了各种游戏中的截图分享的功能。**当然大家也可以通过使用android或则ios提供的一些接口去实现,这里就不做多的赘述。

代码介绍

原生平台截图

1.一般情况下我们需要的是对游戏或则项目内的某一个界面进行截图,在cocos中也就是一个node节点。为了不影响整个游戏流程,我们可以单独给这个node添加一个相机,渲染一帧后,保存下来相机的数据,再把相机进行销毁即可。具体实现代码如下:

public static getCameraTexture(node: cc.Node): cc.RenderTexture {
        let camera = node.addComponent(cc.Camera);
        // 设置你想要的截图内容的 cullingMask
        camera.cullingMask = 0xffffffff;
        camera.clearFlags = cc.Camera.ClearFlags.STENCIL | cc.Camera.ClearFlags.DEPTH;
        camera.depth = 0;
        camera.rect = cc.rect(0, 0, 1, 1);
        camera.zoomRatio = Math.max(cc.winSize.height / node.height, cc.winSize.width / node.width)

        // 新建一个 RenderTexture,并且设置 camera 的 targetTexture 为新建的 RenderTexture,这样 camera 的内容将会渲染到新建的 RenderTexture 中。
        let texture = new cc.RenderTexture();
        texture.initWithSize(node.width, node.height, cc.game['_renderContext'].STENCIL_INDEX8);
        camera.targetTexture = texture;
        const scale = node.scaleY;
        node.scaleY = -1
        camera.render(node);
        node.scaleY = scale;
        //移除相机组件并且销毁相机
        node.removeComponent(camera);    
        camera.destroy();
        return texture;
    }

2.上面返回的就是cocos内的一个RenderTexture对象,这个对象是不能直接作为数据保存在手机中的,所以需要将其转换成我们需要的Uint8Array数据,关于如何转换cocos提供了对应的api:renderTexture.readPixels()

3.有了数据,就需要将数据保存起起来,保存数据针对不同的平台是有分别的原生平台和web分别不同。这里只讲述原生平台(区别不同平台主要是,只有原生平台支持我们使用jsb.fileUtils类去实现文件读写操作)。调用jsb.fileUtils.getWritablePath()原生平台会返回一个可支持读写的路径,提供我们进行文件读写操作这里截图为了不影响游戏主进程采用异步的方式去实现。具体代码如下:

 /**
     * @description 截图
     * @param screenshotNode 截图节点
     * @returns 存放截图的本地路径
     * 注意1.全屏截图需要添加自适应组件
     *  2.带透明的需要存储png格式(会出现亮斑)
     *  3需要占用内存少,不被透明度营销就存储为.jpg格式
     */
    public static captureScreen(screenshotNode: cc.Node): Promise<string> {
        return new Promise((resolve, reject) => {
            const renderTexture = CommonUtil.getCameraTexture(screenshotNode)
            const imgData = renderTexture.readPixels()
            if (CC_JSB) {   //CC_JBS标志是原生平台
                const shareImgRootPath = `${jsb.fileUtils.getWritablePath()}ShareImg/`
                const imgFilePath = shareImgRootPath + "_shareImg.jpg"
                console.log(`imgFilePath:`, imgFilePath);
                //@ts-ignore
                const success = jsb.saveImageData(imgData, screenshotNode.width, screenshotNode.height, imgFilePath)
             //文件写成功之后,返回图片存储的路径
                if (success) {  
                    resolve(imgFilePath)
                }
                else {
                    console.log(`save imgData failed! path:`, imgFilePath);
                    reject(null)
                }
            }
        })
    }

关于分享功能,就需要各位去接入微信,QQ等社会化分享的SDK,这里不做多的介绍。希望这篇文章能对大家有所帮助,我是爱分享技术的程序员小虎。


点击全文阅读


本文链接:http://zhangshiyu.com/post/29840.html

截图  平台  数据  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1