PGRData/Script/matrix/xui/xuigoldenminer/game/XGoldenMinerGame.lua

1687 lines
61 KiB
Lua
Raw Permalink Normal View History

2024-09-01 22:49:41 +02:00
local XGoldenMinerComponentHook = require("XUi/XUiGoldenMiner/Game/Component/XGoldenMinerComponentHook")
local XGoldenMinerComponentStone = require("XUi/XUiGoldenMiner/Game/Component/XGoldenMinerComponentStone")
local XGoldenMinerComponentMove = require("XUi/XUiGoldenMiner/Game/Component/XGoldenMinerComponentMove")
local XGoldenMinerComponentMouse = require("XUi/XUiGoldenMiner/Game/Component/XGoldenMinerComponentMouse")
local XGoldenMinerComponentQTE = require("XUi/XUiGoldenMiner/Game/Component/XGoldenMinerComponentQTE")
local XGoldenMinerComponentMussel = require("XUi/XUiGoldenMiner/Game/Component/XGoldenMinerComponentMussel")
local XGoldenMinerComponentDirectionPoint = require("XUi/XUiGoldenMiner/Game/Component/XGoldenMinerComponentDirectionPoint")
local XGoldenMinerComponentTimeLineAnim = require("XUi/XUiGoldenMiner/Game/Component/XGoldenMinerComponentTimeLineAnim")
local XGoldenMinerEntityHook = require("XUi/XUiGoldenMiner/Game/Entity/XGoldenMinerEntityHook")
local XGoldenMinerEntityStone = require("XUi/XUiGoldenMiner/Game/Entity/XGoldenMinerEntityStone")
local XGoldenMinerEntityBuffContainer = require("XUi/XUiGoldenMiner/Game/Entity/XGoldenMinerEntityBuffContainer")
local XGoldenMinerSystemHook = require("XUi/XUiGoldenMiner/Game/System/XGoldenMinerSystemHook")
local XGoldenMinerSystemStone = require("XUi/XUiGoldenMiner/Game/System/XGoldenMinerSystemStone")
local XGoldenMinerSystemMove = require("XUi/XUiGoldenMiner/Game/System/XGoldenMinerSystemMove")
local XGoldenMinerSystemBuff = require("XUi/XUiGoldenMiner/Game/System/XGoldenMinerSystemBuff")
local XGoldenMinerSystemQTE = require("XUi/XUiGoldenMiner/Game/System/XGoldenMinerSystemQTE")
local XGoldenMinerSystemTimeLineAnim = require("XUi/XUiGoldenMiner/Game/System/XGoldenMinerSystemTimeLineAnim")
local XGoldenMinerMapStoneData = require("XEntity/XGoldenMiner/Game/XGoldenMinerMapStoneData")
local GAME_STATUS = {
NONE = 0,
INIT = 1,
PLAY = 2,
PAUSE = 3,
END = 4,
QTE = 5,
TIME_STOP = 6,
}
local MIN_FRAME_TIME = 1 / 20
local MILLION_PERCENT = 1000000
local W_PERCENT = 10000
local CSXResourceManagerLoad = CS.XResourceManager.Load
---@class XGoldenMinerGame
local XGoldenMinerGame = XClass(nil, "XGoldenMinerGame")
function XGoldenMinerGame:Ctor()
---@type XGoldenMinerGameData
self._Data = false
---一级状态:游戏状态
self._Status = GAME_STATUS.NONE
---二级状态:暂停原因
self._PauseReason = XGoldenMinerConfigs.GAME_PAUSE_TYPE.NONE
---暂停前状态缓存
self._PauseStageCatchStatus = GAME_STATUS.NONE
---时间停止前状态缓存
self._TimeStopCatchStatus = GAME_STATUS.NONE
---QTE前状态缓存
self._QTECatchStatus = GAME_STATUS.NONE
---@type UnityEngine.Transform
self._MapObjRoot = false
---@type UnityEngine.Vector2
self._RectSize = false
---@type UnityEngine.Transform[]
self._HookObjDir = {}
---@type UnityEngine.Transform
self._HookRoot = false
---资源字典
self._ResourcePool = {}
self.BuffIdList = {}
---@type XGoldenMinerEntityBuffContainer
self.BuffContainer = XGoldenMinerEntityBuffContainer.New()
---@type XGoldenMinerEntityHook[]
self.HookEntityList = false
self.HookEntityStatus = XGoldenMinerConfigs.GAME_HOOK_ENTITY_STATUS.NONE
---@type XGoldenMinerEntityStone[]
self.StoneEntityList = {}
---QTE触发钩子
---@type XGoldenMinerEntityHook
self.QTEHookEntity = false
---QTE触发抓取
---@type XGoldenMinerEntityStone
self.QTEStoneEntity = false
---QTE触发钩子缓存
---@type XGoldenMinerEntityHook
self.QTECatchHookEntityList = { }
---QTE触发抓取缓存
---@type XGoldenMinerEntityStone
self.QTECatchStoneEntityList = { }
---@type XGoldenMinerSystemHook
self.SystemHook = XGoldenMinerSystemHook.New()
---@type XGoldenMinerSystemStone
self.SystemStone = XGoldenMinerSystemStone.New()
---@type XGoldenMinerSystemMove
self.SystemMove = XGoldenMinerSystemMove.New()
---@type XGoldenMinerSystemBuff
self.SystemBuff = XGoldenMinerSystemBuff.New()
---@type XGoldenMinerSystemQTE
self.SystemQTE = XGoldenMinerSystemQTE.New()
---@type XGoldenMinerSystemTimeLineAnim
self.SystemTimeLimeAnim = XGoldenMinerSystemTimeLineAnim.New()
end
--region GameControl
function XGoldenMinerGame:Init()
if not self:_IsStatus(GAME_STATUS.NONE) then
return
end
self._Status = GAME_STATUS.INIT
self:InitHook()
self:InitMap()
self:InitBuff()
self:InitTimeLineAnim()
self._Status = GAME_STATUS.PLAY
end
function XGoldenMinerGame:Update(time)
time = self:_CheckFrameTime(time)
if self:IsQTE() then
self:UpdateQTE(time)
elseif self:IsPlay() then
self:UpdateTime(time)
self:UpdateBuff(time)
self:UpdateHook(time)
self:UpdateStone(time)
self:UpdateStoneMove(time)
self:UpdateTimeLineAnim(time)
elseif self:IsTimeStop() then
self:UpdateBuff(time)
self:UpdateHook(time)
self:UpdateStone(time)
self:UpdateTimeLineAnim(time)
end
end
function XGoldenMinerGame:Resume(reason)
if self:IsEnd() then
return
end
if reason then
self._PauseReason = self._PauseReason & (~reason)
end
if self._PauseReason ~= XGoldenMinerConfigs.GAME_PAUSE_TYPE.NONE then
return
end
self._Status = self._PauseStageCatchStatus
end
function XGoldenMinerGame:Pause(reason)
if self:IsEnd() or self:IsPause(reason) then
return
end
if not self:IsPause() then
self._PauseStageCatchStatus = self._Status
end
if reason then
self._PauseReason = self._PauseReason | reason
end
self._Status = GAME_STATUS.PAUSE
end
function XGoldenMinerGame:GameOver()
self._Status = GAME_STATUS.END
end
function XGoldenMinerGame:TimeStop()
if self:IsEnd() or self:IsPause() then
return
end
if not self:IsTimeStop() then
self._TimeStopCatchStatus = self._Status
end
self._Status = GAME_STATUS.TIME_STOP
end
function XGoldenMinerGame:TimeResume()
if self:IsEnd() or self:IsPause() then
return
end
if self._TimeStopCatchStatus == GAME_STATUS.NONE then
return
end
self._Status = self._TimeStopCatchStatus
end
function XGoldenMinerGame:Destroy()
for _, resource in pairs(self._ResourcePool) do
resource:Release()
end
self._Data = nil
self._Status = nil
self._PauseReason = nil
self._PauseStageCatchStatus = nil
self._MapObjRoot = nil
self._RectSize = nil
self._MapObjRoot = nil
self._HookObjDir = nil
self._HookRoot = nil
self.HookEntityList = nil
self.StoneEntityList = nil
self.QTEHookEntity = nil
self.QTEStoneEntity = nil
self.SystemHook = nil
self.SystemStone = nil
self.SystemMove = nil
self.SystemBuff = nil
self.SystemQTE = nil
self.SystemTimeLimeAnim = nil
end
--endregion
--region GameCheck
function XGoldenMinerGame:CheckIsStoneClear()
for _, stoneEntity in ipairs(self.StoneEntityList) do
if not stoneEntity.HookDirectionPoint and
stoneEntity.Status ~= XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS.GRABBED and
stoneEntity.Status ~= XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS.DESTROY
then
return false
end
end
self._Status = GAME_STATUS.END
XEventManager.DispatchEvent(XEventId.EVENT_GOLDEN_MINER_GAME_STONE_CLEAR)
return true
end
---防止卡顿跳帧
function XGoldenMinerGame:_CheckFrameTime(time)
if time > MIN_FRAME_TIME then
time = MIN_FRAME_TIME
end
return time
end
---@param status number GAME_STATUS
function XGoldenMinerGame:_IsStatus(status)
return self._Status == status
end
function XGoldenMinerGame:IsRunning()
return self:_IsStatus(GAME_STATUS.INIT)
or self:IsPlay()
or self:IsQTE()
or self:IsTimeStop()
end
function XGoldenMinerGame:IsPlay()
return self:_IsStatus(GAME_STATUS.PLAY)
end
function XGoldenMinerGame:IsQTE()
return self:_IsStatus(GAME_STATUS.QTE)
end
function XGoldenMinerGame:IsPause(reason)
local isReason = true
if reason then
isReason = self._PauseReason & reason ~= XGoldenMinerConfigs.GAME_PAUSE_TYPE.NONE
end
return self:_IsStatus(GAME_STATUS.PAUSE) and isReason
end
function XGoldenMinerGame:IsTimeStop()
return self:_IsStatus(GAME_STATUS.TIME_STOP)
end
function XGoldenMinerGame:IsEnd()
return self:_IsStatus(GAME_STATUS.END)
end
--endregion
--region Data
---@param data XGoldenMinerGameData
function XGoldenMinerGame:SetData(data)
self._Data = data
end
function XGoldenMinerGame:SetBuffIdList(buffIdList)
self.BuffIdList = buffIdList
end
---@param mapObjRoot UnityEngine.Transform
function XGoldenMinerGame:SetMapObjRoot(mapObjRoot)
self._MapObjRoot = mapObjRoot
end
---@param rectSize UnityEngine.Vector2
function XGoldenMinerGame:SetRectSize(rectSize)
self._RectSize = rectSize
end
---@param hookObjDir UnityEngine.Transform[]
function XGoldenMinerGame:SetHookObjDir(hookObjDir)
self._HookObjDir = hookObjDir
end
---@param hookColliderDir UnityEngine.Collider2D[]
function XGoldenMinerGame:SetHookColliderDir(hookRoot)
self._HookRoot = hookRoot
end
function XGoldenMinerGame:GetData()
return self._Data
end
function XGoldenMinerGame:GetCurScore()
if not self._Data then
return 0
end
return self._Data:GetCurScore()
end
function XGoldenMinerGame:GetChangeScore()
if not self._Data then
return 0
end
return self._Data:GetChangeScore()
end
function XGoldenMinerGame:GetOldScore()
if not self._Data then
return 0
end
return self._Data:GetOldScore()
end
---@return XGoldenMinerEntityStone[]
function XGoldenMinerGame:GetGrabbedStoneEntityList()
local result = {}
for _, hookEntity in ipairs(self.HookEntityList) do
if not XTool.IsTableEmpty(hookEntity.HookGrabbedStoneList) then
for _, stoneEntity in ipairs(hookEntity.HookGrabbedStoneList) do
result[#result + 1] = stoneEntity
end
end
end
return result
end
---@return XGoldenMinerEntityStone[]
function XGoldenMinerGame:GetGrabbedScoreDir()
local result = {}
local AddScore = function(type, score)
if not XTool.IsNumberValid(result[type]) then
result[type] = 0
end
result[type] = result[type] + score
end
for _, hookEntity in ipairs(self.HookEntityList) do
if not XTool.IsTableEmpty(hookEntity.HookGrabbedStoneList) then
for _, stoneEntity in ipairs(hookEntity.HookGrabbedStoneList) do
local type = stoneEntity.Data:GetType()
if type == XGoldenMinerConfigs.StoneType.Mussel and stoneEntity.CarryStone then
type = stoneEntity.CarryStone.Data:GetType()
end
AddScore(type, stoneEntity.Stone.CurScore)
if stoneEntity.CarryStone then
AddScore(type, stoneEntity.CarryStone.Stone.CurScore)
end
if stoneEntity.QTE then
AddScore(type, stoneEntity.QTE.AddScore)
end
end
end
end
return result
end
function XGoldenMinerGame:GetStopTime()
if not self.SystemBuff then
return 0
end
local time = 0
---@type XGoldenMinerComponentBuff
local buff
buff = self.SystemBuff:GetAliveBuffByType(self.BuffContainer, XGoldenMinerConfigs.BuffType.GoldenMinerUseItemStopTime)
if buff then
time = time + buff.Time
end
buff = self.SystemBuff:GetAliveBuffByType(self.BuffContainer, XGoldenMinerConfigs.BuffType.GoldenMinerItemStopTime)
if buff then
time = time + buff.Time
end
return math.ceil(time)
end
function XGoldenMinerGame:AddMapScore(score)
self._Data:SetMapScore(self._Data:GetMapScore() + score)
XEventManager.DispatchEvent(XEventId.EVENT_GOLDEN_MINER_GAME_ADD_SCORE)
end
function XGoldenMinerGame:AddTime(time)
self._Data:SetTime(self._Data:GetTime() + time)
XEventManager.DispatchEvent(XEventId.EVENT_GOLDEN_MINER_GAME_ADD_TIME, time)
end
function XGoldenMinerGame:AddItem(itemId)
if not XTool.IsNumberValid(itemId) then
return
end
XEventManager.DispatchEvent(XEventId.EVENT_GOLDEN_MINER_GAME_ADD_ITEM, itemId)
end
--endregion
--region Data - Time
---@param usedTime number 经过的时间
function XGoldenMinerGame:UpdateTime(usedTime)
if self:IsEnd() then
return
end
local curUsedTime = self._Data:GetUsedTime()
self._Data:SetUsedTime(curUsedTime + usedTime)
self:ChangeTime(usedTime)
end
---改变时间
function XGoldenMinerGame:ChangeTime(usedTime)
local curTime = self._Data:GetTime()
self._Data:SetTime(curTime - usedTime)
if self._Data:IsTimeOut() then
self._Status = GAME_STATUS.END
XEventManager.DispatchEvent(XEventId.EVENT_GOLDEN_MINER_GAME_TIMEOUT)
end
end
--endregion
--region Data - HideTask
---隐藏任务
---@param hookEntity XGoldenMinerEntityHook
function XGoldenMinerGame:CheckHideTask(hookEntity)
if XTool.IsTableEmpty(hookEntity.HookGrabbingStoneList) then
return
end
local hideTaskList = self._Data:GetHideTaskInfoList()
if XTool.IsTableEmpty(hideTaskList) then
return
end
for _, hideTaskInfo in ipairs(hideTaskList) do
if not hideTaskInfo:IsFinish() then
local type = hideTaskInfo:GetType()
if type == XGoldenMinerConfigs.HideTaskType.GrabStone then
for _, stoneEntity in ipairs(hookEntity.HookGrabbingStoneList) do
if stoneEntity.Data:GetId() == hideTaskInfo:GetParams()[1] then
hideTaskInfo:AddCurProgress()
end
end
elseif type == XGoldenMinerConfigs.HideTaskType.GrabStoneByOnce then
local isFinish = false
for _, stoneEntity in ipairs(hookEntity.HookGrabbingStoneList) do
if stoneEntity.Data:GetId() == hideTaskInfo:GetParams()[1] then
hideTaskInfo:SetCatchValue(hideTaskInfo:GetCatchValue() + 1)
isFinish = hideTaskInfo:GetCatchValue() >= hideTaskInfo:GetParams()[2]
end
end
if isFinish then
hideTaskInfo:AddCurProgress()
end
elseif type == XGoldenMinerConfigs.HideTaskType.GrabStoneInBuff then
-- 在某Buff加持下抓取物品
if self:CheckHasBuffByBuffId(hideTaskInfo:GetParams()[2]) then
for _, stoneEntity in ipairs(hookEntity.HookGrabbingStoneList) do
if stoneEntity.Data:GetId() == hideTaskInfo:GetParams()[1] then
hideTaskInfo:AddCurProgress()
end
end
end
elseif type == XGoldenMinerConfigs.HideTaskType.GrabStoneByReflection then
local isGrab = false
local isHitCount = 0
for _, stoneEntity in ipairs(hookEntity.HookGrabbingStoneList) do
if stoneEntity.Data:GetId() == hideTaskInfo:GetParams()[1] then
isGrab = true
end
end
if not XTool.IsTableEmpty(hookEntity.HookHitStoneList) then
for i = 2, #hideTaskInfo:GetParams() do
for _, stoneEntity in ipairs(hookEntity.HookHitStoneList) do
if stoneEntity.Data:GetId() == hideTaskInfo:GetParams()[i] then
isHitCount = isHitCount + 1
end
end
end
end
if isGrab and isHitCount >= #hideTaskInfo:GetParams() - 1 then
hideTaskInfo:AddCurProgress()
end
elseif type == XGoldenMinerConfigs.HideTaskType.GrabDrawMap then
local mapDrawGroup = XGoldenMinerConfigs.GetHideTaskMapDrawGroup(hideTaskInfo:GetParams()[1])
local isFinish = true
for _, drawId in ipairs(mapDrawGroup) do
local index = XGoldenMinerConfigs.GetHideTaskMapDrawGroupStoneIdIndex(drawId)
local isStay = XGoldenMinerConfigs.GetHideTaskMapDrawGroupIsStay(drawId)
local stoneEntity = self.StoneEntityList[index]
if isStay then
if stoneEntity.Status ~= XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS.ALIVE then
isFinish = false
end
else
if stoneEntity.Status ~= XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS.GRABBED
and stoneEntity.Status ~= XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS.BE_DESTROY
and stoneEntity.Status ~= XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS.DESTROY
then
isFinish = false
end
end
end
if isFinish then
hideTaskInfo:AddCurProgress()
end
end
if hideTaskInfo:IsFinish() then
--XGoldenMinerConfigs.DebugLog("隐藏任务完成:HideTaskId="..hideTaskInfo:GetId())
end
end
end
end
---隐藏任务缓存值清除
function XGoldenMinerGame:ClearHideTaskCatch()
local hideTaskList = self._Data:GetHideTaskInfoList()
if XTool.IsTableEmpty(hideTaskList) then
return
end
for _, hideTaskInfo in ipairs(hideTaskList) do
if not hideTaskInfo:IsFinish() then
hideTaskInfo:SetCatchValue(0)
end
end
end
--endregion
--region System - HookEntity
function XGoldenMinerGame:InitHook()
self.HookEntityList = {}
for _, type in ipairs(self._Data:GetHookTypeList()) do
---@type XGoldenMinerEntityHook
local hookEntity = XGoldenMinerEntityHook.New()
hookEntity.Hook = self:_CreateHookComponent(type, self._HookObjDir[type], self._HookRoot)
hookEntity.HookGrabbingStoneList = {}
hookEntity.HookGrabbedStoneList = {}
hookEntity.HookHitStoneList = {}
for _, aim in pairs(hookEntity.Hook.AimTranList) do
local length = math.ceil(math.sqrt(self._RectSize.x ^ 2 + self._RectSize.y ^ 2))
local rectTran = aim.gameObject:GetComponent("RectTransform")
local sizeDelta = rectTran.sizeDelta
rectTran.sizeDelta = Vector2(sizeDelta.x, length)
aim.gameObject:SetActiveEx(false)
end
self:RegisterHookHitCallBack(hookEntity)
self.HookEntityList[#self.HookEntityList + 1] = hookEntity
end
if self.SystemHook then
self.SystemHook:Init(self)
end
end
function XGoldenMinerGame:UpdateHook(time)
if self:IsEnd() then
return
end
if not self.SystemHook then
return
end
self.SystemHook:Update(self, time)
end
---@return XGoldenMinerComponentHook
function XGoldenMinerGame:_CreateHookComponent(type, hookObj, hookRoot)
if XTool.UObjIsNil(hookObj) then
return false
end
---@type XGoldenMinerComponentHook
local hook = XGoldenMinerComponentHook.New()
hook.Type = type
hook.Transform = hookObj
hook.HookObj = XUiHelper.TryGetComponent(hook.Transform, "Hook")
hook.HookObjStartLocalPosition = hook.HookObj.localPosition
hook.RopeObjList = { XUiHelper.TryGetComponent(hook.Transform, "RopeRoot/Rope") }
hook.RopeObjStartLocalPosition = hook.RopeObjList[1].localPosition
local Collider2DList = hook.HookObj.gameObject:GetComponentsInChildren(typeof(CS.UnityEngine.Collider2D))
for i = 0, Collider2DList.Length - 1 do
hook.ColliderList[i + 1] = Collider2DList[i]
hook.GoInputHandlerList[i + 1] = hook.ColliderList[i + 1].transform:GetComponent(typeof(CS.XGoInputHandler))
if XTool.UObjIsNil(hook.GoInputHandlerList[i + 1]) then
hook.GoInputHandlerList[i + 1] = hook.ColliderList[i + 1].transform.gameObject:AddComponent(typeof(CS.XGoInputHandler))
end
end
-- 绳子碰撞点,用于碰撞转向点
local ropeColliderObj = XUiHelper.TryGetComponent(hook.Transform, "RopeCollider")
if ropeColliderObj then
hook.RopeCollider = ropeColliderObj.transform:GetComponent(typeof(CS.UnityEngine.Collider2D))
hook.RopeInputHandler = hook.RopeCollider.transform:GetComponent(typeof(CS.XGoInputHandler))
if XTool.UObjIsNil(hook.RopeInputHandler) then
hook.RopeInputHandler = hook.RopeCollider.gameObject:AddComponent(typeof(CS.XGoInputHandler))
end
end
hook.GrabPoint = XUiHelper.TryGetComponent(hook.Transform, "Hook/RopeCord/TriggerObjs")
hook.AimTranList = {
XUiHelper.TryGetComponent(hook.Transform, "Hook/RopeCord/Aim"),
XUiHelper.TryGetComponent(hook.Transform, "Hook/RopeCord/Aim2"),
XUiHelper.TryGetComponent(hook.Transform, "Hook/RopeCord/Aim3")
}
hook.RopeMaxLength = math.ceil(math.sqrt(self._RectSize.x ^ 2 + self._RectSize.y ^ 2) + XGoldenMinerConfigs.GetHookRopeExLength())
hook.RopeMinLength = hook.RopeObjList[1].sizeDelta.y
hook.RopeLength = hook.RopeMinLength
hook.IdleSpeed = XGoldenMinerConfigs.GetRopeRockSpeed()
hook.ShootSpeed = XGoldenMinerConfigs.GetRopeStretchSpeed()
hook.CurShootSpeed = hook.ShootSpeed
hook.IdleRotateDirection = false
hook.CurIdleRotateAngle = hook.Transform.localRotation.eulerAngles
return hook
end
---@param hookEntity XGoldenMinerEntityHook
function XGoldenMinerGame:RegisterHookHitCallBack(hookEntity)
if not hookEntity.Hook or XTool.IsTableEmpty(hookEntity.Hook.GoInputHandlerList) then
return
end
for _, goInputHandler in ipairs(hookEntity.Hook.GoInputHandlerList) do
goInputHandler:AddTriggerEnter2DCallback(function(collider)
self:HookHit(hookEntity, collider)
end)
end
if hookEntity.Hook.RopeInputHandler then
hookEntity.Hook.RopeInputHandler:AddTriggerEnter2DCallback(function(collider)
self:RopeHit(hookEntity, collider)
end)
end
end
function XGoldenMinerGame:HookShoot()
self:ClearHideTaskCatch()
if self.SystemHook then
self.SystemHook:HookShoot(self)
end
end
---@param hookEntity XGoldenMinerEntityHook
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:HookGrab(hookEntity, stoneEntity)
if not self.SystemHook then
return
end
self:SetStoneGrab(hookEntity, stoneEntity)
if self.SystemTimeLimeAnim then
self.SystemTimeLimeAnim:PlayAnim(hookEntity, XGoldenMinerConfigs.GAME_ANIM.HOOK_CLOSE, function()
self:HookRevoke(hookEntity)
end)
else
self.SystemHook:HookRevoke(self, hookEntity.Hook)
end
end
---@param hookEntity XGoldenMinerEntityHook
function XGoldenMinerGame:HookRevoke(hookEntity)
if self.SystemHook then
self.SystemHook:HookRevoke(self, hookEntity.Hook)
end
end
---@param hookEntity XGoldenMinerEntityHook
---@param collider UnityEngine.Collider2D
function XGoldenMinerGame:HookHit(hookEntity, collider)
local stoneEntity = self:FindStoneEntityByCollider(collider)
local hitHookEntity = self:FindHookEntityByCollider(collider)
if hitHookEntity then
return
end
if self.SystemHook then
self.SystemHook:OnHookHit(self, hookEntity, stoneEntity)
end
end
---@param hookEntity XGoldenMinerEntityHook
---@param collider UnityEngine.Collider2D
function XGoldenMinerGame:RopeHit(hookEntity, collider)
local stoneEntity = self:FindStoneEntityByCollider(collider)
local hitHookEntity = self:FindHookEntityByCollider(collider)
if hitHookEntity then
return
end
if self.SystemHook then
self.SystemHook:OnRopeHit(self, hookEntity, stoneEntity)
end
end
---@param hookEntity XGoldenMinerEntityHook
function XGoldenMinerGame:OnHookRevokeToIdle(hookEntity)
local score = 0
-- 收回
for _, stoneEntity in ipairs(hookEntity.HookGrabbingStoneList) do
if stoneEntity.Status == XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS.GRABBED then
-- Buff
self:TriggerStoneGrabBuff(stoneEntity)
-- 加分
score = score + stoneEntity.Stone.CurScore
-- 特殊抓取物触发
self:CheckHookRevokeToIdle(stoneEntity)
if stoneEntity.CarryStone then
score = score + stoneEntity.CarryStone.Stone.CurScore
self:CheckHookRevokeToIdle(stoneEntity.CarryStone)
end
if stoneEntity.QTE then
score = score + stoneEntity.QTE.AddScore
if XTool.IsNumberValid(stoneEntity.QTE.AddBuff) then
self:AddBuff(stoneEntity.QTE.AddBuff)
end
if XTool.IsNumberValid(stoneEntity.QTE.AddItemId) then
self:AddItem(stoneEntity.QTE.AddItemId)
end
end
end
end
if self.SystemTimeLimeAnim and not XTool.IsTableEmpty(hookEntity.HookGrabbingStoneList) then
self.SystemTimeLimeAnim:PlayAnim(hookEntity, XGoldenMinerConfigs.GAME_ANIM.HOOK_OPEN)
end
self:AddMapScore(score)
-- 隐藏任务
self:CheckHideTask(hookEntity)
-- 表情
XEventManager.DispatchEvent(XEventId.EVENT_GOLDEN_MINER_GAME_PLAY_FACE,
XGoldenMinerConfigs.GAME_FACE_PLAY_TYPE.GRABBED,
XGoldenMinerConfigs.GAME_FACE_PLAY_ID.GRABBED)
-- 清理
hookEntity.HookGrabbingStoneList = {}
hookEntity.HookHitStoneList = {}
self:TriggerCountRevokeEndCountBuff()
self:CheckIsStoneClear()
end
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:CheckHookRevokeToIdle(stoneEntity)
-- 特殊抓取物触发
if stoneEntity.Data:GetType() == XGoldenMinerConfigs.StoneType.RedEnvelope then
local redEnvelopeId = stoneEntity.AdditionValue[XGoldenMinerConfigs.StoneType.RedEnvelope]
if not redEnvelopeId then
local redEnvelopeGroup = stoneEntity.Data:GetRedEnvelopeGroup()
redEnvelopeId = XGoldenMinerConfigs.GetRedEnvelopeRandId(redEnvelopeGroup)
stoneEntity.AdditionValue[XGoldenMinerConfigs.StoneType.RedEnvelope] = redEnvelopeId
end
local itemId = XGoldenMinerConfigs.GetRedEnvelopeItemId(redEnvelopeId)
stoneEntity.Stone.Score = itemId
self:AddItem(itemId)
elseif stoneEntity.Data:GetType() == XGoldenMinerConfigs.StoneType.AddTimeStone then
self:AddTime(stoneEntity.Data:GetAddTimeStoneAddTime())
elseif stoneEntity.Data:GetType() == XGoldenMinerConfigs.StoneType.ItemStone then
self:UseItemToAddBuff(stoneEntity.Data:GetItemStoneItemId())
end
end
function XGoldenMinerGame:HookAimRight()
for _, hookEntity in ipairs(self.HookEntityList) do
hookEntity.Hook.IdleRotateDirection = Vector3.forward
end
end
function XGoldenMinerGame:HookAimLeft()
for _, hookEntity in ipairs(self.HookEntityList) do
hookEntity.Hook.IdleRotateDirection = Vector3.back
end
end
function XGoldenMinerGame:HookAimIdle()
for _, hookEntity in ipairs(self.HookEntityList) do
hookEntity.Hook.IdleRotateDirection = false
end
end
---@param hook XGoldenMinerComponentHook
---@return XGoldenMinerEntityHook
function XGoldenMinerGame:GetHookEntityByHook(hook)
for _, hookEntity in ipairs(self.HookEntityList) do
if hookEntity.Hook == hook then
return hookEntity
end
end
return false
end
---@param anim XGoldenMinerComponentTimeLineAnim
---@return XGoldenMinerEntityHook
function XGoldenMinerGame:GetHookEntityByAnim(anim)
for _, hookEntity in ipairs(self.HookEntityList) do
if hookEntity.Anim == anim then
return hookEntity
end
end
return false
end
---@param hookStatus number XGoldenMinerConfigs.GAME_HOOK_STATUS
---@return XGoldenMinerEntityStone[]
function XGoldenMinerGame:GetHookGrabEntity(hookStatus, stoneStatus)
local stoneEntityList = {}
for _, hookEntity in ipairs(self.HookEntityList) do
if (not hookStatus or hookEntity.Hook.Status == hookStatus)
and not XTool.IsTableEmpty(hookEntity.HookGrabbingStoneList) then
for _, stoneEntity in ipairs(hookEntity.HookGrabbingStoneList) do
if not stoneStatus or stoneEntity.Status == stoneStatus then
stoneEntityList[#stoneEntityList + 1] = stoneEntity
end
end
end
end
return stoneEntityList
end
function XGoldenMinerGame:GetHookGrabWeight(stoneStatus)
local stoneEntityList = self:GetHookGrabEntity(nil, stoneStatus)
local weight = 0
for _, stoneEntity in pairs(stoneEntityList) do
weight = weight + stoneEntity.Stone.CurWeight
if stoneEntity.CarryStone then
weight = weight + stoneEntity.CarryStone.Stone.CurWeight
end
end
return weight
end
function XGoldenMinerGame:GetHookGrabScore(stoneStatus)
local stoneEntityList = self:GetHookGrabEntity(nil, stoneStatus)
local score = 0
for _, stoneEntity in pairs(stoneEntityList) do
score = score + stoneEntity.Stone.CurScore
if stoneEntity.CarryStone then
score = score + stoneEntity.CarryStone.Stone.CurScore
end
if stoneEntity.QTE then
score = score + stoneEntity.QTE.AddScore
end
end
return score
end
---@param collider UnityEngine.Collider2D
---@return XGoldenMinerEntityHook
function XGoldenMinerGame:FindHookEntityByCollider(collider)
if XTool.IsTableEmpty(self.HookEntityList) then
return false
end
for _, entity in ipairs(self.HookEntityList) do
if not XTool.IsTableEmpty(entity.Hook.ColliderList) then
for _, hookCollider in ipairs(entity.Hook.ColliderList) do
if hookCollider == collider then
return entity
end
end
end
if entity.Hook.RopeCollider and entity.Hook.RopeCollider == collider then
return entity
end
end
return false
end
--endregion
--region System - StoneEntity
function XGoldenMinerGame:InitMap()
self.StoneEntityList = {}
local mapStoneList = self._Data:GetMapStoneDataList()
if XTool.IsTableEmpty(mapStoneList) then
return
end
for _, stoneData in ipairs(mapStoneList) do
local stoneEntity = self:CreateStoneEntity(stoneData)
self.StoneEntityList[#self.StoneEntityList + 1] = stoneEntity
end
if self.SystemStone then
self.SystemStone:Init(self)
end
end
function XGoldenMinerGame:UpdateStone(time)
if self:IsEnd() then
return
end
if self.SystemStone then
self.SystemStone:Update(self, time)
end
self:CheckIsStoneClear()
end
function XGoldenMinerGame:UpdateStoneMove(time)
if self:IsEnd() then
return
end
if self.SystemMove then
self.SystemMove:Update(self, time)
end
end
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:ChangeToGold(stoneEntity)
if stoneEntity.Mouse or stoneEntity.Mussel then
self:_CarryStoneChangeToGold(stoneEntity)
else
self:_StoneChangeToGold(stoneEntity)
end
end
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:_StoneChangeToGold(stoneEntity)
local goldId = XGoldenMinerConfigs.GetGoldIdByWeight(stoneEntity.Stone.Weight, stoneEntity.Data:GetId())
if not goldId then
return
end
local parent = stoneEntity.Stone.Transform.parent
local stoneData = XGoldenMinerMapStoneData.New(goldId)
XUiHelper.Destroy(stoneEntity.Stone.Transform.gameObject)
stoneEntity.Data = stoneData
stoneEntity.Stone = self:_CreateStoneComponent(stoneData)
stoneEntity.Move = self:_CreateMoveComponent(stoneData, stoneEntity.Stone.Transform)
stoneEntity.CarryStone = self:_CreateCarryStone(stoneEntity, stoneEntity.Data:GetCarryStoneId())
stoneEntity.Anim = false
stoneEntity.Stone.Transform:SetParent(parent, false)
local rectTransform = stoneEntity.Stone.Transform:GetComponent("RectTransform")
rectTransform.anchorMin = Vector2(0.5, 1)
rectTransform.anchorMax = Vector2(0.5, 1)
rectTransform.pivot = Vector2(0.5, 1)
stoneEntity.Stone.Transform.localPosition = Vector3.zero
stoneEntity.Stone.Transform.localRotation = CS.UnityEngine.Quaternion.identity
stoneEntity.Stone.Score = stoneEntity.Data:GetScore()
stoneEntity.Stone.CurScore = stoneEntity.Stone.Score
stoneEntity.Mussel = false
stoneEntity.QTE = false
end
---猫猫点石成金只改携带物
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:_CarryStoneChangeToGold(stoneEntity)
-- 没有携带物则道具白用
if not stoneEntity.CarryStone then
return
end
local goldId = XGoldenMinerConfigs.GetGoldIdByWeight(stoneEntity.CarryStone.Data:GetWeight(), stoneEntity.Data:GetCarryStoneId())
if not goldId then
return
end
XUiHelper.Destroy(stoneEntity.CarryStone.Stone.Transform.gameObject)
stoneEntity.CarryStone = nil
stoneEntity.CarryStone = self:_CreateCarryStone(stoneEntity, goldId)
stoneEntity.Stone.Score = stoneEntity.Data:GetScore()
stoneEntity.Stone.CurScore = stoneEntity.Stone.Score
stoneEntity.CarryStone.Stone.Score = stoneEntity.CarryStone.Data:GetScore()
stoneEntity.CarryStone.Stone.CurScore = stoneEntity.CarryStone.Data:GetScore()
end
---@param stoneData XGoldenMinerMapStoneData
---@return XGoldenMinerEntityStone
function XGoldenMinerGame:CreateStoneEntity(stoneData)
---@type XGoldenMinerEntityStone
local stoneEntity = XGoldenMinerEntityStone.New()
stoneEntity.Data = stoneData
stoneEntity.Stone = self:_CreateStoneComponent(stoneData)
stoneEntity.Move = self:_CreateMoveComponent(stoneData, stoneEntity.Stone.Transform)
stoneEntity.Mouse = self:_CreateMouseComponent(stoneData, stoneEntity.Stone.Transform)
stoneEntity.QTE = self:_CreateQTEComponent(stoneData, stoneEntity.Stone.Transform)
stoneEntity.Mussel = self:_CreateMusselComponent(stoneData, stoneEntity.Stone.Transform)
stoneEntity.HookDirectionPoint = self:_CreateDirectionPointComponent(stoneData, stoneEntity.Stone.Transform)
stoneEntity.CarryStone = self:_CreateCarryStone(stoneEntity, stoneEntity.Data:GetCarryStoneId())
-- 注册抓取物间碰撞
self:RegisterStoneHitCallBack(stoneEntity)
self:_RegisterMusselHitCallBack(stoneEntity)
return stoneEntity
end
---@param stoneEntity XGoldenMinerEntityStone
---@return XGoldenMinerEntityStone
function XGoldenMinerGame:_CreateCarryStone(stoneEntity, carryStoneId)
if not stoneEntity.Stone or not stoneEntity.Data:IsHaveCarryStone() then
return false
end
if stoneEntity.Mouse then
stoneEntity.Stone.CarryItemParent = stoneEntity.Mouse.CarryPoint[XGoldenMinerConfigs.GAME_MOUSE_STATE.ALIVE]
elseif stoneEntity.Mussel and stoneEntity.Mussel.GrabCarry then
stoneEntity.Stone.CarryItemParent = stoneEntity.Mussel.GrabCarry
else
stoneEntity.Stone.CarryItemParent = stoneEntity.Stone.Transform
end
if not stoneEntity.Stone.CarryItemParent then
return false
end
---@type XGoldenMinerEntityStone
local carryStone = XGoldenMinerEntityStone.New()
local carryStoneData = XGoldenMinerMapStoneData.New(carryStoneId)
carryStone.Data = carryStoneData
carryStone.Stone = XGoldenMinerComponentStone.New()
carryStone.Stone.Transform = self:_LoadStone(carryStoneData, stoneEntity.Stone.CarryItemParent)
carryStone.Stone.Collider = XUiHelper.TryGetComponent(carryStone.Stone.Transform, "", "Collider2D")
-- 携带物不需要碰撞体
if carryStone.Stone.Collider then
carryStone.Stone.Collider.enabled = false
end
-- 不移动不处理移动方向
if stoneEntity.Move and stoneEntity.Move.MoveType == XGoldenMinerConfigs.StoneMoveType.None
or not stoneEntity.Move then
return carryStone
end
-- 携带物要处理方向
carryStone.Stone.Transform.localScale = Vector3(
carryStone.Stone.Transform.localScale.x * stoneEntity.Data:GetStartMoveDirection(),
carryStone.Stone.Transform.localScale.y,
carryStone.Stone.Transform.localScale.z)
if carryStoneData:GetType() == XGoldenMinerConfigs.StoneType.Boom then -- 爆炸物默认碰撞体关闭
carryStone.Stone.BoomCollider = XUiHelper.TryGetComponent(carryStone.Stone.Transform, "", "CircleCollider2D")
if carryStone.Stone.BoomCollider then
carryStone.Stone.BoomCollider.enabled = false
end
end
return carryStone
end
---@param stoneData XGoldenMinerMapStoneData
---@return XGoldenMinerComponentStone
function XGoldenMinerGame:_CreateStoneComponent(stoneData)
---@type XGoldenMinerComponentStone
local stone = XGoldenMinerComponentStone.New()
stone.Transform = self:_LoadStone(stoneData, self._MapObjRoot)
if not stone.Transform then
XLog.Error("抓取物创建失败!请检查Prefab字段!id="..stoneData:GetId())
end
stone.Collider = XUiHelper.TryGetComponent(stone.Transform, "", "Collider2D")
stone.BornDelayTime = stoneData:GetBornDelay()
stone.AutoDestroyTime = stoneData:GetDestroyTime() > 0 and (stoneData:GetBornDelay() + stoneData:GetDestroyTime()) or 0
stone.BeDestroyTime = 0
stone.HideTime = 0
stone.GoInputHandler = stone.Transform:GetComponent(typeof(CS.XGoInputHandler))
if XTool.UObjIsNil(stone.GoInputHandler) then
stone.GoInputHandler = stone.Transform.gameObject:AddComponent(typeof(CS.XGoInputHandler))
end
if stoneData:GetType() == XGoldenMinerConfigs.StoneType.Boom then -- 爆炸物默认碰撞体关闭
stone.BoomCollider = XUiHelper.TryGetComponent(stone.Transform, "", "CircleCollider2D")
if stone.BoomCollider then
stone.BoomCollider.enabled = false
end
end
return stone
end
---@param stoneData XGoldenMinerMapStoneData
---@param transform UnityEngine.Transform
---@return XGoldenMinerComponentQTE
function XGoldenMinerGame:_CreateQTEComponent(stoneData, transform)
if not stoneData:IsHaveQTE() then
return false
end
---@type XGoldenMinerComponentQTE
local qte = XGoldenMinerComponentQTE.New()
qte.QTEGroupId = stoneData:GetQTEGroupId()
qte.Time = stoneData:GetQTETime()
if self.SystemQTE then
self.SystemQTE:InitQTE(qte, transform)
end
return qte
end
---@param stoneData XGoldenMinerMapStoneData
---@param transform UnityEngine.Transform
---@return XGoldenMinerComponentMussel
function XGoldenMinerGame:_CreateMusselComponent(stoneData, transform)
if not stoneData:IsHaveMussel() then
return false
end
---@type XGoldenMinerComponentMussel
local mussel = XGoldenMinerComponentMussel.New()
mussel.CanHide = true
mussel.IsGrabbed = stoneData:GetMusselIsGrabbed()
mussel.InitIsOpen = stoneData:GetMusselInitIsOpen()
mussel.OpenTime = stoneData:GetMusselOpenTime()
mussel.HideTime = stoneData:GetMusselHideTime()
mussel.AnimOpen = XUiHelper.TryGetComponent(transform, "AnimOpen/Open")
mussel.AnimClose = XUiHelper.TryGetComponent(transform, "AnimClose/Close")
mussel.OpenCollider = XUiHelper.TryGetComponent(transform, "AnimOpen", "Collider2D")
mussel.CloseCollider = XUiHelper.TryGetComponent(transform, "AnimClose", "Collider2D")
mussel.GrabCarry = XUiHelper.TryGetComponent(transform, "UiGoldenMinerBx04/ContentPos")
if not mussel.GrabCarry then
mussel.GrabCarry = XUiHelper.TryGetComponent(transform, "ContentPos")
end
if mussel.InitIsOpen then
mussel.Status = XGoldenMinerConfigs.GAME_MUSSEL_STATUS.OPEN
mussel.CurTime = mussel.OpenTime
else
mussel.Status = XGoldenMinerConfigs.GAME_MUSSEL_STATUS.CLOSE
mussel.CurTime = mussel.HideTime
end
if mussel.AnimOpen then
mussel.AnimOpen.gameObject:SetActiveEx(mussel.Status == XGoldenMinerConfigs.GAME_MUSSEL_STATUS.OPEN)
mussel.AnimClose.gameObject:SetActiveEx(mussel.Status == XGoldenMinerConfigs.GAME_MUSSEL_STATUS.CLOSE)
end
if mussel.OpenCollider then
mussel.OpenCollider.gameObject:SetActiveEx(mussel.Status == XGoldenMinerConfigs.GAME_MUSSEL_STATUS.OPEN)
mussel.OpenGoInputHandler = mussel.OpenCollider.transform:GetComponent(typeof(CS.XGoInputHandler))
if XTool.UObjIsNil(mussel.OpenGoInputHandler) then
mussel.OpenGoInputHandler = mussel.OpenCollider.gameObject:AddComponent(typeof(CS.XGoInputHandler))
end
end
if mussel.CloseCollider then
mussel.CloseCollider.gameObject:SetActiveEx(mussel.Status == XGoldenMinerConfigs.GAME_MUSSEL_STATUS.CLOSE)
mussel.CloseGoInputHandler = mussel.CloseCollider.transform:GetComponent(typeof(CS.XGoInputHandler))
if XTool.UObjIsNil(mussel.CloseGoInputHandler) then
mussel.CloseGoInputHandler = mussel.CloseCollider.gameObject:AddComponent(typeof(CS.XGoInputHandler))
end
end
return mussel
end
---@param stoneData XGoldenMinerMapStoneData
---@param transform UnityEngine.Transform
---@return XGoldenMinerComponentMussel
function XGoldenMinerGame:_CreateMouseComponent(stoneData, transform)
if not (stoneData:GetType() == XGoldenMinerConfigs.StoneType.Mouse) then
return false
end
---@type XGoldenMinerComponentMouse
local component = XGoldenMinerComponentMouse.New()
component.IsBoom = false
component.StateTrans[XGoldenMinerConfigs.GAME_MOUSE_STATE.ALIVE] = XUiHelper.TryGetComponent(transform, "Run")
component.StateTrans[XGoldenMinerConfigs.GAME_MOUSE_STATE.GRABBING] = XUiHelper.TryGetComponent(transform, "Grab")
component.StateTrans[XGoldenMinerConfigs.GAME_MOUSE_STATE.BOOM] = XUiHelper.TryGetComponent(transform, "Bomb")
component.CarryPoint[XGoldenMinerConfigs.GAME_MOUSE_STATE.ALIVE] = XUiHelper.TryGetComponent(transform, "Run/RunCarryItemParent")
component.CarryPoint[XGoldenMinerConfigs.GAME_MOUSE_STATE.GRABBING] = XUiHelper.TryGetComponent(transform, "Grab/GrabCarryItemParent")
return component
end
---@param stoneData XGoldenMinerMapStoneData
---@param transform UnityEngine.Transform
---@return XGoldenMinerComponentDirectionPoint
function XGoldenMinerGame:_CreateDirectionPointComponent(stoneData, transform)
if not stoneData:IsHaveDirectionPoint() then
return false
end
---@type XGoldenMinerComponentDirectionPoint
local directionPoint = XGoldenMinerComponentDirectionPoint.New()
directionPoint.AngleList = stoneData:GetHookDirectionPointAngleList()
directionPoint.AngleTimeList = stoneData:GetHookDirectionPointTimeList()
directionPoint.CurAngleIndex = 1
directionPoint.CurTime = directionPoint.AngleTimeList[directionPoint.CurAngleIndex]
directionPoint.AngleTransform = transform
directionPoint.FillImage = XUiHelper.TryGetComponent(transform, "RImgBg03", "Image")
return directionPoint
end
---@param stoneData XGoldenMinerMapStoneData
---@param transform UnityEngine.Transform
---@return XGoldenMinerComponentMove
function XGoldenMinerGame:_CreateMoveComponent(stoneData, transform)
if not transform or XTool.UObjIsNil(transform) then
return false
end
---@type XGoldenMinerComponentMove
local move = XGoldenMinerComponentMove.New()
move.MoveType = stoneData:GetMoveType()
-- 静止的物体不需要其他参数
if move.MoveType == XGoldenMinerConfigs.StoneMoveType.None then
return move
end
move.StartDirection = stoneData:GetStartMoveDirection()
move.CurDirection = stoneData:GetStartMoveDirection()
move.Speed = stoneData:GetMoveSpeed()
if move.MoveType == XGoldenMinerConfigs.StoneMoveType.Circle then
local x = transform.localPosition.x + stoneData:GetMoveRange() * math.cos(move.StartDirection / 180 * math.pi)
local y = transform.localPosition.y + stoneData:GetMoveRange() * math.sin(move.StartDirection / 180 * math.pi)
move.CircleMovePoint = transform.position
move.StartPoint = Vector3(x, y, 0)
transform:Rotate(0, 0, move.CurDirection - 90)
transform.localPosition = move.StartPoint
else
move.StartPoint = transform.localPosition
local aLimit, bLimit
if move.MoveType == XGoldenMinerConfigs.StoneMoveType.Horizontal then
aLimit = transform.localPosition.x
elseif move.MoveType == XGoldenMinerConfigs.StoneMoveType.Vertical then
aLimit = transform.localPosition.y
end
bLimit = aLimit + move.StartDirection * stoneData:GetMoveRange()
move.MoveMinLimit = math.min(aLimit, bLimit)
move.MoveMaxLimit = math.max(aLimit, bLimit)
end
-- 定春需要处理方向
if stoneData:GetType() == XGoldenMinerConfigs.StoneType.Mouse
and move.MoveType ~= XGoldenMinerConfigs.StoneMoveType.None
and move.MoveType ~= XGoldenMinerConfigs.StoneMoveType.Circle then
transform.localScale = Vector3(
transform.localScale.x * stoneData:GetStartMoveDirection(),
transform.localScale.y,
transform.localScale.z)
end
return move
end
---@param stoneData XGoldenMinerMapStoneData
---@param objRoot UnityEngine.Transform
---@return UnityEngine.Transform
function XGoldenMinerGame:_LoadStone(stoneData, objRoot)
local path = stoneData:GetPrefab()
if string.IsNilOrEmpty(path) or not objRoot or not self._RectSize then
return
end
local resource = self._ResourcePool[path]
if not resource then
resource = CSXResourceManagerLoad(path)
self._ResourcePool[path] = resource
end
if resource == nil or not resource.Asset then
XLog.Error(string.format("XGoldenMinerGame:LoadStone加载资源路径%s", path))
return
end
local obj = XUiHelper.Instantiate(resource.Asset, objRoot)
-- 抓取物的携带物不存在index,直接返回
if not XTool.IsNumberValid(stoneData:GetMapIndex()) then
obj.transform.localPosition = Vector3.zero
return obj.transform
end
local width = self._RectSize.x
local height = self._RectSize.y
local xPosPercent = stoneData:GetXPosPercent() / MILLION_PERCENT
local yPosPercent = stoneData:GetYPosPercent() / MILLION_PERCENT
local scale = stoneData:GetScale() / MILLION_PERCENT
local rotationZ = stoneData:GetRotationZ() / W_PERCENT
obj.transform.localPosition = Vector3(xPosPercent * width, yPosPercent * height, 0)
obj.transform.localScale = Vector3(scale, scale, scale)
obj.transform.localEulerAngles = Vector3(0, 0, rotationZ)
return obj.transform
end
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:RegisterStoneHitCallBack(stoneEntity)
if not stoneEntity or not stoneEntity.Stone.GoInputHandler or XTool.UObjIsNil(stoneEntity.Stone.GoInputHandler) then
return
end
stoneEntity.Stone.GoInputHandler:AddTriggerEnter2DCallback(function(collider)
self:StoneHit(stoneEntity, collider)
end)
end
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:_RegisterMusselHitCallBack(stoneEntity)
if not stoneEntity or not stoneEntity.Mussel or not stoneEntity.Mussel.OpenGoInputHandler then
return
end
stoneEntity.Mussel.OpenGoInputHandler:AddTriggerEnter2DCallback(function(collider)
self:StoneHit(stoneEntity, collider)
end)
stoneEntity.Mussel.CloseGoInputHandler:AddTriggerEnter2DCallback(function(collider)
self:StoneHit(stoneEntity, collider)
end)
end
---@param stoneEntity XGoldenMinerEntityStone
---@param collider UnityEngine.Collider2D
function XGoldenMinerGame:StoneHit(stoneEntity, collider)
local beHitStoneEntity = self:FindStoneEntityByCollider(collider)
if self.SystemStone then
self.SystemStone:OnStoneHit(stoneEntity, beHitStoneEntity)
end
end
---@param collider UnityEngine.Collider2D
function XGoldenMinerGame:FindStoneEntityByCollider(collider)
if XTool.IsTableEmpty(self.StoneEntityList) then
return false
end
for _, entity in ipairs(self.StoneEntityList) do
if entity.Stone.Transform and entity.Stone.Transform == collider.transform then
return entity
end
if entity.Mussel then
if entity.Mussel.OpenCollider and entity.Mussel.OpenCollider == collider then
return entity
end
if entity.Mussel.CloseCollider and entity.Mussel.CloseCollider == collider then
return entity
end
end
if entity.CarryStone
and entity.CarryStone.Stone.Transform
and entity.CarryStone.Stone.Transform == collider.transform then
return entity
end
end
return false
end
---@param stoneEntity XGoldenMinerEntityStone
---@param status number XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS
function XGoldenMinerGame:SetStoneEntityStatus(stoneEntity, status)
self.SystemStone:SetStoneEntityStatus(stoneEntity, status)
end
---@param hookEntity XGoldenMinerEntityHook
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:SetStoneGrab(hookEntity, stoneEntity)
hookEntity.HookGrabbingStoneList[#hookEntity.HookGrabbingStoneList + 1] = stoneEntity
self.SystemHook:HookGrab(self, hookEntity.Hook, stoneEntity)
self:SetStoneEntityStatus(stoneEntity, XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS.GRABBING)
end
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:SetCarryStoneBoom(stoneEntity)
if not stoneEntity.CarryStone then
return
end
if stoneEntity.CarryStone.Stone.BoomCollider then
stoneEntity.CarryStone.Stone.BoomCollider.enabled = true
XEventManager.DispatchEvent(XEventId.EVENT_GOLDEN_MINER_GAME_PLAY_EFFECT,
XGoldenMinerConfigs.GAME_EFFECT_TYPE.STONE_BOOM,
stoneEntity.CarryStone.Stone.Transform,
stoneEntity.CarryStone.Data:GetCatchEffect())
end
end
---@param stoneType number XGoldenMinerConfigs.StoneType
---@param stoneStatusType number XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS
---@return XGoldenMinerEntityStone[]
function XGoldenMinerGame:GetStoneEntityList(stoneType, stoneStatusType)
local result = {}
for _, stoneEntity in ipairs(self.StoneEntityList) do
if (not stoneStatusType or stoneEntity.Status == stoneStatusType) and
(not stoneType or stoneEntity.Data:GetType() == stoneType) then
result[#result + 1] = stoneEntity
end
end
return result
end
--endregion
--region System - QTE
---@param hookEntity XGoldenMinerEntityHook
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:QTEStart(hookEntity, stoneEntity)
if self:IsEnd() or self:IsPause() then
return
end
if self:IsQTE() then
if self.QTEHookEntity and self.QTEHookEntity ~= hookEntity
and self.QTEStoneEntity and self.QTEStoneEntity ~= stoneEntity
and not table.indexof(self.QTECatchHookEntityList, hookEntity)
and not table.indexof(self.QTECatchStoneEntityList, stoneEntity)
then
self.QTECatchHookEntityList[#self.QTECatchHookEntityList + 1] = hookEntity
self.QTECatchStoneEntityList[#self.QTECatchStoneEntityList + 1] = stoneEntity
end
return
end
if not self:IsQTE() then
self._QTECatchStatus = self._Status
end
self.QTEHookEntity = hookEntity
self.QTEStoneEntity = stoneEntity
self._Status = GAME_STATUS.QTE
end
function XGoldenMinerGame:QTEResume()
if self:IsEnd() or self:IsPause() then
return
end
if self._QTECatchStatus == GAME_STATUS.NONE then
return
end
self._Status = self._QTECatchStatus
end
function XGoldenMinerGame:UpdateQTE(time)
if self:IsEnd() then
return
end
if self.SystemQTE then
self.SystemQTE:Update(self, time)
end
end
function XGoldenMinerGame:QTEClick()
if not self:IsQTE() then
return
end
if self.SystemQTE then
self.SystemQTE:ClickQTE(self)
end
end
function XGoldenMinerGame:QTECrab()
if not self:IsQTE() then
return
end
local QTE = self.QTEStoneEntity.QTE
local qteId = XGoldenMinerConfigs.GetQTELevelGroupByCount(QTE.QTEGroupId, QTE.CurClickCount)
local params = XGoldenMinerConfigs.GetQTELevelGroupParams(qteId)
local type = XGoldenMinerConfigs.GetQTELevelGroupType(qteId)
if type == XGoldenMinerConfigs.QTEGroupType.Score then
QTE.AddScore = params[1]
elseif type == XGoldenMinerConfigs.QTEGroupType.Item then
QTE.AddItemId = params[1]
elseif type == XGoldenMinerConfigs.QTEGroupType.Buff then
QTE.AddBuff = params[1]
elseif type == XGoldenMinerConfigs.QTEGroupType.ScoreAndBuff then
QTE.AddScore = params[1]
QTE.AddBuff = params[2]
elseif type == XGoldenMinerConfigs.QTEGroupType.ScoreAndItem then
QTE.AddScore = params[1]
QTE.AddItemId = params[2]
elseif type == XGoldenMinerConfigs.QTEGroupType.BuffAndItem then
QTE.AddBuff = params[1]
QTE.AddItemId = params[2]
elseif type == XGoldenMinerConfigs.QTEGroupType.All then
QTE.AddScore = params[1]
QTE.AddBuff = params[2]
QTE.AddItemId = params[3]
end
if self.QTEHookEntity then
-- 状态不对过滤
if self.QTEHookEntity.Hook.Type == XGoldenMinerConfigs.FalculaType.Magnetic
or self.QTEHookEntity.Hook.Type == XGoldenMinerConfigs.FalculaType.StorePressMagnetic then
self:SetStoneGrab(self.QTEHookEntity, self.QTEStoneEntity)
else
self:HookGrab(self.QTEHookEntity, self.QTEStoneEntity)
end
end
self.QTEHookEntity = false
self.QTEStoneEntity = false
self:QTEResume()
self:QTECheck()
end
function XGoldenMinerGame:QTECheck()
if XTool.IsTableEmpty(self.QTECatchHookEntityList) then
return
end
local hookEntity = self.QTECatchHookEntityList[1]
local stoneEntity = self.QTECatchStoneEntityList[1]
local newHookList = {}
local newStoneList = {}
for i = 2, #self.QTECatchHookEntityList do
newHookList[#newHookList + 1] = self.QTECatchHookEntityList[i]
newStoneList[#newStoneList + 1] = self.QTECatchStoneEntityList[i]
end
self.QTECatchHookEntityList = newHookList
self.QTECatchStoneEntityList = newStoneList
self:QTEStart(hookEntity, stoneEntity)
end
--endregion
--region System - TimeLineAnim
function XGoldenMinerGame:InitTimeLineAnim()
for _, entity in ipairs(self.HookEntityList) do
entity.Anim = self:_CreateAnimComponent(entity.Hook.Transform)
end
for _, entity in ipairs(self.StoneEntityList) do
if entity.Data:GetType() == XGoldenMinerConfigs.StoneType.Mouse then
entity.Anim = self:_CreateAnimComponent(entity.Stone.Transform)
end
end
end
function XGoldenMinerGame:UpdateTimeLineAnim(time)
if self:IsEnd() then
return
end
if self.SystemTimeLimeAnim then
self.SystemTimeLimeAnim:Update(self, time)
end
end
---@param transform UnityEngine.Transform
---@return XGoldenMinerComponentTimeLineAnim
function XGoldenMinerGame:_CreateAnimComponent(transform)
if not transform or XTool.UObjIsNil(transform) then
return false
end
---@type XGoldenMinerComponentTimeLineAnim
local anim = XGoldenMinerComponentTimeLineAnim.New()
anim.AnimRoot = XUiHelper.TryGetComponent(transform, "Animation")
anim.CurAnim = XGoldenMinerConfigs.GAME_ANIM.NONE
anim.FinishCallBack = false
anim.BePlayAnim = XGoldenMinerConfigs.GAME_ANIM.NONE
anim.BeFinishCallBack = false
return anim
end
--endregion
--region System - Buff&Item
function XGoldenMinerGame:InitBuff()
if self.SystemBuff then
self.SystemBuff:Init(self)
end
end
function XGoldenMinerGame:UpdateBuff(time)
if self:IsEnd() then
return
end
if self.SystemBuff then
self.SystemBuff:Update(self, time)
end
end
---@return table<number, XGoldenMinerComponentBuff[]>
function XGoldenMinerGame:GetBuffDir()
return self.BuffContainer.BuffTypeDir
end
function XGoldenMinerGame:CheckHasBuff(buffType)
if self.SystemBuff then
return self.SystemBuff:CheckHasBuff(self.BuffContainer, buffType)
end
return false
end
function XGoldenMinerGame:CheckHasBuffByBuffId(buffId)
if self.SystemBuff then
return self.SystemBuff:CheckHasBuffByBuffId(self.BuffContainer, XGoldenMinerConfigs.GetBuffType(buffId), buffId)
end
return false
end
function XGoldenMinerGame:CheckItemCanUse(itemId)
if not self:IsPlay() and not self:IsTimeStop() then
return
end
local buffId = XGoldenMinerConfigs.GetItemBuffId(itemId)
local type = XGoldenMinerConfigs.GetBuffType(buffId)
if type == XGoldenMinerConfigs.BuffType.GoldenMinerBoom
or type == XGoldenMinerConfigs.BuffType.GoldenMinerStoneChangeGold
then
local result = false
for _, hookEntity in ipairs(self.HookEntityList) do
if not XTool.IsTableEmpty(hookEntity.HookGrabbingStoneList) then
for _, stoneEntity in ipairs(hookEntity.HookGrabbingStoneList) do
if stoneEntity.Status == XGoldenMinerConfigs.GAME_GRAB_OBJ_STATUS.GRABBING then
result = true
end
end
end
end
return result
elseif type == XGoldenMinerConfigs.BuffType.GoldenMinerTypeBoom then
for _, stoneEntity in ipairs(self.StoneEntityList) do
if stoneEntity.Data:GetType() == XGoldenMinerConfigs.GetBuffParams(buffId)[1] then
return true
end
end
return false
end
return true
end
function XGoldenMinerGame:UseItemToAddBuff(itemId)
local characterBuffList = XGoldenMinerConfigs.GetCharacterBuffIds(self._Data:GetCurCharacterId())
local itemBuffId = XGoldenMinerConfigs.GetItemBuffId(itemId)
for _, buffId in pairs(characterBuffList) do
-- 使用道具时停
if XGoldenMinerConfigs.GetBuffType(buffId) == XGoldenMinerConfigs.BuffType.GoldenMinerUseItemStopTime then
self:AddBuff(buffId)
end
-- 使用道具加时
if XGoldenMinerConfigs.GetBuffType(buffId) == XGoldenMinerConfigs.BuffType.GoldenMinerUseItemAddTime then
self:AddBuff(buffId)
end
end
-- 使用炸弹道具加分
if XGoldenMinerConfigs.GetBuffType(itemBuffId) == XGoldenMinerConfigs.BuffType.GoldenMinerBoom then
self:CheckAndTriggerBuff(XGoldenMinerConfigs.BuffType.GoldenMinerBoomGetScore)
end
self:AddBuff(XGoldenMinerConfigs.GetItemBuffId(itemId))
end
function XGoldenMinerGame:AddBuff(buffId)
if self.SystemBuff then
self.SystemBuff:AddBuffById(self.BuffContainer, buffId)
end
end
function XGoldenMinerGame:CheckAndTriggerBuff(buffType)
if not self.SystemBuff then
return false
end
if not self:CheckHasBuff(buffType) then
return false
end
local result = false
for _, buff in ipairs(self.BuffContainer.BuffTypeDir[buffType]) do
if self.SystemBuff:CheckBuffIsAlive(buff) then
if buff.TimeType == XGoldenMinerConfigs.BuffTimeType.Count then
local isTrigger = self.SystemBuff:TriggerCountBuff(buff)
result = result or isTrigger
elseif buff.TimeType == XGoldenMinerConfigs.BuffTimeType.Global then
self.SystemBuff:TriggerGlobalRoleSkillBuff(self, buff)
end
end
end
return result
end
---触发回收时次数型Buff
function XGoldenMinerGame:TriggerCountRevokeEndCountBuff()
-- 按次数生效的回收速度buff
self:CheckAndTriggerBuff(XGoldenMinerConfigs.BuffType.GoldenMinerShortenSpeed)
-- 防爆次数触发
self:CheckAndTriggerBuff(XGoldenMinerConfigs.BuffType.GoldenMinerNotActiveBoom)
end
---触发抓到炸弹时Buff
function XGoldenMinerGame:TriggerCountGrabBoomCountBuff()
return self:CheckAndTriggerBuff(XGoldenMinerConfigs.BuffType.GoldenMinerNotActiveBoom)
end
---@param stoneType number
function XGoldenMinerGame:TriggerStoneHitBuff(stoneType)
if stoneType == XGoldenMinerConfigs.StoneType.Boom then
self:CheckAndTriggerBuff(XGoldenMinerConfigs.BuffType.GoldenMinerBoomGetScore)
end
end
---@param stoneEntity XGoldenMinerEntityStone
function XGoldenMinerGame:TriggerStoneGrabBuff(stoneEntity)
if stoneEntity.Data:GetType() == XGoldenMinerConfigs.StoneType.Mouse then
self:CheckAndTriggerBuff(XGoldenMinerConfigs.BuffType.GoldenMinerMouseGetItem)
elseif stoneEntity.Data:GetType() == XGoldenMinerConfigs.StoneType.QTE then
self:CheckAndTriggerBuff(XGoldenMinerConfigs.BuffType.GoldenMinerQTEGetScore)
end
end
--endregion
--region EventListener
function XGoldenMinerGame:AddEventListener()
XEventManager.AddEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_PAUSE, self.Pause, self)
XEventManager.AddEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_RESUME, self.Resume, self)
XEventManager.AddEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_QTE_START, self.QTEStart, self)
XEventManager.AddEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_QTE_END, self.QTECrab, self)
XEventManager.AddEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_HOOK_HIT, self.TriggerStoneHitBuff, self)
end
function XGoldenMinerGame:RemoveEventListener()
XEventManager.RemoveEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_PAUSE, self.Pause, self)
XEventManager.RemoveEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_RESUME, self.Resume, self)
XEventManager.RemoveEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_QTE_START, self.QTEStart, self)
XEventManager.RemoveEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_QTE_END, self.QTECrab, self)
XEventManager.RemoveEventListener(XEventId.EVENT_GOLDEN_MINER_GAME_HOOK_HIT, self.TriggerStoneHitBuff, self)
end
--endregion
return XGoldenMinerGame