cocos-lua 手游之游戏新手引导

5 篇文章 0 订阅
4 篇文章 0 订阅

cocos-lua 手游之游戏新手引导

1.新手引导在游戏中还是比较重要的 往往新手引导的实现都是在游戏开发的后期
2.新手引导有这么几个要点
1.不影响原有的代码
2.断线后引导继续(也可跳过引导具体看策划的需求)
3.和服务器的交互
3.其实新手引导不仅仅可以作为开始游戏的引导 也可作为任务的对话 

ok,因为新手引导的方法很多 我现在就来说下我的新手引导的逻辑
1.把每一步的引导以枚举的形式保存(也可用配置文件)
2.GuideMgr只记录当前的步骤和当前引导的信息
3.添加引导 删除引导 用通知者模式通知界面
4.不影响原有的代码
具体的代码可能比较乱 所以我就只贴部分的代码
先来看下部分枚举
NewHandDef.STAGE = {
	STAGE_BUILD_FARM = 1,
	SRAGE_BUILD_IRON = 2,
	SRAGE_BUILD_SOLDIER = 3,
}

NewHandDef.BUILD_FARM_SUB_STAGE = {
	SUBSTAGE_1 = 1,
	SUBSTAGE_2 = 2,
	SUBSTAGE_3 = 3,
	SUBSTAGE_4 = 4,
}
枚举分为Stage SubStage 分别表示第几阶段 第几小步
再看下mgr的代码
NewHandMgr = class("NewHandMgr")

--[[
    1.判断是否需要引导
    2.记录下引导到当前的步骤 和引导的信息
--]]

local _instance = nil
local _guideIndex = nil -- 指引的顺序索引  
local _guideInfo = nil -- 当前引导信息 
local _isGuiding = nil-- 是否开启指引 
local _isGuideLayer = nil --是否有引导层

function NewHandMgr:ctor()
    _guideInfo = {}
	_isGuiding = false
    _isGuideLayer = false
end

function NewHandMgr:getInstance()
    if _instance == nil then
        _instance = NewHandMgr.new()
    end
    return _instance
end

-----外部调用这个函数 可以通知到adGuide 知道 _guideInfo 的信息
--进行判断 
function NewHandMgr:setGuideInfo(data)
    if not data then
        print("---------没有设置引导信息------------")
        return
    end
    if  not data.STAGE then
        print("---------没有设置引导信息的阶段------------")
        return
    end
    if not data.SUBSTAGE then
        print("---------没有设置引导信息的步骤------------")
        return
    end
    _guideInfo = data  
end

function NewHandMgr:addGuide()
    if _isGuiding and _guideInfo then
        DataCenter:getInstance():sendMsg(DataEvent.GUIDE.ADD, _guideInfo)
        _isGuideLayer = true
        printInfo("开始指引的是第%s阶段%s小步",_guideInfo.STAGE,_guideInfo.SUBSTAGE)
    end
end

function NewHandMgr:removeGuide()
    if _isGuideLayer then
         DataCenter:getInstance():sendMsg(DataEvent.GUIDE.END,_guideInfo)
         printInfo("指引的第%s阶段%s小步,完成",_guideInfo.STAGE,_guideInfo.SUBSTAGE)
        _guideInfo = nil
        self:nextGuide()
    end
    _isGuideLayer = false
end    
   
function NewHandMgr:nextGuide()
	if _isGuiding == false and _isGuideLayer then  
        return   
    end  
    if _guideInfo.STAGE == NewHandDef.STAGE.STAGE_BUILD_FARM then
        if _guideIndex < = #NewHandDef.BUILD_FARM_SUB_STAGE then<span style="font-family: Arial, Helvetica, sans-serif;">	</span>
