0


lua 游戏架构 之 游戏 AI (七)ai_dead

定义一个名为ai_dead的类,继承自ai_base类。这个类用于处理游戏中AI在死亡状态下的行为逻辑。以下是对代码的具体解释:

  1. 引入基类

    • 使用require函数引入ai_base类,作为基础类。
  2. 定义ai_dead

    • 使用class关键字定义了ai_dead类,并继承自BASE(即ai_base)。
  3. **构造函数 (ctor)**:

    • 构造函数接受一个entity参数,并设置_type属性为eAType_DEAD,表示死亡的行为。
  4. IsValid 方法

    • 这个方法用于验证AI是否应该处于死亡状态。它首先调用基类的IsValid方法,然后检查实体是否死亡。
  5. OnEnter 方法

  •  - 当AI组件进入激活状态时执行。如果基类的`OnEnter`方法返回`true`,则执行以下操作:
    
  •  - 重置`_fadeOut`和`_slowMotion`标志。
    
  •  - 检查并重置玩家的自动普通攻击状态。
    
  •  - 隐藏实体的称号节点。
    
  •  - 检查并重置玩家的超级模式状态。
    
  •  - 检查并重置骑乘状态。
    
  •  - 如果实体不是宠物或技能类型,播放死亡动作列表。
    
  •  - 锁定实体动画。
    
  •  - 处理同步RPC和发送死亡命令。
    
  •  - 处理玩家死亡后的界面逻辑,如复活界面和宠物状态。
    
  •  - 清理死亡实体的仇恨列表和战斗时间。
    
  1. OnLeave 方法: 当AI组件离开激活状态时执行。如果基类的OnLeave方法返回true,则解锁实体动画。

  2. OnLogic 方法: 逻辑更新方法。如果基类的OnLogic方法返回true,则根据时间间隔处理死亡逻辑,如淡出效果、实体销毁等。

  3. 创建组件函数create_component函数用于创建ai_dead类的新实例,传入一个实体和一个优先级。

代码中的一些关键点:

    • IsDead():检查实体是否死亡。
    • ShowTitleNode():显示或隐藏实体的称号节点。
    • SuperMode():处理玩家的超级模式。
    • OnRideMode():处理玩家的骑乘模式。
    • PlayActionList():播放一系列动作。
    • LockAni():锁定实体的动画。
    • Show():控制实体的显示与隐藏。
    • Destory():销毁实体。
    • CanRelease():检查实体是否可以释放。

OnEnter 方法的逻辑流程:

    • 调用基类的OnEnter方法,如果返回true,则继续。
    • 重置相关动画和攻击状态。
    • 隐藏称号节点。
    • 检查并重置超级模式和骑乘状态。
    • 播放死亡动作列表并锁定动画。
    • 发送死亡同步命令和处理复活界面逻辑。
    • 清理仇恨列表和战斗时间。

OnLogic 方法中,根据时间间隔处理死亡后的逻辑,如:

    • 如果实体存活时间超过4秒,并且可以释放,则销毁实体。
    • 如果实体存活时间超过2秒,并且可以释放,则开始淡出效果。

整体而言,ai_dead类的目的是在AI实体死亡时,提供一套标准的行为和逻辑处理,确保游戏内死亡状态的表现和交互符合预期。


local require = require

local BASE = require("logic/entity/ai/ai_base").ai_base;

------------------------------------------------------
ai_dead = class("ai_dead", BASE);
function ai_dead:ctor(entity)
    self._type = eAType_DEAD;
end

function ai_dead:IsValid()
    if not BASE.IsValid(self) then return false; end

    return self._entity:IsDead();
end

