前言:
不知道你在玩遊戲的時候有沒有發現這樣一個現象:就是咱們控制人物在地圖上移動時,人物和環境一直在發生位置變化,而咱們的那些控制按鍵、技能按鍵、還有金幣數或者能量值等···這些都沒有發生變化。爲實現這一效果,就須要用到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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。