--- 执行关卡地图图标事件 --- Generated by EmmyLua(https://github.com/EmmyLua) --- Created by aaa. --- DateTime: 2019/10/18 18:23 --- local this = {} local mapIconConfig = ConfigManager.GetConfig(ConfigName.MainMapIconConfig) --- 执行完行为后的回调 local actionCallBack = nil --- 是否界面已经关闭 local panelIsClose = false -- 角色当前的位置信息 local m_roleCurPos local m_selectPointPos = 0 local m_parent -- 默认0是没有buff,1是攻击buff 2是防御buff local m_isHaveBuff = 0 -- 当前Buff创建的buff应该存在的时间 local m_buffStayStep = 0 -- 是不是单纯的屁话 local simpleTalk = true --- 配置定义 -- 角色对话气泡位置 local m_roleTextPos = { [3] = {pos = Vector3.New(172, 200, 0), angleOffset = 180}, -- 角色朝左, 气泡在右 [4] = {pos = Vector3.New(-177, 204, 0), angleOffset = 0} -- 反之 } -- 老头对话气泡位置 local m_oldManTextPos = { [3] = {pos = Vector3.New(-176, 130, 0), angleOffset = 0}, -- 角色朝左,气泡在左 [4] = {pos = Vector3.New(154, 130, 0), angleOffset = 180} -- 反之 } -- buff提示图片 local buffTipImg = { -- 攻击提升 [1] = { [1] = "r_guanka_baojitisheng", [2] = "r_guanka_baoshangtisheng", [3] = "r_guanka_gongjitisheng", }, -- 防御加强 [2] = { [1] = "r_guanka_hujiatisheng", [2] = "r_guanka_mokangtisheng", }, } -- 角色移动速度 local m_moveSpeed = 0.4 -- 打击速度 local m_hitSpeed = 0.15 -- 飘血资源 local hurtRes = "FloatingText" --- 从父对象注册需要的组件 function this.InitRegisterComponent(parent) panelIsClose = false m_parent = nil m_parent = parent --this.isBeginFight = false -- 加载初始化资源 -- 初始化3个伤害字体 this.hurtNum = {} for i = 1, 3 do this.hurtNum[i] = poolManager:LoadAsset(hurtRes, PoolManager.AssetType.GameObject) -- 设置父级 this.hurtNum[i].transform:SetParent(m_parent.effectRoot.transform) this.hurtNum[i].transform.localScale = Vector3.New(0.5, 0.5, 0.5) Util.GetGameObject(this.hurtNum[i], "anim"):GetComponent("Canvas").sortingOrder = m_parent.GetCurLayer() this.hurtNum[i]:SetActive(false) end this.SetActionSpeed(1, 1) this.public_EndDialogue() end -- 设置暴击文字层级 function this:OnSortingOrderChange(parentSort) if #this.hurtNum > 0 then -- 初始化完成 for i = 1, 3 do Util.GetGameObject(this.hurtNum[i], "anim"):GetComponent("Canvas").sortingOrder = parentSort end end end -------------------- 事件的对外接口函数 ----------------- --- 遇见一个宝箱 --- @parame iconType 图标类型 --- @parame roleFaceDir 角色朝向 function this.public_MeGetBaby(iconType, roleFaceDir, point, func, isSelf) actionCallBack = nil if func then actionCallBack = func end if isSelf then simpleTalk = true -- 对话次数 local talktimes = 1 this.private_SetDialogueBoxDir(roleFaceDir, point, false) this.private_StartBB(talktimes, iconType, point) else if actionCallBack then actionCallBack() end end end --- 遇见一个老大爷 --- @parame iconType 图标类型 --- @parame roleFaceDir 角色朝向 function this.public_MeetYourGrandPa(iconType, roleFaceDir, point, func, isSelf) actionCallBack = nil if func then actionCallBack = func end if isSelf then simpleTalk = true -- 对话次数 local talktimes = 3 this.private_SetDialogueBoxDir(roleFaceDir, point, true) this.private_StartBB(talktimes, iconType, point) else if actionCallBack then actionCallBack() end end end --- 进入战斗 ----@param battleTimes 战斗次数 ----@param roleCurPosInfo 角色当前的位置信息 function this.public_SetBattleTimes(point, roleFaceDir, battleTimes, roleCurPosInfo, selectPointPos, func) actionCallBack = nil if func then actionCallBack = func end m_roleCurPos = nil if roleCurPosInfo then m_roleCurPos = roleCurPosInfo end m_selectPointPos = 0 if selectPointPos then m_selectPointPos = selectPointPos end -- 开始战斗 this.private_StartBattle(point, roleFaceDir, battleTimes) end --- 加点血 function this.public_GiveMeMilk(iconType, point, roleFaceDir, selectPointPos, func) actionCallBack = nil if func then actionCallBack = func end m_roleCurPos = nil m_selectPointPos = 0 if selectPointPos then m_selectPointPos = selectPointPos end simpleTalk = false --this.private_StartBB(2, iconType, point) this.private_DrinkSomeMilk(iconType, point, roleFaceDir) end -- 显示一个buff, 管他是个什么锤子 function this.public_GetBuff(iconType, func) actionCallBack = nil if func then actionCallBack = func end if mapIconConfig[iconType].Steps and mapIconConfig[iconType].Steps > 0 then m_buffStayStep = mapIconConfig[iconType].Steps else Log("搞笑呢,这数据都没有!") end local buffType = iconType == 14 and 1 or 2 this.showBuffTimer = nil this.showBuffTimer = Timer.New(function () if panelIsClose then return end this.private_CreateBuff(buffType) end, 1) this.showBuffTimer:Start() end --- 结束对话 function this.public_EndDialogue() this.private_SetDialogueText(false, " ") end -- 设置行动速度 function this.SetActionSpeed(moveSpeed, hitSpeed) m_moveSpeed = 0.4 / moveSpeed m_hitSpeed = 0.15 / hitSpeed end -- 获取移动速度 function this.GetRoleSpeed() return m_moveSpeed end -- 隐藏飘字 function this.public_HideEffect() for i = 1, 3 do this.hurtNum[i]:SetActive(false) end end -- 界面销毁时,可能还有方法在调用父对象的组件,注意判断 function this.public_DestroyRegisterComponent() panelIsClose = true -- 注销时钟 if this.talkTimer then this.talkTimer:Stop() end if this.callbackTimer then this.callbackTimer:Stop() end if this.hurtNumTimer then this.hurtNumTimer:Stop() end if this.showBuffTimer then this.showBuffTimer:Stop() end for i = 1, 3 do if this.hurtNum[i] then poolManager:UnLoadAsset(hurtRes, this.hurtNum[i], PoolManager.AssetType.GameObject) this.hurtNum[i] = nil end end this.talkTimer = nil this.callbackTimer = nil this.hurtNumTimer = nil this.showBuffTimer = nil -- 清空列表引用 this.hurtNum = {} m_isHaveBuff = 0 m_buffStayStep = 0 SoundManager.StopSoundByChannel(20) end -------------------------------------------------------- -------------------- 私有函数 -------------------------- ----- ============== 角色对话处理 ====================== --- 开始对话 --- @param leftTimes 剩余对话次数 --- @param iconType 图标类型 --- @param point 遇到的图标 function this.private_StartBB(leftTimes, iconType, point) if leftTimes > 0 then this.private_SetTalkObj(leftTimes, iconType, point, function () leftTimes = leftTimes - 1 this.private_StartBB(leftTimes, iconType, point) end) else -- 对话完执行回调 if actionCallBack then actionCallBack() end actionCallBack = nil return end end --- 这是对话时的气泡朝向 ----@param point 需要设置的事件点 ----@param isSetIcon 是否需要设置事件点 function this.private_SetDialogueBoxDir(roleFaceDir, point, isSetIcon) if panelIsClose then return end -- 设置角色, 值为4的时候是角色朝右 local index = roleFaceDir == 4 and 4 or 3 m_parent.dialogueRoot.transform.localEulerAngles = Vector3.New(0, m_roleTextPos[index].angleOffset, 0) m_parent.context.transform.localEulerAngles = Vector3.New(0, m_roleTextPos[index].angleOffset, 0) m_parent.dialogueRoot.transform.localPosition = m_roleTextPos[index].pos if isSetIcon then -- 设置老头 local oldManAngle = Vector3.New(0, m_oldManTextPos[index].angleOffset, 0) point:SetDialogueDir(m_oldManTextPos[index].pos, oldManAngle) point:ShowDialogue(false) end end --- 设置角色对话内容 function this.private_SetDialogueText(state, iconType) if panelIsClose then return end m_parent.dialogueRoot:SetActive(state) if state then PlayUIAnim(m_parent.dialogueRoot) m_parent.context.text = this.private_GetRoleTalkShit(iconType) end end --- 随机一份角色的对话内容 function this.private_GetRoleTalkShit(iconType) local contents = string.split(GetLanguageStrById(mapIconConfig[iconType].Desc), "#") local index = math.random(1, #contents) return contents[index] end --- 选择当前的说话对象 function this.private_SetTalkObj(leftTimes, iconType, point, func) local isMe = math.floor(leftTimes % 2) == 1 local damnOld = point damnOld:ShowDialogue(not isMe) this.private_SetDialogueText(isMe, iconType) if not isMe then -- 找找他该说啥 local contents = string.split(GetLanguageStrById(mapIconConfig[iconType].DescNPC), "#") local index = math.random(1, #contents) damnOld:SetDialogueStr(contents[index]) PlayUIAnim(damnOld.go) end if leftTimes > 1 then this.talkTimer = nil this.talkTimer = Timer.New(function () if not panelIsClose then if func then func() end end end, 0.8) this.talkTimer:Start() else if func then func() end end end --- ==================================================== --- ============ 战斗显示设置 =========================== --- 开始战斗 function this.private_StartBattle(point, roleFaceDir, battleTimes) if not panelIsClose then this.private_ShakeByTimes(point, roleFaceDir, battleTimes, 1) end end function this.private_ShakeByTimes(point, roleFaceDir, shakeTime, index) if panelIsClose then return end if point then local icon = point.go local start = index local iconType = point.iconId local leftNum = math.floor(start % 2) -- 主动打击者 local go = leftNum == 1 and m_parent.roleRoot or icon -- 受击对象 local hurtGo = leftNum ~= 1 and m_parent.roleRoot or Util.GetGameObject(icon, "root") local isReverse = leftNum == 0 local objPos = isReverse and m_roleCurPos.u * 256 + m_roleCurPos.v or m_selectPointPos local end_callBack = function() -- 受击结束动画 if panelIsClose then return end m_parent.hitEffect:SetActive(false) if start >= shakeTime then -- 执行最终回调 actionCallBack() return else start = start + 1 this.private_ShakeByTimes(point, roleFaceDir, shakeTime, start) end end local mid_callBack = function() -- 打击时间点 -- 泼血 this.private_BloodBlood(objPos, start, iconType, isReverse, 0) this.pravite_PlayHitEffect(objPos) if point then point:SetPointAnimation(iconType, 2) end --整个东西缩一下 this.PlayScale(hurtGo, 0.7) SoundManager.PlaySound(SoundConfig.Sound_FightArea_Attack[math.random(1, #SoundConfig.Sound_FightArea_Attack)]) end local func = function() this.pravite_ShakeObjOnce(go, isReverse, roleFaceDir, end_callBack, mid_callBack) end this.callbackTimer = nil this.callbackTimer = Timer.New(function () if not panelIsClose then func() end end, 0.2) this.callbackTimer:Start() end end -- 怪物被打得吐血 --- @param showType 参数为0时表示为掉血,参数大于0时表示为补血 function this.private_BloodBlood(objPos, index, iconType, isMonster, showType, func) if panelIsClose then return end local go = this.hurtNum[math.floor(index % 3 + 1)] -- 吐血随机值 local hurtNum, isCritical = this.pravite_GetHurtValue(isMonster, iconType, showType) local v2 = SetObjPosByUV(objPos) go:GetComponent("RectTransform").anchoredPosition3D = Vector3.New(v2.x, v2.y, 0) + Vector3.New(0, 120, 0) Util.GetGameObject(go, "anim/Image"):SetActive(false) Util.GetGameObject(go, "anim/anim"):GetComponent("Text").text = this.DecodeHurt(hurtNum, isCritical, showType) if not FightPointPassManager.isBeginFight then go:SetActive(true) else go:SetActive(false) end this.hurtNumTimer = nil this.hurtNumTimer = Timer.New(function() if panelIsClose then return end if go then go:SetActive(false) end if func then func() end end, 1.5) this.hurtNumTimer:Start() end -- 获取伤害值 --- @param hadFought 已经战斗的次数 function this.pravite_GetHurtValue(isMonster, iconType, showType) local hurtNum = 0 -- 计算是否有宝鸡 local isCritical = false if showType == 0 then -- 计算掉血量 -- 计算普伤 if isMonster then hurtNum = math.floor(math.random(100, mapIconConfig[iconType].HurtMax / 2)) else hurtNum = math.random(mapIconConfig[iconType].HurtMin, mapIconConfig[iconType].HurtMax) end -- 宝鸡概率 local forceRate = mapIconConfig[iconType].StrikeProbability / 100 local forceValue = (math.random(0, 0.8) + forceRate * math.random(0.5, 1)) + 0.2 isCritical = forceValue >= 1 hurtNum = isCritical and hurtNum * 2 or hurtNum else -- 计算补血量 hurtNum = math.random(mapIconConfig[iconType].HurtMin, mapIconConfig[iconType].HurtMax) end -- 是否有buff hurtNum = this.private_GetBuffGain(not isMonster, hurtNum) return hurtNum, isCritical end -- 解码显示伤害值 function this.DecodeHurt(hurtValue, iscritical, showType) -- 信息头 local color = 0 local offSet = 0 local text = "" if showType == 0 then if iscritical then -- 宝鸡 color = 0 -- text = text .. string.char(33) -- 暴击文字 else -- 普伤 color = 1 end offSet = 10 else color = 3 offSet = 11 end -- 数字 text = text .. string.char((color*2)+100 + offSet) -- 符号 local str = tostring(hurtValue) for i=1,#str do text = text..string.char((string.byte(str,i) - 48) + color*10 + 40) end return text end -- 受击特效 function this.pravite_PlayHitEffect(pos) if panelIsClose then return end --local u, v = Map_Pos2UV(pos) --local v2 = RectTransformUtility.WorldToScreenPoint(TileMapView.GetCamera(), TileMapView.GetLiveTilePos(u, v)) --v2 = v2 / math.min(Screen.width/1080, Screen.height/1920) m_parent.hitEffect.transform.localPosition = SetObjPosByUV(pos) if not FightPointPassManager.isBeginFight then m_parent.hitEffect:SetActive(true) else m_parent.hitEffect:SetActive(false) end end -- 震动动画 function this.pravite_ShakeObjOnce(go, isReverse, roleFaceDir, func, mid_func) if panelIsClose then func = nil mid_func = nil return end local offSet = isReverse and 90 or 120 offSet = offSet / math.min(Screen.width/1080, Screen.height/1920) local originPos = go:GetComponent("RectTransform").anchoredPosition local value = isReverse and -1 or 1 local targetPos = originPos + Vector2.New(offSet * roleFaceDir.x * value, offSet * roleFaceDir.y * value) if go then go:GetComponent("RectTransform"):DOAnchorPos(targetPos, m_hitSpeed, false):OnComplete(function () if panelIsClose then return end if mid_func then mid_func() end go:GetComponent("RectTransform"):DOAnchorPos(originPos, m_hitSpeed, false):OnComplete(function () if panelIsClose then return end if func then func() end end) end) end end -- 缩放 function this.PlayScale(go, scale) if go then local originScale = go.transform.localScale go.transform:DOScale(originScale * scale, 0.1):OnComplete(function () go.transform:DOScale(originScale, 0.1) end) end end --- ================= 我要喝点牛牛补补血 ============ function this.private_DrinkSomeMilk(iconType, point, roleFaceDir) this.private_BloodBlood(m_selectPointPos, 1, iconType, false, 1) if actionCallBack then actionCallBack() end end --- =================================================== -- 每走一步看看我是否还有Buff function this.JudgeBuffState(spLoader, u, v) if m_isHaveBuff > 0 then this.private_UpDateBuff() if m_buffStayStep % 2 == 1 then -- 设置一下提示文字 this.ShowBuffTip(u, v) end end m_buffStayStep = m_buffStayStep - 1 end -- 显示buff的提示文字 function this.ShowBuffTip(spLoader, u, v) if m_parent.buffTipList then local go = m_parent.buffTipList[m_buffStayStep % 3 + 1] if go then local originPos = SetObjPosByUV(u * 256 + v) local targetPos = originPos + Vector2.New(0, 164) go:GetComponent("RectTransform").anchoredPosition = originPos local imgList = buffTipImg[m_isHaveBuff] go:GetComponent("Image").sprite = spLoader:LoadSprite(imgList[math.random(1, #imgList)]) go:SetActive(true) go:GetComponent("Image"):DOFade(0, 0.3):SetDelay(0.5):OnComplete(function () if panelIsClose then return end if go then go:GetComponent("Image"):DOFade(1, 0.1) end end) go:GetComponent("RectTransform"):DOAnchorPos(targetPos, 0.8, false):OnComplete(function () if panelIsClose then return end if go then go:SetActive(false) end end) end end end -- 添加一个Buff --- @param buffType 1 -- 攻击buff 2 -- 防御buff 0 -- 无buff,隐藏所有 function this.private_CreateBuff(buffType) local haveBuff = buffType > 0 local isAttackBuff = buffType == 1 if panelIsClose then return end if m_parent.buffEffectRoot then m_parent.buffEffectRoot:SetActive(haveBuff) end if m_parent.buffAttack then m_parent.buffAttack:SetActive(isAttackBuff) end if m_parent.buffDefend then m_parent.buffDefend:SetActive(not isAttackBuff) end m_isHaveBuff = buffType -- 创建完毕 if actionCallBack then actionCallBack() end -- 加速吧,少年 this.SetActionSpeed(2, 1.5) -- 用一个特殊的音频通道播放并在关闭界面和buff结束时关闭 SoundManager.PlaySound(SoundConfig.Sound_FightArea_Buff,nil, nil, 20) end -- 消除一个Buff function this.private_EndBuff() if panelIsClose then return end if m_parent.buffEffectRoot then m_parent.buffEffectRoot:SetActive(false) end if m_parent.buffAttack then m_parent.buffAttack:SetActive(false) end if m_parent.buffDefend then m_parent.buffDefend:SetActive(not false) end m_isHaveBuff = 0 -- 变成龟速 this.SetActionSpeed(1, 1) SoundManager.StopSoundByChannel(20) end -- 走一步更新buff状态 function this.private_UpDateBuff() m_buffStayStep = m_buffStayStep > 0 and m_buffStayStep or 0 if m_buffStayStep == 0 then this.private_EndBuff() end end -- 攻击乘以 1.5 -- 防御降低到0.5的伤害值 -- 计算当前buff带来的数值增量 --- @param isMonster 攻击对象是否是个怪 --- @param curHurtNum 叠加暴击后的伤害值 function this.private_GetBuffGain(isMonster, curHurtNum) -- 如果没有buff if m_isHaveBuff then return curHurtNum end local gainNum = curHurtNum if isMonster then if m_isHaveBuff == 1 then -- 攻击怪时拥有攻击buff gainNum = curHurtNum * 1.2 else gainNum = curHurtNum end else -- 天呢,我被打了 if m_isHaveBuff == 1 then gainNum = curHurtNum else gainNum = curHurtNum * 0.5 end end return gainNum end --- ==================================================== -------------------------------------------------------- return this