CocosCreator 无死角Camera游戏摄像机 (第十篇)

前言:
不知道你在玩游戏的时候有没有发现这样一个现象:就是咱们控制人物在地图上移动时,人物和环境一直在发生位置变化,而咱们的那些控制按键、技能按键、还有金币数或者能量值等···这些都没有发生变化。为实现这一效果,就须要用到Camera摄像机了,简单介绍一下,摄像机是玩家观察游戏世界的窗口,场景中至少须要有一个摄像机,也能够同时存在多个摄像机。建立场景时,Creator 会默认建立一个名为 Main Camera 的摄像机,做为这个场景的主摄像机。多摄像机的支持可让你轻松实现高级的自定义效果,好比双人分屏效果,或者场景小地图的生成。javascript

通俗一点就是不少台摄像机一块儿拍电影,可是不一样的摄像机拍的内容不同,而后一同在屏幕上显示!java


Camera组件属性面板:
在这里插入图片描述node


1、Camera属性介绍

1. backgroundColor

当指定了摄像机须要清除颜色的时候,摄像机会使用设定的背景色来清除场景。web

2. depth

摄像机深度,用于决定摄像机的渲染顺序。值越大,则摄像机越晚被渲染。
这样就能够制做出层级关系的画面了,出现覆盖现象。canvas

3. cullingMask

cullingMask 将决定这个摄像机用来渲染场景的哪些部分。微信

通常游戏中的 UI 部分都是不须要移动的,而游戏节点可能会往屏幕外移动,这时须要另外的一个摄像机去跟随这个游戏节点。svg

4. clearFlags

指定渲染摄像机时须要作的清除操做函数

5. rect

决定摄像机绘制在屏幕上的哪一个区域,便于实现相似小地图那样的 Viewport,值为 0~1。测试

6. zoomRatio

指定摄像机的缩放比例,值越大显示的图像越大。url

7. alignWithScreen

当 alignWithScreen 为 true 的时候,摄像机会自动将视窗大小调整为整个屏幕的大小。若是想要彻底自由地控制摄像机,则须要将 alignWithScreen 设置为 false。(v2.2.1 新增)

8. orthoSize

摄像机在正交投影模式下的视窗大小。该属性在 alignWithScreen 设置为 false 时生效。

9. targetTexture

若是设置了 targetTexture ,那么摄像机渲染的内容不会输出到屏幕上,而是会渲染到 targetTexture 上。

若是你须要作一些屏幕的后期特效,能够先将屏幕渲染到 targetTexture ,而后再对 targetTexture 作总体处理,最后再经过一个 sprite 将这个 targetTexture 显示出来。

3D 摄像机属性

这些属性在摄像机节点设置为 3D 节点 后才会显示在 属性检查器 中。

  • nearClip:摄像机的近剪裁面。
  • farClip:摄像机的远剪裁面。
  • ortho:设置摄像机的投影模式是正交(true)仍是透视(false)模式。
  • fov:决定摄像机视角的高度,当 alignWithScreen 和 ortho 都设置为 false 时生效。

2、摄像机方法

1. cc.Camera.findCamera

findCamera 会经过查找当前全部摄像机的 cullingMask 是否包含节点的 group 来获取第一个匹配的摄像机。

cc.Camera.findCamera(node);

2. containsNode

检测节点是否被此摄像机影响。

3. render

若是你须要当即渲染摄像机,能够调用这个方法来手动渲染摄像机,好比截图的时候。

camera.render();

3、坐标转换

一个常见的问题是,当摄像机被移动、旋转或者缩放后,这时候用点击事件获取到的坐标去测试节点的坐标,这样每每是获取不到正确结果的。

由于这时候获取到的点击坐标是屏幕坐标系下的坐标了,咱们须要将这个坐标转换到世界坐标系下,才能继续与节点的世界坐标进行运算。

下面是一些坐标系转换的函数:

// 将一个屏幕坐标系下的点转换到世界坐标系下
camera.getScreenToWorldPoint(point, out);
// 将一个世界坐标系下的点转换到屏幕坐标系下
camera.getWorldToScreenPoint(point, out);

// 获取屏幕坐标系到世界坐标系的矩阵,只适用于 2D 摄像机而且 alignWithScreen 为 true 的状况
camera.getScreenToWorldMatrix2D(out);
// 获取世界坐标系到屏幕坐标系的矩阵,只适用于 2D 摄像机而且 alignWithScreen 为 true 的状况
camera.getWorldToScreenMatrix2D(out);

4、截图

截图是游戏中一个很是常见的需求,经过摄像机和 RenderTexture 咱们能够快速实现一个截图功能。

// 此代码仅适用于 web 平台。要在 native 平台中使用这个功能,请参考 example-case 中的 capture_to_native 场景。
let node = new cc.Node();
node.parent = cc.director.getScene();
let camera = node.addComponent(cc.Camera);

// 设置你想要的截图内容的 cullingMask
camera.cullingMask = 0xffffffff;

// 新建一个 RenderTexture,而且设置 camera 的 targetTexture 为新建的 RenderTexture,这样 camera 的内容将会渲染到新建的 RenderTexture 中。
let texture = new cc.RenderTexture();
let gl = cc.game._renderContext;
// 若是截图内容中不包含 Mask 组件,能够不用传递第三个参数
texture.initWithSize(cc.visibleRect.width, cc.visibleRect.height, gl.STENCIL_INDEX8);
camera.targetTexture = texture;

// 渲染一次摄像机,即更新一次内容到 RenderTexture 中
camera.render();

// 这样咱们就能从 RenderTexture 中获取到数据了
let data = texture.readPixels();

// 接下来就能够对这些数据进行操做了
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
let width = canvas.width = texture.width;
let height = canvas.height = texture.height;

canvas.width = texture.width;
canvas.height = texture.height;

let rowBytes = width * 4;
for (let row = 0; row < height; row++) { 
 
   
    let srow = height - 1 - row;
    let imageData = ctx.createImageData(width, 1);
    let start = srow*width*4;
    for (let i = 0; i < rowBytes; i++) { 
 
   
        imageData.data[i] = data[start+i];
    }

    ctx.putImageData(imageData, 0, row);
}

let dataURL = canvas.toDataURL("image/jpeg");
let img = document.createElement("img");
img.src = dataURL;

截取部分区域:

当摄像机设置了 RenderTexture 而且 alignWithScreen 为 true 的时候,camera 视窗大小会调整为 design resolution 的大小。若是只须要截取屏幕中的某一块区域时,设置 alignWithScreen 为 false,而且根据摄像机的 投影方式 调整 orthoSize 或者 fov 便可。(v2.2.1 新增)

camera.alignWithScreen = false;
camera.orthoSize = 100;
camera.position = cc.v2(100, 100);

在原平生台上保存截图文件:

首先先截图,而后在  readPixels  以后使用:
var data = renderTexture.readPixels();
var filePath = jsb.fileUtils.getWritablePath() + 'Image.png';
jsb.saveImageData(data, imgWidth, imgHeight, filePath)

微信中的截图:

注意:微信小游戏中因为不支持 createImageData,也不支持用 data url 建立 image,因此上面的作法须要一些变通。在使用 Camera 渲染出须要的结果后,请使用微信的截图 API:canvas.toTempFilePath完成截图的保存和使用。


推荐阅读:
CocosCreator 教你如何使用对象池 (第九篇)
CocosCreator 经典飞刀小游戏 (实战)

本文同步分享在 博客“战 胜”(CSDN)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索