cocos2dx LUA使用ClippingNode來製作新手引導
阿新 • • 發佈:2019-02-12
新手教程是遊戲開發必須的一部分,cocos2dx中也為我們提供了節點裁剪的類ClippingNode,在實際使用中還是有點麻煩,所以我自己包裝了個類。我是基於cocos2dx 3.3 的lua框架,其他版本的cocos2dx應該也差不多,思想一樣。具體實現如下:
-- 新手引導的類 local GuideClipLayer = class("GuideClipLayer",function() return cc.Layer:create() end)
GuideCilpLayer這個就是專門的切圖層,在使用時加到你遊戲介面的最上層。
GuideClipLayer.__index = GuideClipLayer --用於訪問 ------------------------------------------------------------- GuideClipLayer._visibleSize = nil -- 螢幕大小size GuideClipLayer._origin = nil -- 原點 GuideClipLayer._nodef = nil -- 模板(可以響應觸控事件) GuideClipLayer._cutSprites = {}-- 挖掉的那個圖(可以響應觸控事件) GuideClipLayer._cutNotListenSprites = {} -- 挖掉的那個圖(不可以響應觸控事件) GuideClipLayer._enableClick = false -- 響應點選事件 function GuideClipLayer:create(ResPaths,strKeys,needlisten,NotListenResPaths,strNotListenKeys) if needlisten == nil then needlisten = true end local layer = GuideClipLayer.new() layer:ctor() layer:addChild(layer:createClip(ResPaths,strKeys,NotListenResPaths,strNotListenKeys),1) layer:addChild(layer:createistenLayer()) layer._enableClick = needlisten return layer end function GuideClipLayer:ctor() self._nodef = nil self._cutSprites = {} self._cutNotListenSprites = {} self._enableClick = false self._visibleSize = cc.Director:getInstance():getVisibleSize() self._origin = cc.Director:getInstance():getVisibleOrigin() end function GuideClipLayer:createClip(ResPaths, strKeys,NotListenResPaths,strNotListenKeys) local clip = cc.ClippingNode:create()--建立裁剪節點 clip:setInverted(true)--設定底板可見 clip:setAlphaThreshold(0.0)--設定透明度Alpha值為0 local layerColor = cc.LayerColor:create(cc.c4b(0,0,0,150)) clip:addChild(layerColor,8)-- 在裁剪節點新增一個灰色的透明層 -- 建立模板,也就是你要在裁剪節點上挖出來的那個”洞“是什麼形狀的 self._nodef = cc.Node:create()-- 建立模版 --響應點選事件挖孔 for i = 1,#strKeys do local nodeSprite= BUI:findNode(strKeys[i]) if nodeSprite == nil then return end if ResPaths[i] == nil then print("裁剪節點跟資源個數不對應") else self._cutSprites[i] = cc.Sprite:create(ResPaths[i]) -- 這裡使用的那個圖示 local Pos = cc.p(nodeSprite:getParent():convertToWorldSpace(cc.p(nodeSprite:getPosition()))) self._cutSprites[i]:setPosition(Pos) -- 設定座標位置 self._nodef:addChild(self._cutSprites[i])-- 在模版上新增精靈 end end if NotListenResPaths and strNotListenKeys then for i = 1,#strNotListenKeys do local nodeSprite= BUI:findNode(strNotListenKeys[i]) if nodeSprite == nil then return end if NotListenResPaths[i] == nil then print("不響應觸控事件裁剪節點跟資源個數不對應") else self._cutNotListenSprites[i] = cc.Sprite:create(NotListenResPaths[i]) -- 這裡使用的那個圖示 local Pos = cc.p(nodeSprite:getParent():convertToWorldSpace(cc.p(nodeSprite:getPosition()))) self._cutNotListenSprites[i]:setPosition(Pos) -- 設定座標位置 self._nodef:addChild(self._cutNotListenSprites[i])-- 在模版上新增精靈 end end end local Pos = cc.p(0,0) self._nodef:setPosition(Pos) -- 設定的座標的座標位置上 clip:setStencil(self._nodef)-- 設定模版 return clip end --按鍵監聽 function GuideClipLayer:createistenLayer() local listen_layer = cc.Layer:create() -- 註冊單點觸控 local dispatcher = cc.Director:getInstance():getEventDispatcher() local listener = cc.EventListenerTouchOneByOne:create()--建立一個觸控監聽(單點觸控) -- 觸控開始 local function onTouchBegan(touch, event) if not self._enableClick then listener:setSwallowTouches(true) return true end local pos = touch:getLocation() -- 獲取觸點的位置 local posnodef = cc.p(self._nodef:getPosition()) local enableSwTc = false for i=1 , #self._cutSprites do local rect = self._cutSprites[i]:getBoundingBox() rect= {y = rect.y+posnodef.y, x = rect.x + posnodef.x, height = rect.height, width=rect.width} if cc.rectContainsPoint(rect,pos) then enableSwTc = true end end if enableSwTc then listener:setSwallowTouches(false) -- 如果觸點處於rect中 則事件向下透傳 else listener:setSwallowTouches(true) end return true -- 必須返回true 後邊move end才會被處理 end -- 觸控移動 local function onTouchMoved(touch, event) -- print("Touch Moved") end -- 觸控結束 local function onTouchEnded(touch, event) -- print("Touch Ended") end listener:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN) listener:registerScriptHandler(onTouchMoved, cc.Handler.EVENT_TOUCH_MOVED) listener:registerScriptHandler(onTouchEnded, cc.Handler.EVENT_TOUCH_ENDED) dispatcher:addEventListenerWithSceneGraphPriority(listener, listen_layer)-- 將listener和listen_layer繫結,放入事件委託中 return listen_layer end
在使用中直接呼叫
ChipNode = bf.GuideClipLayer:create(ResPaths,strKeys,needlisten,NotListenResPaths,strNotListenKeys)
if ChipNode then
GameGuideChipLayer:addChild(ChipNode)
end
建立黑色覆蓋層.
實際使用中需配合cocos studio。
- ResPaths;要挖空的圖資源路徑(圖只要形狀)
- strKeys;cocos studio中確定位置用的節點關鍵字。
- needlisten;根據strKeys位置挖空的地方是否支援觸控響應。
- NotListenResPaths,strNotListenKeys;同1,2一樣,只是根據這個形狀圖挖空的地方不支援觸控響應。
效果圖如下:
圖中只有“牛牛”按鈕能響應觸控事件,其餘的切割部分不響應。