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 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