<span style="white-space:pre"></span><pre name="code" class="cpp">            _guideIndex = _guideIndex + 1
 
 
 
 
            _guideInfo = {STAGE = NewHandDef.STAGE.STAGE_BUILD_FARM , SUBSTAGE = _guideIndex}
            self:addGuide()
            return
        end
    elseif _guideInfo.STAGE == NewHandDef.STAGE.SRAGE_BUILD_IRON then
        if _guideIndex < = #NewHandDef.BUILD_IRON_SUB_STAGE then
            _guideInfo = {STAGE = NewHandDef.STAGE.STAGE_BUILD_FARM , SUBSTAGE = _guideIndex}
            self:addGuide()
            return
        end
    elseif _guideInfo.STAGE == NewHandDef.STAGE.SRAGE_BUILD_SOLDIER then
        if _guideIndex < = #NewHandDef.BUILD_SOLDIER_SUB_STAGE then
            _guideInfo = {STAGE = NewHandDef.STAGE.SRAGE_BUILD_SOLDIER , SUBSTAGE = _guideIndex}
            self:addGuide()
            return
        end
    end
    print("----------引导全部完成-------------")
    _isGuiding = false
    _guideIndex = nil   
    _guideInfo = nil  
end
  
-- 是否进行新手引导  
function NewHandMgr:isGuiding()  
    return _isGuiding  
end  
  
-- 获取当前引导信息  
function NewHandMgr:getInfo()  
    return _guideInfo  
end  
在外部进行每一个触发条件的时候 引用setGuideInfo 假如现在城市到达了3级 提示需要建造农场 那进入农场层的时候 设置guideInfo 
由于外部都需要调用GuideLayer (引导层) 所以我们拿出来写 
 <pre name="code" class="cpp">require("app.Test.NewHandMgr")
local GuideLayer=class("GuideLayer", function()
	return cc.Layer:create()
end)

function GuideLayer:ctor(widget_data)
    local widget = widget_data.widget
    local pos = widget_data.pos
    --压黑
    local layerColor = cc.LayerColor:create(cc.c4f(0, 0, 0, 200), display.width, display.height)
    --高亮
    local clipNode = cc.ClippingNode:create()
    clipNode:setInverted(true)
    clipNode:addChild(layerColor)
    local stencilNode = cc.Node:create()
    local highLightNode = widget:clone()
    pos.x =  pos.x+widget:getAnchorPoint().x*widget:getBoundingBox().width
    pos.y =  pos.y+widget:getAnchorPoint().y*widget:getBoundingBox().height
    highLightNode:setPosition(cc.p(pos.x,pos.y))
    
    local tip_sprite = display.newSprite("equip_21.png")
    
    tip_sprite:setAnchorPoint(cc.p(0,0))
    tip_sprite:setPosition(highLightNode:getPosition())
    local action = cc.Blink:create(1,2)
    tip_sprite:runAction(cc.RepeatForever:create(action))
    tip_sprite:addTo(self)


    stencilNode:addChild(highLightNode)
    stencilNode:setAnchorPoint(cc.p(0.5,0.5))
    clipNode:setStencil(stencilNode)
    clipNode:setAlphaThreshold(0)
    self:addChild(clipNode)
    self:setTouchEnabled(true)
    local eventDispatcher = self:getEventDispatcher()

    local function onTouchBegan(touch, event)
        local locationInNode = highLightNode:getParent():convertToNodeSpace(touch:getLocation())
        -- dump(touch:getLocation())
        printInfo("点击的X=%s 点击的Y=%s",locationInNode.x,locationInNode.y ) 
        local rect = highLightNode:getBoundingBox()
        -- dump(rect)
        if  self:isVisible() == false then
            return false
        elseif cc.rectContainsPoint(rect, locationInNode) then
            print("----在高亮区域里---")
            NewHandMgr:getInstance():removeGuide()
            return false
        else
            return true
        end  
    end

    local function onTouchMoved(touch, event)
        
    end

    local  function onTouchEnded(touch, event)
        print("-----------触摸结束----------")
    end
    local listener = cc.EventListenerTouchOneByOne:create()
    self._listener = listener
    listener:setSwallowTouches(true)
    
    listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
    listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )
    listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )

    eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self)
  
end

return GuideLayer


 
 其实guideLayer的方法有很多种 我这只是利用剪切高亮实现的一种 下面我贴一个链接  
