cocos2dx-lua制作新手引导
2016-11-25 16:21
489 查看
cocos2dx-lua制作新手引导
最近在项目中负责制作新手引导,有些想法分享一下。常见的引导类型有点击和对话(剧情),甚至有些对话(剧情)不归属新手引导的范围,但是下文介绍的时候会涉及到剧情方面。
引导的整体逻辑
我的新手引导连贯性是使用事件派发实现,cocos2dx自带的事件派发是跟Node绑定的,所以你需要去找一个lua的事件派发(当然自己写一个更好)。下面的代码中sgEventDispatcher即为我使用的事件派发工具。新手引导肯定是跟UI层有关联的,这个无法避免所以一定要设置合理的UI节点保证你引导的位置。我这里UI是使用cocosbuilder来拼接的,lua层解析使用的Viewbase基类。在设计UI时,我会在有引导的ccb中设置一个空的Node,并且命名为ccbNodeTutorial, 然后Viewbase解析的时候,如果检测到该节点就会在该Node的”enterTransitionFinish”事件里注册监听引导的监听函数,然后在”exitTransitionStart”取消注册。
function ViewBase:registerListener() if not tutorialMgr:getTutorialOpenState() then return end self:onNodeEvent("enterTransitionFinish", function() if self.ccbNodeTutorial then sgEventDispatcher:registerEventListener("sgeNewTutorial", self.onEventAddTutorial, self) self:onNodeEvent("exitTransitionStart", self.unregisterListener, self) sgEventDispatcher:dispatchEvent("sgeStartTutorial") end end) end function ViewBase:unregisterListener() sgEventDispatcher:remove("sgeNewTutorial", self.onEventAddTutorial, self) end function ViewBase:onEventAddTutorial(event) if not tutorialMgr:checkCanCreateTutorialView(self) then return end app:showSwallowLayer() local node = display.newNode():addTo(self) performWithDelay(node, function() tutorialMgr:processNormalTutorial(self) end, delayTime) end
然后在每次新手引导完成,或者是加载一个含有可引导节点的时候,或者达到指定的条件(比如等级达到), 都会派发一个新的引导事件,有时候会收到多次派发事件,需要做好筛选。
新手引导主要考虑的问题:
新手引导中途断开怎么办?新手引导阻止触摸怎么实现?
新手引导一连串的引导怎么实现?
新手引导如果有特殊的触发条件?
新手引导如果有特殊场景的引导?
新手引导中途断开处理
新手引导设计一般是按照一定的时间轴进行的, 策划配表的时候可以按照一步一步来配置,但是每一步引导一般属于实现某个功能引导的一部分,可以按照对所属的功能引导把引导步数进行分组。配置示例:[1] = {index = 1, part = 1, type = 2, finish = 1, dialog = 901, receiver = "ccb/WelcomeScene.ccbi", }, [2] = {index = 2, part = 2, type = 1, finish = 1, receiver = "ccb/Gate.ccbi", target = "ccbNodeEnterGate", targetCallback = "onBtnEnterGate", },
然后在存档的时候只存储分组的字段,每次进入游戏都是取出该分组的第一步进行引导。但是在实际引导过程中,我们需要知道当前的具体引导索引,必须设置一个字段来记录当前的引导索引。新手引导管理类的初始化方法,self.baseInfo.curTutorialPart即为存档的引导分组,self.curIndex即为当前引导的具体索引:
function Ref:ctor() self.baseInfo = data.baseInfo self.guiding = false self.pause = false self.tutorial = tutorialApi:getTutorialInfoByPart(self.baseInfo.curTutorialPart) -- 判断引导是否开启 if self.tutorial == nil then self.state = stateOff else self.state = stateOn self.curIndex = self.tutorial.index end --注册监听 sgEventDispatcher:registerEventListener("sgeStartTutorial", self.onEventStartTutorial, self) sgEventDispatcher:registerEventListener("sgeEndTutorial", self.onEventEndTutorial, self) end
当引导完成时的处理:
function Ref:onEventEndTutorial() self.guiding = false --检查引导是否完成 if self:checkTutorialEndCondition() then self:processTutorialFinished() else --引导未完成重新进行该分组的引导 self.tutorial = tutorialApi:getTutorialInfoByPart(self.baseInfo.curTutorialPart) self.curIndex = self.tutorial.index self:dispatchTutorialEvent() end end --处理引导完成 function Ref:processTutorialFinished() local lastTutorial = self:getCurrentTutorialInfo() self.curIndex = self.curIndex + 1 if lastTutorial.finish == 1 then self.baseInfo.curTutorialPart = self.baseInfo.curTutorialPart + 1 end if self:getCurrentTutorialInfo() ~= nil then self:dispatchTutorialEvent() else -- 特殊引导完成 if lastTutorial.special == 1 then self.baseInfo.specialTutorial[lastTutorial.part] = 1 self.curIndex = self.backUpIndex self:dispatchTutorialEvent() else self:tutorialAllFinished() end end end
新手引导阻止触摸怎么实现?
在引导点击层中注册触摸监听事件,然后在onTouchBegan, onTouchEnded中处理--[[ 创建一个全屏阻止触摸的层,点击在指定范围内才会响应onTouchEnded方法,调用点击的回到方法。 self.swallow是因为有时候可能需要点击到下层,如果不需要可以去掉。 ]] function Ref:onTouchBegan(touch, event) local touchPoint = touch:getLocation() local touchPos = self:getParent():convertToNodeSpace(touchPoint) local swallow = self.swallow if not swallow then if cc.pGetDistance(touchPos, self.pos) > 50 then swallow = true else swallow = false end end return swallow end function Ref:onTouchEnded(touch, event) local touchPoint = touch:getLocation() local touchPos = self:getParent():convertToNodeSpace(touchPoint) if cc.pGetDistance(touchPos, self.pos) < 50 then self:processTutorialComplete() end end function Ref:processTutorialComplete() if self.callback then self.callback() end sgEventDispatcher:dispatchEvent("sgeEndTutorial") self:removeSelf() end
新手引导一连串的引导怎么实现?
就是通过事件派发实现,但是有许多细节需要处理。比如两次引导之间如果快速点击出现问题怎么办?我的解决方法是Node接收到合理的引导事件的时候创建一个全屏阻止触摸的layer,然后引导层出现之后移除该layer.
新手引导如果有特殊的触发条件?
local tutorialMap = { [1] = "onGuidingClick", [2] = "onGuidingStory", } -- 开始处理普通引导 function Ref:processNormalTutorial(view) if self:getIsGuidingTutorial() or self.pause or not self:checkTutorialStartCondition() then return end local tutorial = self:getCurrentTutorialInfo() if tutorial.voice then audio:preloadAudio(string.format(tutorialAudioPath,tutorial.voice)) end local funcName = tutorialMap[tutorial.type] local callback = handler(self, self[funcName]) local arg = callback(tutorial, view) self:pushTutorial(tutorial.type, arg) end
在self:checkTutorialStartCondition()检查引导配置里配置的引导条件是否满足,比如等级,未达到等级则不能进行引导。
新手引导如果有特殊场景的引导?
这个也可以理解为正常引导流程以外的引导。依然走的是正常引导的流程,不过需要把之前的引导进度保存起来,特殊引导走完之后再恢复回来。因为修改的是内存中self.curIndex的值,所以不需要考虑特殊引导进行中游戏中断的情况。-- 开始处理特殊引导 function Ref:processSpecialTutorial(view, type) if self.baseInfo.specialTutorial[type] ~= nil then return end self.backUpIndex = self.curIndex local specialTutorial = tutorialApi:getTutorialInfoByPart(type) self.curIndex = specialTutorial.index self.tutorial = self:getCurrentTutorialInfo() self.pause = false self:processNormalTutorial(view) end
相关文章推荐
- cocos2dx LUA使用ClippingNode来制作新手引导
- cocos2dx-3.4 lua新手引导
- cocos2dx混合模式应用———制作新手引导高亮区域
- cocos2dx混合模式应用———制作新手引导高亮区域 (2.2.0)
- Cocos2d-x教程(11)-利用遮罩(蒙版)CCLayerColor制作新手引导界面(上) (转)
- 游戏新手引导的制作原理(下)
- 【AS3 Coder】任务九:游戏新手引导的制作原理(下)
- 使用cocos2d-js制作游戏新手引导(一)
- Cocos2d-x教程(12)-利用遮罩(蒙版)CCLayerColor制作新手引导界面(中) (转)
- cocos2dx-lua制作游戏五维图
- Cocos2d-js制作游戏新手引导(二)
- [Quick-x]制作新手引导高亮区域方法之二:裁剪模式
- 制作新手引导高亮区域方法之一:混合模式
- Swift - 启动时的向导页(新手引导)的制作
- Cocos2d-x教程第(11)讲-利用遮罩(蒙版)CCLayerColor制作新手引导界面(上)
- 使用Cocos2d-JS制作游戏新手引导(一)
- cocos2dx 3.0 用ClippingNode做游戏的新手引导
- cocos2dx-lua使用UIListView制作二级折叠菜单
- 使用cocos2d-js制作游戏新手引导(二)
- 【Cocos2dx-lua 3.11.1】plist制作、播放帧动画