c1_lua/lua/app/module/battle/component/battle_unit_comp.lua
2023-04-12 23:10:22 +08:00

262 lines
7.1 KiB
Lua

local BattleConst = require "app/module/battle/battle_const"
local BattleUnitComp = class("BattleUnitComp", LuaComponent)
local UNIT_STATE = BattleConst.UNIT_STATE
local SIDE_ATK = BattleConst.SIDE_ATK
local SPINE_ANIMATION_NAME = BattleConst.SPINE_ANIMATION_NAME
function BattleUnitComp:ctor()
end
function BattleUnitComp:initPosition()
if self.unitEntity:getSide() == SIDE_ATK then
self.baseObject:setLocalPosition(-BattleConst.INIT_POS_X, 0, 0)
self.body:setLocalScaleX(1)
self.direction = 1
else
self.baseObject:setLocalPosition(BattleConst.INIT_POS_X, 0, 0)
self.body:setLocalScaleX(-1)
self.direction = -1
end
end
function BattleUnitComp:playBorn()
self:playAnimation(SPINE_ANIMATION_NAME.IDLE, true, false)
end
function BattleUnitComp:_initBase()
self.isClear = false
self.isDead = false
self.isMove = false
self.attackTime = 0
self.currAttackDuration = 0
self.currAttackKeyTime = 0
self.isPlayHurt = 0
self.attackDurationMap = {}
self.currState = UNIT_STATE.INIT
end
function BattleUnitComp:initWithEntity(modelId, entity, battleController, target)
self.modelId = modelId
self.unitEntity = entity
self.battleController = battleController
self.target = target
self.body = self.baseObject:getChildByName("body")
self.side = entity:getSide()
self:_initBase()
self:initPosition()
self:playBorn()
end
function BattleUnitComp:hideOutsideScreen()
if self.unitEntity:getSide() == SIDE_ATK then
self.baseObject:setLocalPosition(-GConst.UI_SCREEN_WIDTH/2 - BattleConst.UNIT_BODY_WIDTH, 0, 0)
else
self.baseObject:setLocalPosition(GConst.UI_SCREEN_WIDTH/2 + BattleConst.UNIT_BODY_WIDTH, 0, 0)
end
end
function BattleUnitComp:playAnimation(name, loop, forceRefresh)
self.currAnimationName = name
self.baseObject:playAnimation(name, loop, forceRefresh)
end
function BattleUnitComp:getAnimationDuration(aniName)
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 BattleUnitComp:useNormalSkill(count, callback)
self.actionOverCallback = callback
self.normalSkillCount = count
if not self:changeState(UNIT_STATE.NORMAL_ATTACK) then
self.actionOverCallback = nil
callback()
end
end
function BattleUnitComp:changeState(state)
if self.currState == state and not self:repeatCurrState() then
return false
end
if self.isDead then -- 死亡后只能去死亡状态
if state ~= UNIT_STATE.DEAD then
return false
end
end
-- 离开当前状态
if self.currState == UNIT_STATE.IDLE then
self:exitIdleState()
elseif self.currState == UNIT_STATE.NORMAL_ATTACK then
self:exitNormalAttackState()
elseif self.currState == UNIT_STATE.SKILL then
self:exitSkillState()
elseif self.currState == UNIT_STATE.DEAD then
self:exitDeadState()
end
-- 进入目标状态
self.currState = state
if state == UNIT_STATE.IDLE then
self:enterIdleState()
elseif state == UNIT_STATE.NORMAL_ATTACK then
self:enterNormalAttackState()
elseif state == UNIT_STATE.SKILL then
self:enterSkillState()
elseif state == UNIT_STATE.DEAD then
self:enterDeadState()
elseif self.currState == UNIT_STATE.BORN then
self:enterBornState()
end
return true
end
function BattleUnitComp:repeatCurrState()
if self.currState == UNIT_STATE.IDLE then
return false
elseif self.currState == UNIT_STATE.NORMAL_ATTACK then
return true
elseif self.currState == UNIT_STATE.SKILL then
return true
elseif self.currState == UNIT_STATE.DEAD then
return false
end
return false
end
function BattleUnitComp:exitIdleState()
end
function BattleUnitComp:enterIdleState()
self:playAnimation(SPINE_ANIMATION_NAME.IDLE, true, false)
end
function BattleUnitComp:updateIdle(dt)
self:updateHurt(dt)
end
function BattleUnitComp: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(SPINE_ANIMATION_NAME.IDLE, true, false)
self.isPlayHurt = 0
end
elseif self.isPlayHurt == 2 then
self.hurtTime = self.hurtTime + dt
if self.hurtTime >= self.currHitGroundDuration then
self.isPlayHurt = 0
end
end
end
function BattleUnitComp:enterNormalAttackState()
self.attackOver = false
self.attackTime = 0
self.currAttackKeyTime = 0.1
local skill = self.unitEntity:getNormalSkill()
if skill:getMoveType() == BattleConst.SKILL_MOVE_TYPE.MOVE then
self.isMove = true
self.positionX = self.baseObject:fastGetLocalPosition()
if self.side == BattleConst.SIDE_ATK then
self.targetX = BattleConst.UNIT_FRONT_POS_X
self.moveDirection = 1
else
self.targetX = -BattleConst.UNIT_FRONT_POS_X
self.moveDirection = -1
end
else
self.isMove = false
local attackName = skill:getRandomNormalAttackName()
self.currAttackDuration = self:getAnimationDuration(attackName)
self:playAnimation(attackName, false, false)
end
end
function BattleUnitComp:exitNormalAttackState()
end
function BattleUnitComp:updateNormalAttack(dt)
if self.isMove then
local addX = dt*BattleConst.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:changeState(UNIT_STATE.IDLE)
local callback = self.actionOverCallback
self.actionOverCallback = nil
if callback then
callback()
end
else -- 到位置该攻击了
self:playAnimation(SPINE_ANIMATION_NAME.ATTACK, false, false)
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.normalSkillCount = self.normalSkillCount - 1
if self.normalSkillCount <= 0 then
local skill = self.unitEntity:getNormalSkill()
if skill:getMoveType() == BattleConst.SKILL_MOVE_TYPE.MOVE then
self.isMove = true
self.positionX = self.baseObject:fastGetLocalPosition()
if self.side == BattleConst.SIDE_ATK then
self.targetX = -BattleConst.INIT_POS_X
self.moveDirection = -1
else
self.targetX = BattleConst.INIT_POS_X
self.moveDirection = 1
end
else
self:changeState(UNIT_STATE.IDLE)
local callback = self.actionOverCallback
self.actionOverCallback = nil
if callback then
callback()
end
end
return
else -- 继续攻击
self.attackTime = 0
self:playAnimation(SPINE_ANIMATION_NAME.ATTACK, false, false)
end
end
if self.currAttackKeyTime > 0 and self.attackTime >= self.currAttackKeyTime then -- 到达关键后使用
self.currAttackKeyTime = self.currAttackDuration
end
end
function BattleUnitComp:tick(dt)
if self.isClear then
return
end
if self.isDead then
self:updateDead(dt)
return
end
if self.currState == UNIT_STATE.IDLE then
self:updateIdle(dt)
return
end
if self.currState == UNIT_STATE.NORMAL_ATTACK then
self:updateNormalAttack(dt)
elseif self.currState == UNIT_STATE.SKILL then
self:updateSkill(dt)
end
end
return BattleUnitComp