c1_lua/lua/app/ui/idle/component/idle_unit_comp.lua
2023-05-26 15:46:15 +08:00

376 lines
9.6 KiB
Lua

local IdleUnitComp = class("BattleUnitComp", LuaComponent)
local UNIT_STATE_INIT = 0
local UNIT_STATE_IDLE = 1
local UNIT_STATE_ATTACK = 2
local UNIT_STATE_DEAD = 3
local UNIT_STATE_BORN = 4
local ATTACK_COUNT = 4 -- 写死攻击4次
local INIT_POS_X = 150
local UNIT_FRONT_POS_X = 0
local MOVE_SPEED = 2000 -- 战斗单位攻击时的移动速度
function IdleUnitComp:ctor()
end
function IdleUnitComp:init()
self.isPlayHurt = 0
self.body = self.baseObject:getChildByName("body")
self.currState = UNIT_STATE_INIT
self.isClear = false
end
function IdleUnitComp:initSkills(skillIds)
self.normalSkills = {}
local skillCfg = ConfigManager:getConfig("skill")
if skillIds then
for k, v in ipairs(skillIds) do
if skillCfg[v] then
table.insert(self.normalSkills, skillCfg[v])
end
end
end
end
function IdleUnitComp:getModelId()
return self.modelId
end
function IdleUnitComp:setActive(isActive)
self.baseObject:setActive(isActive)
end
function IdleUnitComp:setTarget(target)
self.target = target
end
function IdleUnitComp:prepare(side, modelId)
self.side = side
self.modelId = modelId
self:initPosition()
end
function IdleUnitComp:initPosition()
if self.side == 1 then
self.baseObject:setLocalPosition(-INIT_POS_X, 0, 0)
self.body:setLocalScaleX(1)
self.direction = 1
else
self.baseObject:setLocalPosition(INIT_POS_X, 0, 0)
self.body:setLocalScaleX(-1)
self.direction = -1
end
end
function IdleUnitComp:playAnimation(name, loop, forceRefresh)
if name == GConst.BattleConst.SPINE_ANIMATION_NAME.HIT then
self.isPlayHurt = 1
else
self.isPlayHurt = 0
end
self.baseObject:playAnimation(name, loop, forceRefresh)
end
function IdleUnitComp:playBorn()
self.isPlayHurt = 0
self.currState = UNIT_STATE_INIT
self.isClear = false
if self.side == 1 then
self:changeState(UNIT_STATE_IDLE)
else
self:changeState(UNIT_STATE_BORN)
end
end
function IdleUnitComp:updateBorn(dt)
self.waitTime = self.waitTime - dt
if self.waitTime < 0 then
self:changeState(UNIT_STATE_IDLE)
end
end
function IdleUnitComp:enterBornState()
self.waitTime = self:getAnimationDuration(GConst.BattleConst.SPINE_ANIMATION_NAME.BORN)
self:playAnimation(GConst.BattleConst.SPINE_ANIMATION_NAME.BORN, false, false)
end
function IdleUnitComp:changeState(state)
if self.currState == state and not self:repeatCurrState() then
return false
end
if self.currState == UNIT_STATE_DEAD then -- 死亡后只能去死亡状态
if state ~= UNIT_STATE_DEAD then
return false
end
end
-- 离开当前状态
-- if self.currState == UNIT_STATE_IDLE then
-- elseif self.currState == UNIT_STATE_ATTACK then
-- elseif self.currState == UNIT_STATE_DEAD then
-- end
-- 进入目标状态
self.currState = state
if state == UNIT_STATE_IDLE then
self:enterIdleState()
elseif state == UNIT_STATE_ATTACK then
self:enterAttackState()
elseif state == UNIT_STATE_DEAD then
self:enterDeadState()
elseif state == UNIT_STATE_BORN then
self:enterBornState()
end
return true
end
function IdleUnitComp:repeatCurrState()
if self.currState == UNIT_STATE_ATTACK then
return true
end
return false
end
function IdleUnitComp:playHurt()
self.hurtTime = 0
if self.currHitDuration == nil then
self.currHitDuration = self:getAnimationDuration(GConst.BattleConst.SPINE_ANIMATION_NAME.HIT)
end
self:playAnimation(GConst.BattleConst.SPINE_ANIMATION_NAME.HIT, false, false)
end
function IdleUnitComp:updateHurt(dt)
if self.isPlayHurt == 0 then
return
end
if self.isPlayHurt == 1 then
self.hurtTime = self.hurtTime + dt
if self.hurtTime >= self.currHitDuration then
self:playAnimation(GConst.BattleConst.SPINE_ANIMATION_NAME.IDLE, true, false)
self.isPlayHurt = 0
end
end
end
function IdleUnitComp:updateIdle(dt)
self:updateHurt(dt)
end
function IdleUnitComp:enterIdleState()
self:playAnimation(GConst.BattleConst.SPINE_ANIMATION_NAME.IDLE, true, false)
end
function IdleUnitComp:doAttack(callback)
self.baseObject:getTransform():SetAsLastSibling()
self.actionOverCallback = callback
self.attackCount = ATTACK_COUNT
self:changeState(UNIT_STATE_ATTACK)
end
function IdleUnitComp:enterAttackState()
self.attackOver = false
self.attackTime = 0
local skillInfo = self:getNormalSkill(true)
if skillInfo.skill_position == GConst.BattleConst.SKILL_MOVE_TYPE.MOVE then
self.isMove = true
self:playAnimation(GConst.BattleConst.SPINE_ANIMATION_NAME.MOVE, true, false)
self.positionX = self.baseObject:fastGetLocalPosition()
if self.side == 1 then
self.targetX = UNIT_FRONT_POS_X
self.moveDirection = 1
else
self.targetX = -UNIT_FRONT_POS_X
self.moveDirection = -1
end
else
self.isMove = false
local attackName = skillInfo.name_act
self.currAttackDuration = self:getAnimationDuration(attackName)
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
self:playAnimation(attackName, false, false)
end
end
function IdleUnitComp:updateAttack(dt)
if self.isMove then
local addX = dt*MOVE_SPEED*self.moveDirection
self.positionX = self.positionX + addX
if (self.moveDirection > 0 and self.positionX >= self.targetX) or (self.moveDirection < 0 and self.positionX <= self.targetX) then
self.isMove = false
self.positionX = self.targetX
if self.attackOver then -- 归位后该下一步了
self:onAttackOver()
else -- 到位置该攻击了
self:doNextAttack()
end
end
self.baseObject:setLocalPosition(self.positionX, 0, 0)
return
end
self.attackTime = self.attackTime + dt
if self.attackTime >= self.currAttackDuration then
self.attackOver = true
self.attackCount = self.attackCount - 1
if self.attackCount <= 0 then
local skillInfo = self:getNormalSkill()
if skillInfo.skill_position == GConst.BattleConst.SKILL_MOVE_TYPE.MOVE then
self:moveBackToInitPosition()
else
self:onAttackOver()
end
return
else -- 继续攻击
self:doNextAttack()
end
else
if self.currAttackKeyTime > 0 and self.attackTime >= self.currAttackKeyTime then
self.currAttackKeyTime = 0
if self.attackCount == 1 then -- 最后一次攻击的话对方该死了
self.target:changeState(UNIT_STATE_DEAD)
else
self.target:playHurt()
end
end
end
end
function IdleUnitComp:moveBackToInitPosition()
self.isMove = true
self:playAnimation(GConst.BattleConst.SPINE_ANIMATION_NAME.MOVE, true, false)
self.positionX = self.baseObject:fastGetLocalPosition()
if self.side == 1 then
self.targetX = -INIT_POS_X
self.moveDirection = -1
else
self.targetX = INIT_POS_X
self.moveDirection = 1
end
end
function IdleUnitComp:doNextAttack()
self.attackTime = 0
local skillInfo = self:getNormalSkill(true)
local attackName = skillInfo.name_act
self.currAttackDuration = self:getAnimationDuration(attackName)
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
self:playAnimation(attackName, false, false)
end
function IdleUnitComp:onAttackOver()
self:changeState(UNIT_STATE_IDLE)
local callback = self.actionOverCallback
self.actionOverCallback = nil
if callback then
callback()
end
end
function IdleUnitComp:getAnimationDuration(aniName)
if self.attackDurationMap == nil then
self.attackDurationMap = {}
end
local duration = self.attackDurationMap[aniName]
if duration == nil then
duration = self.baseObject:getAnimationDuration(aniName)
self.attackDurationMap[aniName] = duration
end
return duration or 0
end
function IdleUnitComp:getAnimationKeyFrameTime(animationName, index)
index = index or 1
if self.attackKeyFrameTimeMap == nil then
self.attackKeyFrameTimeMap = {}
end
local timeList = self.attackKeyFrameTimeMap[animationName]
if timeList == nil then
local timeList = self.baseObject:getAnimationKeyFrameTimes(animationName)
if not timeList[1] then
table.insert(timeList, 0.3)
end
self.attackKeyFrameTimeMap[animationName] = timeList
end
return timeList[index] or 0.3
end
function IdleUnitComp:getNormalSkill(reRandom)
if self.normalSkills == nil then
return nil
end
if not reRandom then
return self.normalSkill
end
if self.normalSkillIndex == nil then
self.normalSkillIndex = math.random(1, #self.normalSkills)
else
local temp = self.normalSkills[#self.normalSkills]
self.normalSkills[#self.normalSkills] = self.normalSkills[self.normalSkillIndex]
self.normalSkills[self.normalSkillIndex] = temp
self.normalSkillIndex = math.random(1, #self.normalSkills - 1)
end
self.normalSkill = self.normalSkills[self.normalSkillIndex]
return self.normalSkill
end
function IdleUnitComp:getBornTime()
return self:getAnimationDuration(GConst.BattleConst.SPINE_ANIMATION_NAME.BORN)
end
function IdleUnitComp:playDead(callback)
if self.isClear then
if callback then
callback()
end
return
end
self.deadOverCallback = callback
self:changeState(UNIT_STATE_DEAD)
end
function IdleUnitComp:enterDeadState()
local aniName = GConst.BattleConst.SPINE_ANIMATION_NAME.DEAD
self.deadTime = self:getAnimationDuration(aniName) + 0.1
self:playAnimation(aniName, false, false)
end
function IdleUnitComp:updateDead(dt)
self.deadTime = self.deadTime - dt
if self.deadTime <= 0 then
self:clear()
if self.deadOverCallback then
local callback = self.deadOverCallback
self.deadOverCallback = nil
callback()
end
end
end
function IdleUnitComp:clear()
if self.isClear then
return
end
self.isClear = true
end
function IdleUnitComp:tick(dt)
if self.isClear then
return
end
if self.currState == UNIT_STATE_DEAD then
self:updateDead(dt)
return
end
if self.currState == UNIT_STATE_IDLE then
self:updateIdle(dt)
return
end
if self.currState == UNIT_STATE_ATTACK then
self:updateAttack(dt)
elseif self.currState == UNIT_STATE_BORN then
self:updateBorn(dt)
end
end
function IdleUnitComp:destroy()
self.baseObject:destroy()
end
return IdleUnitComp