利用的是其他方法 剪切区域 把非剪切区域变暗
http://www.cnblogs.com/dudu580231/p/4563992.html或许你还会不理解convertToWorldSpace 和convertToNodeSpace再贴一个链接
http://blog.csdn.net/cjopengler/article/details/12117691 
现在我贴一部分在UI上使用这些类的代码
<pre name="code" class="cpp">require("app.View.UIManager")
require("app.Test.DataCenter")
require("app.Def.NewHandDef")
require("app.Test.NewHandMgr")
require("app.Def.DataEvent")

MainLayer = class("MainLayer", function()
	return display.newLayer()
end)

MainLayer.FILE_NAME = "csb/new_hand_guide.csb"
function MainLayer:onCreate()
	DataCenter:getInstance():addRegister(self)
	self:init()
end

function MainLayer:onRelease()
	DataCenter:getInstance():removeRegister(self)
end

function MainLayer:init()
	local guide_info = {STAGE = 1 , SUBSTAGE = 1}
	dump(guide_info)
	NewHandMgr:getInstance():setGuideInfo(guide_info)
	self._btn_1 = cc.uiloader:seekNodeByName(self,"test_btn_1")
	self._btn_2 = cc.uiloader:seekNodeByName(self,"test_btn_2")
	self._btn_3 = cc.uiloader:seekNodeByName(self,"test_btn_3")
	self._btn_1:addClickEventListener(handler(self, self.oneCallback))
	self._btn_2:addClickEventListener(handler(self, self.twoCallback))
	self._btn_3:addClickEventListener(handler(self, self.threeCallback))
	self.label =  display.newTTFLabel({
    	text ="111111",
   		size = 64,
   		color = cc.c3b(255, 0, 0)
  		})
	self.label:setPosition(display.cx,display.cy)
	self.label:addTo(self)
	NewHandMgr:getInstance():addGuide()
end

function MainLayer:oneCallback()
	local text = "i am _btn_1 clicked"
	self.label:setString(text)
end

function MainLayer:twoCallback()
	self.label:setString("i am _btn_2 clicked")
end

function MainLayer:threeCallback()
	self.label:setString("i am _btn_3 clicked")
end

function MainLayer:onDataChange(eventTag, param)
	if  eventTag == DataEvent.GUIDE.ADD  then
		self:NewHandEvnet(param)
	elseif eventTag == DataEvent.GUIDE.END then
		self:removeNewHandEvent(param)
	end
end

function MainLayer:NewHandEvnet(param)
	if not param.STAGE == NewHandDef.STAGE.STAGE_BUILD_FARM then
		return
	end
	if param.SUBSTAGE == NewHandDef.BUILD_FARM_SUB_STAGE.SUBSTAGE_1 then
		local widget_data = {widget = self._btn_1 , pos = self._btn_1:convertToWorldSpace(cc.p(0,0)) }
		dump(widget_data)
		UIManager:getInstance():addGuideLayer(widget_data)

	elseif param.SUBSTAGE == NewHandDef.BUILD_FARM_SUB_STAGE.SUBSTAGE_2 then
		local widget_data = {widget = self._btn_2 , pos = self._btn_2:convertToWorldSpace(cc.p(0,0)) }
		UIManager:getInstance():addGuideLayer(widget_data)

	elseif param.SUBSTAGE == NewHandDef.BUILD_FARM_SUB_STAGE.SUBSTAGE_3 then
		local widget_data = {widget = self._btn_3 , pos = self._btn_3:convertToWorldSpace(cc.p(0,0)) }
		UIManager:getInstance():addGuideLayer(widget_data)
	end
end

function MainLayer:removeNewHandEvent(param)
	if not param.STAGE == NewHandDef.STAGE.STAGE_BUILD_FARM  then
		return
	end
	UIManager:getInstance():removeGuideLayer()
end

 
 
 
  
 

现在我来贴一个大神用配置文件做的新手引导
http://blog.csdn.net/operhero1990/article/details/51482734

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值