function ai_dead:OnEnter()
    if BASE.OnEnter(self) then
        self._fadeOut    = false;
        self._slowMotion= false;

        local logic = game_get_logic();
        if logic then
            local player = logic:GetPlayer();
            if player and player:GetHero() then
                local hero = player:GetHero();
                if hero then
                    if hero._autonormalattack then
                        if hero._guid == self._entity._guid then
                            hero._preautonormalattack = false;
                            hero._autonormalattack = false;
                        elseif self._entity._selected == self._entity._guid then
                            hero._preautonormalattack = false;
                            hero._autonormalattack = false;
                        elseif hero._follow then
                            if hero._follow._guid == self._entity._guid then
                                hero._preautonormalattack = false;
                                hero._autonormalattack = false;
                            end
                        end
                    end
                    
                end
            end
        end
        self._entity:ShowTitleNode(false);
        if self._entity:GetEntityType() == eET_Player then
            --清神兵状态
            if self._entity._superMode.valid then
                local hero = game_get_player_hero()
                if self._entity:IsPlayer() then
                    self._entity:SuperMode(false)
                else
                    self._entity:OnSuperMode(false)
                end
            end
            if self._entity:IsPlayer() then
                g_game_context:ResetLeadMode()
                local animation = g_game_context:GetSelectWeaponMaxAnimation()
                if animation then
                    g_game_context:OnStuntAnimationChangeHandler(animation,false)
                end
            end
            --清骑乘
            local world = game_get_world()
            if world and not world._syncRpc then
                if self._entity:IsOnRide() then
                    self._entity:OnRideMode(false, true)
                end
            end
            if self._entity._DIYSkill then
                self._entity._DIYSkill:OnReset();
            end
                
        end
        if self._entity:GetEntityType() ~= eET_Pet and self._entity:GetEntityType() ~= eET_Skill then
            local alist = {}
            table.insert(alist, {actionName = db_common.engine.defaultDeadAction, actloopTimes = 1})
            table.insert(alist, {actionName = db_common.engine.defaultDeadLoopAction, actloopTimes = -1})
            self._entity:PlayActionList(alist, 1);
        end
        self._entity:LockAni(true);

        local logic = game_get_logic();
        if logic then
            local world = logic:GetWorld();
            if world then
                local syncRpc = world._syncRpc;
                if not syncRpc then
                    -- send cmd
                    local entity = self._entity;
                    if entity and entity:GetEntityType() == eET_Monster and entity._spawnID > 0 then
                        local weaponID = g_game_context:IsInSuperMode() and 1 or 0
                        local damageRank = g_game_context:GetMapCopyDamageRank()
                        local args = { spawnPointID = entity._spawnID , pos = entity._curPos, weaponID = weaponID, damageRank = damageRank}
                        sbean.sync_privatemap_kill(args)
                    end
                    local hero = game_get_player_hero()
                    if hero then
                        hero:RemoveSummoned();
                    end
                end
            end
        end

        if self._entity:GetEntityType() == eET_Player then
            if logic then
                local player = logic:GetPlayer()
                local hero = nil
                if player then
                    hero = player:GetHero()
                end
                local logic = game_get_logic();
                local world = logic:GetWorld()
                local PetCount = player:GetPetCount()
                for i = 1,tonumber(PetCount) do
                    local Pet = player:GetPet(i)
                    Pet:OnDead()
                end
                if g_db.db_get_is_open_revive_ui() then    
                    if hero._guid == self._entity._guid then
                        if hero._killerId and hero._killerId < 0 then
                            --天雷复活界面
                            local killerID = math.abs(hero._killerId);
                            local guid = string.split(hero._guid, "|")
                            local playerId = tonumber(guid[2])
                            if killerID == playerId then
                                g_ui_mgr:OpenUI(eUIID_PlayerRevive)
                                g_ui_mgr:RefreshUI(eUIID_PlayerRevive, true)
                            end
                        else
                            g_logic:OpenReviveUI()
                        end
                        --log("eUIID_PlayerRevive")
                        local MercenaryCount = player:GetMercenaryCount();
                        for i = 1,tonumber(MercenaryCount) do
                            local Mercenary = player:GetMercenary(i)
                            Mercenary:OnDead()
                        end
                    end
                else
                    if hero._guid == self._entity._guid and (game_get_map_type() == g_ARENA_SOLO or game_get_map_type() == g_TAOIST) then
                        g_game_context:SetAutoFight(false)
                        local MercenaryCount = player:GetMercenaryCount();
                        for i = 1,tonumber(MercenaryCount) do
                            local Mercenary = player:GetMercenary(i)
                            if not Mercenary:IsDead() then
                                local camera = logic:GetMainCamera()
                                hero:DetachCamera()
                                Mercenary:AttachCamera(camera);
                                camera:UpdatePos(Mercenary._curPosE);
                                break;
                            end
                        end
                    end
                end
                if world and not world._syncRpc then
                    self._entity:ClsHorseAi();
                end
            end
        end

        if self._entity._forceAttackTarget then
            self._entity._forceAttackTarget = nil;
        end

        if self._entity:GetEntityType() == eET_Mercenary then
            self._entity._deadTimeLine = g_get_GMTtime(game_get_time())
            if logic then
                local player = logic:GetPlayer()
                local hero = nil
                if player then
                    hero = player:GetHero()
                end
                local logic = game_get_logic();
                local world = logic:GetWorld()
                if world._fightmap then
                    if hero:IsDead() and (game_get_map_type() == g_ARENA_SOLO or game_get_map_type() == g_TAOIST) then
                        local guid1 = string.split(hero._guid, "_")
                        local guid2 = string.split(self._entity._guid, "_")    
                        if tonumber(guid1[2]) == tonumber(guid2[3]) then
                            local MercenaryCount = player:GetMercenaryCount();
                            for i = 1,tonumber(MercenaryCount) do
                                local Mercenary = player:GetMercenary(i)
                                if not Mercenary:IsDead() then
                                    local camera = logic:GetMainCamera()
                                    self._entity:DetachCamera()
                                    Mercenary:AttachCamera(camera);
                                    camera:UpdatePos(Mercenary._curPosE);
                                    break;
                                end
                            end
                        end
                    end
                end
            end
            self._entity:ClsEnmities();
        end
        if self._entity:GetEntityType() == eET_Player or self._entity:GetEntityType() == eET_Mercenary then
            self._entity:ClearFightTime();
        end
        if self._entity:GetEntityType() ~= eET_Player and self._entity:GetEntityType() ~= eET_Mercenary then
            --self._entity:SetHittable(false);
        end
        if self._entity:GetEntityType() == eET_Pet then
            local world = game_get_world();
            local player = game_get_player()
            if world and not world._syncRpc then
                if self._entity._hoster then
                    local curFightSP = self._entity._hoster:GetFightSp()
                    self._entity._hoster:UpdateFightSpCanYing(curFightSP - 1)
                    local index = player:GetPetIdx(self._entity._guid)
                    if index > 0  then
                        player:RmvPet(index)
                    end
                end
            end
        end
        return true;
    end

    return false;
end

function ai_dead:OnLeave()
    if BASE.OnLeave(self) then
        self._entity:LockAni(false);

        return true;
    end

    return false;
end

function ai_dead:OnLogic(dTick)
    if BASE.OnLogic(self, dTick) then
        if dTick > 0 then
            if self._timeTick > 4000 then
                if self._entity:CanRelease() then
                    self._entity:Destory()
                end
            elseif self._timeTick > 2000 then
                if self._entity:CanRelease() then
                    if not self._fadeOut then
                        self._fadeOut = true;

                        self._entity:Show(false, true, 2000);
                    end
                end
            end
            if self._entity:GetEntityType() == eET_Pet or self._entity:GetEntityType() == eET_Skill then
                if self._entity:CanRelease() then
                    self._entity:Destory()
                end
            end
        end

        return true;
    end

    return false;
end

function create_component(entity, priority)
    return ai_dead.new(entity, priority);
end

本文转载自: https://blog.csdn.net/heyuchang666/article/details/140678800
版权归原作者 heyuchang666 所有, 如有侵权,请联系我们删除。

“lua 游戏架构 之 游戏 AI (七)ai_dead”的评论:

还没有评论