新手教程是游戏开发必须的一部分,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一样,只是根据这个形状图挖空的地方不支持触摸响应。
效果图如下:
图中只有“牛牛”按钮能响应触摸事件,其余的切割部分不响应。