cocos2dx LUA使用ClippingNode来制作新手引导

新手教程是游戏开发必须的一部分,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。

  1. ResPaths;要挖空的图资源路径(图只要形状)
  2. strKeys;cocos studio中确定位置用的节点关键字。
  3. needlisten;根据strKeys位置挖空的地方是否支持触摸响应。
  4. NotListenResPaths,strNotListenKeys;同1,2一样,只是根据这个形状图挖空的地方不支持触摸响应。

效果图如下:

20161102181450









图中只有“牛牛”按钮能响应触摸事件,其余的切割部分不响应。

猜你喜欢

转载自blog.csdn.net/ouzhengai/article/details/53214131
今日推荐