Cocos2d 3.3 lua Camera使用,cocos2dlua
1.為什麼要使用Camera
遊戲有點像電影,鏡頭的使用非常重要。忽遠忽近,跟隨主角,情境切換等等。一般來說2d遊戲不太需要使用Camera,所以cocos2d 就沒太重視Camera,直到了3.3這個版本才較容易使用Camera。之前一些效果都可以使用其他方式來類比Camera,但是這樣邏輯就不太直觀,直接操作Camera是最完美的。
先來看我們這個Camera Demo的:
按照常理來理解就是,一個人不斷往上移動(我在飛,哈哈)。
遊戲實現方式有2種:
1. 固定人物在那個位置,然後把背景往下移動,這樣看起來"人物就在往上移動了"
2.人物往上移動,Camera的位置在人物的位置以下,距離人物一段距離,跟隨著人物移動而移動,背景完全不動,但會拼接。
在Cocos2d 3.3以前,只能用類似第一種方式來實現,一個視覺欺騙,這次有了Camera我們就可以用第二種方式來實現了,更加符合邏輯。
2.建立Camera
if self._camera == nil then self._camera = cc.Camera:createOrthographic(GameUtil:VISIBLE_WIDTH(), GameUtil:VISIBLE_HEIGHT(), 0, 1) self._camera:setCameraFlag(cc.CameraFlag.USER1) self:addChild(self._camera) self._camera:setPosition3D(cc.vec3(0, 0, 0)) end self:setCameraMask(2)
搞過opengl一些api的都知道,有兩種Camera,一種是跟現實生活中的網路攝影機一樣的,遠處的東西會小些,近處的會大點。另外一種是遠處和近處都一樣大。這裡是2d遊戲所以這裡就只管使用第二種Camera了。
createOrthographic有4個參數,大致規定了Camera看的範圍,3d空間那麼大,全部觀察會有很大消耗,也沒必要,所以Camera有一個觀察範圍的概念。這4個參數分別表示寬度,高度,近處,遠處。因為是2d遊戲,所以近處和遠處只要包含了0就OK了。如果你的遊戲情境沒有正常顯示,注意下有沒有包含0.
setCameraFlag 和 setCameraMask是一個對應的關係。決定了那些東西會被Camera看到。
enum class CameraFlag{ DEFAULT = 1, USER1 = 1 << 1, USER2 = 1 << 2, USER3 = 1 << 3, USER4 = 1 << 4, USER5 = 1 << 5, USER6 = 1 << 6, USER7 = 1 << 7, USER8 = 1 << 8,};
看源碼我們知道USER1 = 2, USER2 = 4等等,只要把node的CameraMask設定跟CameraFlag值一樣,這個node對Camera來說就是可見的。
你可以對一個layer的cameramask進行設定,這樣layer中的所有node就遞迴都設定了。設定的時機也要非常注意,要在最後設定,這樣前面添加的node才會起作用。
這裡有一個要注意的:
因為使用了Camera,所以在遊戲中新增一些東西的時候,不要忘記了給新增的東西設定cameramask,不然就看不見了!
3.不受Camera的限制的node
注意到右上方的暫停按鈕了嗎?它的位置是固定的,沒有進行任何移動。是怎麼做到的呢?非常簡單,不設定cameramask就可以了。不是說不設定cameramask就看不到了嗎?這裡怎麼又可以看到,而且位置不變?。這裡就複雜了,跟cocos2d整個遊戲引擎的camera實現有關,太複雜了,我都還沒搞懂。
4.背景的拼接
雖然這篇文章主要講Camera,這裡還是扯一下背景的處理。因為使用了Camera,所以背景可以不需要移動了。但是這樣Camera往上移動,背景就被甩在後面了,就沒背景了。所以背景要不斷改變位置。
什麼時候改變位置呢?當第一張背景的頂部位置在Camera位置之下的時候,就可以把這個背景圖片移到所有背景圖的最上面。
function GameBackgroundLayer:getFirstBgTop()return (self.allBackGrounds[1]:getPositionY() + self.height * 0.5)endfunction GameBackgroundLayer:moveFirstBgToLast()local firstBg = self.allBackGrounds[1]table.remove(self.allBackGrounds, 1)table.insert(self.allBackGrounds, firstBg)firstBg:setPositionY(self.allBackGrounds[#(self.allBackGrounds) - 1]:getPositionY() + self.height)endfunction GameObjectsLayer:update(dt) if(self._camera:getPositionY() >= g_GameMainLayer.backgroundLayer:getFirstBgTop())then g_GameMainLayer.backgroundLayer:moveFirstBgToLast() end end
我這裡雖然只有2張背景圖片,但是還是使用了table來儲存。這樣方便擴充。3,4張背景圖片也能很方便的使用。具體實現看這個Demo的源碼。
5.看一下camera的具體使用
這個是新做的遊戲,使用了cocos2d 3.3中的camera,玩下就會更加清楚些。
IPhone下載: https://itunes.apple.com/cn/app/30-wait/id954181532?l=zh&mt=8 安卓下載:http://toycloud.qiniudn.com/StickHero.apk掃描二維碼下載更加容易。
6.上面講到的Camera Demo源碼下載
http://www.waitingfy.com/?attachment_id=1487
http://www.waitingfy.com/archives/1488