现在的位置: 首页 > 综合 > 正文

武侠-CareObject

2012年07月03日 ⁄ 综合 ⁄ 共 4662字 ⁄ 字号 评论关闭

一 应用:关心与某逻辑Obj的距离(用于商人或者任务窗口/下拉菜单等,当距离超过一定距离后自动关闭)

二 实现

1 首先注册lua接口

 

INT CUIWindowItem::LUA_CareObject(LuaPlus::LuaState* pState)
{
    LuaStack args(pState);
    
if(!(args[2].IsInteger()))
    {
        KLThrow(
"LUA: CUIWindowItem::LUA_CareObject[2] Wrong Param1");
    }
    
if(!(args[3].IsInteger())) 
    {
        KLThrow(
"LUA: CUIWindowItem::LUA_CareObject[3] Wrong Param1");
    } 
    
if(!(args[4].IsString()))
    {
        KLThrow(
"LUA: CUIWindowItem::LUA_CareObject[4] Wrong Param1");
    }

    // Object的ID
    INT nObjID = args[2].GetInteger();

    // 是否关心
    INT    bCare = args[3].GetInteger()==1;

    // 谁在关心
    std::string str = args[4].GetString();

    g_pObjectSystem->CareObject(nObjID, bCare, str);

    return 0;
}

 

2 保存到map里面

 

// 关心某物体的指定事件 id-物体ID,    szSign:关心标志(谁关心)        bCare-关心或者取消关心
// 修改说明:添加一个“是谁关心”的内容
VOID CObjectManager::CareObject(INT id, BOOL bCare, std::string szSign)
{
    
//AxTrace(0,0,"C++ id =%d,bCare =%d,szSign =%s",id,(INT)bCare,szSign.c_str());
    
// 搜索物体
    CObject* pObject = (CObject*)FindObject(id);
    
if(!pObject) return;

    // 是否已经加入
    std::map< std::string, OBJECT_BECARED >::iterator it;
    it 
= m_mapCaredObject.find(szSign);

    // 在表中已经有
    if(it != m_mapCaredObject.end())// && !bCare)
    {
        
if(bCare)
        {
            
// 这个界面已经有关心的NPC,去关心新的 Npc 就可以了,
            it->second.id = id;
        }
        
else
        {
            
// 取消关心的操作
            m_mapCaredObject.erase(it);
        }
    }

    // 在表中没有
    if(it == m_mapCaredObject.end() && bCare)
    {
        OBJECT_BECARED objNewCared;
        objNewCared.id      
= id;
        objNewCared.fLastDistance 
= KLU_GetDist(fVector2(GetMySelf()->GetPosition().x, GetMySelf()->GetPosition().z),
                                                fVector2(pObject
->GetPosition().x, pObject->GetPosition().z));

        m_mapCaredObject.insert(std::make_pair(szSign, objNewCared));
    }
}

 

3 Tick遍历

 

VOID CObjectManager::Tick(VOID)
{
    
// 检查是否有物体不再被关心
    if(CGameProcedure::GetActiveProcedure() == CGameProcedure::s_pProcMain)
        m_pLogicalObject
->Tick_CheckAlive();

    // 执行逻辑函数
    m_pLogicalObject->Tick();

    // 检查被UI关心的逻辑对象
    std::map< std::string, OBJECT_BECARED >::iterator it;
    
for(it=m_mapCaredObject.begin(); it!=m_mapCaredObject.end(); it++)
    {
        OBJECT_BECARED
& obj = it->second;
        
// 物体是否存在
        CObject* pObject = (CObject*)FindObject(obj.id);
        
if(!pObject)
        {
            KLAssert(
false && "Careobject error find!");
            
continue;
        }

        // 计算目前的距离
        FLOAT fDistance = KLU_GetDist(    fVector2(GetMySelf()->GetPosition().x,    GetMySelf()->GetPosition().z),
                                        fVector2(pObject
->GetPosition().x,        pObject->GetPosition().z));

        float fStep = abs(fDistance-obj.fLastDistance);
        
if(fStep > 0.001)
        {
            
// 距离发生改变,产生事件
            std::vector< STRING > vParam;
            CHAR szTemp[MAX_PATH];

            _snprintf(szTemp, MAX_PATH, "%d", pObject->GetID());
            vParam.push_back(szTemp);

            vParam.push_back("distance");

            _snprintf(szTemp, MAX_PATH, "%.3f", fDistance);
            vParam.push_back(szTemp);

            CEventSystem::GetMe()->PushEvent(GE_OBJECT_CARED_EVENT, vParam);
        }

        obj.fLastDistance = fDistance;
    }

    // 加载队列工作
    if(m_pLoadQueue)
    {
        m_pLoadQueue
->Tick();
    }

    // 删除队列
    if(m_pDestoryQueue)
    {
        m_pDestoryQueue
->Tick();
    }
}

 

 

4 事件触发通过event实现,具体以后再分析

5 lua响应,主要是关闭界面

 

    elseif (event == "OBJECT_CARED_EVENT") then
        
if(tonumber(arg0) ~= objCared) then
            
return;
        end

        --如果和NPC的距离大于一定距离或者被删除,自动关闭
        
if( arg1 == "distance" and tonumber(arg2)>MAX_OBJ_DISTANCE or arg1=="destroy" ) then
--            if( arg1 == "destroy" ) then
                        ContexMenu_HideAll();
                        
this:Hide();
                        
--取消关心
                        
this:CareObject( objCared, 0"ContexMenu" );
                end

        elseif( event == "COLSE_SECOND_MENU" )  then
                
ifthis:IsVisible() )then
                        ContexMenu_HideAll();
                        
this:Hide(); 
                end
    
        elseif( 
event == "PK_MODE_CHANGED" ) then
                tempPKMode 
= Player:GetCurrentPKMode();
                
if tempPKMode ~= currentPKMode then
                        currentPKMode 
= tempPKMode;
                        PushDebugMessage(PKModeName[currentPKMode]);
                end
        
        elseif( 
event == "ALLOCATION_MODE_CHANGED" ) then
             tempAcMode 
=  tonumber(arg0);
         
if tempAcMode ~= currentAlloCationMode then
                 currentAlloCationMode 
= tempAcMode;
            
         end

  end

 

抱歉!评论已关闭.