在cocos2d-x游戏中实现tips功能
原文请猛戳: 这次分享一个简单的小功能,用cocos2d-x实现tips效果,作为之前一篇博文的后续。tips的行为很简单:点击某个node(我们不妨称它为 不废话,先上代码: function setupTips(params) local targetNode = params.target_node local tips = params.tips local excludeNodes = params.exclude_nodes or {} local DEFAULT_TIPS_DIST = 10 local TIPS_ZORDER = 1000 if tolua.isnull(targetNode) or tolua.isnull(tips) then return end tips:setVisible(false) targetNode:setTouchEnabled(false) display.getRunningScene():addChild(tips,TIPS_ZORDER) targetNode:addNodeEventListener(cc.NODE_EVENT,function(event) if event.name == "exit" then local scene = display.getRunningScene() scene:performWithDelay(MyPackage.callbackWrapper({scene},function() if not tolua.isnull(tips) then tips:setVisible(false) end end),0) local eventDispatcher = display.getRunningScene():getEventDispatcher() eventDispatcher:removeEventListenersForTarget(targetNode) end end) ------------------------------------------------------------ local function setTipsPosition() local leftBottomPos = MyPackage.getPositionOfNode(targetNode,display.LEFT_BOTTOM) local targetNodePos = display.getRunningScene():convertToNodeSpace(targetNode:getParent():convertToWorldSpace(leftBottomPos)) local targetNodeAnchorPoint = targetNode:getAnchorPoint() local tipsPos = targetNodePos local tipsAnchorPoint = cc.p(0,0) local director = cc.Director:getInstance() local glView = director:getOpenGLView() local frameSize = glView:getFrameSize() local viewSize = director:getVisibleSize() if targetNodePos.x <= frameSize.width * 0.5 / glView:getScaleX() then -- show tips on the right of the targetNode if the targetNode is on the left screen tipsPos.x = tipsPos.x + targetNode:getContentSize().width + DEFAULT_TIPS_DIST else -- show tips on the left of the targetNode otherwises tipsPos.x = tipsPos.x - DEFAULT_TIPS_DIST tipsAnchorPoint.x = 1 end if targetNodePos.y + tips:getContentSize().height > viewSize.height then tipsPos.y = viewSize.height tipsAnchorPoint.y = 1 end if targetNodePos.y < 0 then targetNodePos.y = 0 end tips:ignoreAnchorPointForPosition(false) tips:setAnchorPoint(tipsAnchorPoint) tips:setPosition(tipsPos) end ------------------------------------------------------------ local function activeFunc() local scene = display.getRunningScene() -- NOTE: delay util the next frame in order to get the correct WorldSpace position scene:performWithDelay(MyPackage.callbackWrapper({scene,tips},function() setTipsPosition() tips:setVisible(true) end),0) end local function inactiveFunc() if not tolua.isnull(tips) then tips:setVisible(false) end end local function isTouchInNode(touch,node) if tolua.isnull(node) or tolua.isnull(touch) then return false end local localLocation = node:convertToNodeSpace(touch:getLocation()) local width = node:getContentSize().width local height = node:getContentSize().height local rect = cc.rect(0,width,height) return getCascadeVisibility(node) and node:isRunning() and cc.rectContainsPoint(rect,localLocation) end local function isActive(touch) local isExcluded = false for _,excludeNode in ipairs(excludeNodes) do isExcluded = isExcluded or isTouchInNode(touch,excludeNode) end return isTouchInNode(touch,targetNode) and not isExcluded end local function onTouchBegan(touch,event) if isActive(touch) then activeFunc() return true else return false end end local function onTouchMoved(touch,event) local scene = display.getRunningScene() scene:performWithDelay(MyPackage.callbackWrapper({scene},function() if isActive(touch) then activeFunc() else inactiveFunc() end end),0) end local function onTouchEnded(touch,function() inactiveFunc() end),0) end local listener = cc.EventListenerTouchOneByOne:create() listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN) listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED) listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED) listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_CANCELLED) local eventDispatcher = display.getRunningScene():getEventDispatcher() eventDispatcher:removeEventListenersForTarget(targetNode) eventDispatcher:addEventListenerWithSceneGraphPriority(listener,targetNode) end 关于 上面的代码基本是很简单的,除了有几点需要额外说明一下: 1.几处调用到 function Node:performWithDelay(callback,delay) local action = transition.sequence({ cc.DelayTime:create(delay),cc.CallFunc:create(callback),}) self:runAction(action) return action end 2.我们指定 3.当同一个位置有多个具有 function getCascadeVisibility(node) if tolua.isnull(node) then return true end local visibility = node:isVisible() if visibility then local parent = node:getParent() visibility = visibility and getCascadeVisibility(parent) end return visibility end (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |