Files
SL1900 eafd8f4088 Update - 1.9.0.107
EN: 1.9.0.107
CN: 1.9.0.108
JP: 1.9.0.112
KR: 1.9.0.112
2026-05-14 16:00:00 +09:00

2275 lines
87 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
local ThrowGiftsLevelCtrl = class("ThrowGiftsLevelCtrl", BaseCtrl)
local GameResourceLoader = require("Game.Common.Resource.GameResourceLoader")
local ResTypeAny = GameResourceLoader.ResType.Any
local WwiseAudioMgr = CS.WwiseAudioManager.Instance
local nMarkWidth = 36
local nMarkHeight = 56
ThrowGiftsLevelCtrl._mapNodeConfig = {
Scene = {sComponentName = "Transform"},
rtScene = {
sNodeName = "Scene",
sComponentName = "RectTransform"
},
rtGoalRoot = {sComponentName = "Transform"},
rtObstacleRoot = {sComponentName = "Transform"},
rtSpecialObstacleRoot = {sComponentName = "Transform"},
rtBeginning = {
sComponentName = "RectTransform"
},
rttBeginningDrag = {
sComponentName = "UIDrag",
callback = "OnDrag_Beginning"
},
rtBeginningLine = {
sComponentName = "RectTransform"
},
rtPenguinRoot = {sComponentName = "Transform"},
BeginningDot = {
sComponentName = "RectTransform",
sNodeName = "imgBeginningDot_",
nCount = 30
},
templateBullet = {},
rtBeginningPos = {
sComponentName = "RectTransform"
},
rtBottle = {
sComponentName = "RectTransform"
},
rtBottleAnim = {sComponentName = "Animator", sNodeName = "rtBottle"},
BeginningPenguinRoot = {sComponentName = "Animator"},
rtBlindLevelTrack = {
sCtrlName = "Game.UI.Activity.ThrowGifts.ThrowGiftLevelTrackLineCtrl"
},
rtTemplateTrack = {},
TMPBeginningCountHint = {sComponentName = "TMP_Text"},
imgBeginningHint = {},
rtPenguinBeginningHint = {sComponentName = "Transform"},
rtPenguinBeginningHintAnim = {
sNodeName = "rtPenguinBeginningHint",
sComponentName = "Animator"
},
imgInfinite = {},
penguinRoot = {},
rtTemplateGuideTrack = {},
goBeginningMark = {},
rtBeginningMark = {
sComponentName = "RectTransform"
},
rtDebug = {}
}
ThrowGiftsLevelCtrl._mapEventConfig = {}
ThrowGiftsLevelCtrl._mapRedDotConfig = {}
function ThrowGiftsLevelCtrl:Awake()
self.bDebugMode = false
self.curGiftPenguin = nil
self.nLevelType = 0
self.tbObstacle = {}
self.mapGoal = {}
self.tbGiftPenguin = {}
self.sceneSize = {0, 0}
self.scenePivot = {0, 0}
self.mapItemPoolConfig = {}
self.activeGoal = {}
self.nTotalPenguinCount = -1
self.curPenguinIdx = 1
self.curPenguinType = 1
self.nNextPenguinType = 1
self.curPenguinSpecialType = 0
self.defaultPenguinSpecialType = 0
self.nLevelTime = -1
self.nLevelScore = 0
self.nTotalThrowGiftCount = 0
self.nTotalHitGoalCount = 0
self.nTotalUseItemCount = 0
self.mapItemUseCount = {}
self.bProcessing = false
self.mapExObstacleOrigin = {}
self.tbExObstacleCur = {}
self.bFlying = false
self.nFlyingTime = 0
self.maxVelocity = 1200
self.minVelovity = 400
self.nLinePointInterval = 0.05
self.nGoalSpeed = 100
self.nAngelMax = 90
self.nAngleMin = -30
self.nAG = 500
self.nNavigationPenguinSpeed = 600
self.nCurActiveItem = 0
self.mapCurActiveState = {}
self.tbItemTrackCtrl = {}
self.tbGuideTrackCtrl = {}
self.curDragBeginPos = nil
self.dragState = false
self._mapNode.rtBeginningLine.gameObject:SetActive(false)
self._mapNode.templateBullet.gameObject:SetActive(false)
self._mapNode.imgBeginningHint:SetActive(false)
local forEachItemPool = function(mapData)
if self.mapItemPoolConfig[mapData.PoolId] == nil then
self.mapItemPoolConfig[mapData.PoolId] = {}
end
table.insert(self.mapItemPoolConfig[mapData.PoolId], {
nItemId = mapData.ItemId,
Weight = mapData.Weight
})
end
ForEachTableLine(DataTable.ThrowGiftItemPool, forEachItemPool)
end
function ThrowGiftsLevelCtrl:FadeIn()
end
function ThrowGiftsLevelCtrl:FadeOut()
end
function ThrowGiftsLevelCtrl:OnEnable()
self.rootPath = self._panel._rootPath
EventManager.Hit("ThrowGiftSetSpeacialFunc", self)
self._mapNode.BeginningPenguinRoot.gameObject:SetActive(false)
self._mapNode.penguinRoot:SetActive(false)
self._mapNode.rtBottleAnim:Play("rtBottle_Empty")
self._mapNode.goBeginningMark:SetActive(false)
end
function ThrowGiftsLevelCtrl:OnDisable()
if self.beginningTweener ~= nil then
self.beginningTweener:Kill()
self.beginningTweener = nil
end
if self.mapUpdateTimer ~= nil then
self.mapUpdateTimer:Cancel()
self.mapUpdateTimer = nil
end
self:ClearTrackLine()
if self.tbGuideTrackCtrl ~= nil and #self.tbGuideTrackCtrl ~= 0 then
self:ClearGuideLine()
end
end
function ThrowGiftsLevelCtrl:OnDestroy()
end
function ThrowGiftsLevelCtrl:OnRelease()
end
function ThrowGiftsLevelCtrl:ClearTrackLine()
for _, mapCtrl in ipairs(self.tbItemTrackCtrl) do
mapCtrl:DestroyAll()
self:UnbindCtrlByNode(mapCtrl)
end
self._mapNode.rtBlindLevelTrack:DestroyAll()
self.tbItemTrackCtrl = {}
end
function ThrowGiftsLevelCtrl:ClearGuideLine()
for _, mapCtrl in ipairs(self.tbGuideTrackCtrl) do
mapCtrl:DestroyAll()
self:UnbindCtrlByNode(mapCtrl)
end
self.tbGuideTrackCtrl = {}
end
function ThrowGiftsLevelCtrl:SetLevel(parent, nLevelId, mapActData)
self.nLevelScore = 0
self.parent = parent
self.actData = mapActData
self.nLevelId = nLevelId
self.mapItemUseCount = {}
local mapLevelCfgData = ConfigTable.GetData("ThrowGiftLevel", nLevelId)
if mapLevelCfgData == nil then
return
end
self.mapLevelCfgData = mapLevelCfgData
local mapFloorCfgData = ConfigTable.GetData("ThrowGiftFloor", self.mapLevelCfgData.FloorId)
if mapFloorCfgData == nil then
return
end
self.defaultPenguinSpecialType = self.mapLevelCfgData.DefaultPenguinItemId
self.maxVelocity = mapFloorCfgData.SpeedMax
self.minVelovity = mapFloorCfgData.SpeedMin
self.nAngleMin = mapFloorCfgData.AngelMin
self.nAG = mapFloorCfgData.Gravity
if self.mapLevelCfgData.FlightPath == true then
self._mapNode.rtBlindLevelTrack.gameObject:SetActive(true)
end
self.mapFloorCfgData = mapFloorCfgData
self.nTotalPenguinCount = self.mapFloorCfgData.GiftNum
if self.nTotalPenguinCount == 0 then
self.nTotalPenguinCount = -1
end
self.nLevelTime = self.mapLevelCfgData.CountDownLimit
if self.nLevelTime == 0 then
self.nLevelTime = -1
end
self.curPenguinIdx = 1
self.sceneSize = {
self._mapNode.Scene.rect.width,
self._mapNode.Scene.rect.height
}
self.scenePivot = {
self._mapNode.Scene.pivot.x,
self._mapNode.Scene.pivot.y
}
local rtView = self.gameObject:GetComponent("RectTransform")
self.viewSize = {0, 0}
if rtView ~= nil then
self.viewSize = {
rtView.rect.width,
rtView.rect.height
}
end
self._mapNode.rtDebug:SetActive(self.bDebugMode)
local nStaticChildCount = self._mapNode.rtObstacleRoot.childCount
for i = 0, nStaticChildCount - 1 do
local goObstacle = self._mapNode.rtObstacleRoot:GetChild(i)
if goObstacle ~= nil then
local rtObstacle = goObstacle:GetComponent("RectTransform")
if rtObstacle ~= nil then
local tbBounds = self:GetLocalSpaceRect(rtObstacle, rtObstacle.parent)
table.insert(self.tbObstacle, tbBounds)
print(tbBounds[1] .. " " .. tbBounds[2] .. " " .. tbBounds[3] .. " " .. tbBounds[4] .. " ")
end
end
end
local nSpecialChildCount = self._mapNode.rtSpecialObstacleRoot.childCount
for i = 0, nSpecialChildCount - 1 do
local goObstacle = self._mapNode.rtSpecialObstacleRoot:GetChild(i)
if goObstacle ~= nil then
local rtObstacle = goObstacle:GetComponent("RectTransform")
if rtObstacle ~= nil then
local sName = rtObstacle.gameObject.name
local nId = tonumber(sName)
if nId == nil then
printError("Special obstacl name error!" .. sName)
else
local mapExObstacleCfgData = ConfigTable.GetData("ThrowGiftSpecialObstacle", nId)
if mapExObstacleCfgData ~= nil then
local nInstanceId = rtObstacle.gameObject:GetInstanceID()
self.mapExObstacleOrigin[nInstanceId] = {}
local tbBounds = self:GetLocalSpaceRect(rtObstacle, rtObstacle.parent)
self.mapExObstacleOrigin[nInstanceId].tbBounds = tbBounds
self.mapExObstacleOrigin[nInstanceId].mapConfig = mapExObstacleCfgData
self.mapExObstacleOrigin[nInstanceId].gameObject = rtObstacle.gameObject
table.insert(self.tbExObstacleCur, nInstanceId)
print(tbBounds[1] .. " " .. tbBounds[2] .. " " .. tbBounds[3] .. " " .. tbBounds[4] .. " ")
end
end
end
end
end
local nGoalSpawnpointCount = self._mapNode.rtGoalRoot.childCount
for i = 0, nGoalSpawnpointCount - 1 do
local goGoalSpawnpoint = self._mapNode.rtGoalRoot:GetChild(i)
if goGoalSpawnpoint ~= nil then
local sName = goGoalSpawnpoint.gameObject.name
local nId = tonumber(sName)
if nId == nil then
printError("配置错误 无法转换为ID:" .. sName)
else
local mapSpConfig = ConfigTable.GetData("ThrowGiftSpawnPoints", nId)
if mapSpConfig ~= nil then
self.mapGoal[nId] = {}
self.mapGoal[nId].rtPoint = goGoalSpawnpoint
self.mapGoal[nId].mapConfig = mapSpConfig
self.mapGoal[nId].tbExtractedItems = {}
local nItemPoolId = mapSpConfig.ItemPool
self.mapGoal[nId].tbOrginPool = self.mapItemPoolConfig[nItemPoolId] == nil and {} or clone(self.mapItemPoolConfig[nItemPoolId])
self.mapGoal[nId].curCondId = {}
self.mapGoal[nId].nCurGoalIdx = 1
self.mapGoal[nId].VxDir = 1
self.mapGoal[nId].VyDir = 1
end
end
end
end
for nSpawnPointId, mapConfigData in pairs(self.mapGoal) do
if mapConfigData.mapConfig.InitShow then
self:CreateGoal(nSpawnPointId, mapConfigData)
end
end
if self.mapUpdateTimer ~= nil then
self.mapUpdateTimer:Cancel()
self.mapUpdateTimer = nil
end
self.mapUpdateTimer = self:AddTimer(0, 0, "OnUpdate", true, true, true)
if 0 < #mapFloorCfgData.GuideLine then
for _, nGuideLineId in ipairs(mapFloorCfgData.GuideLine) do
local mapGuideLineData = ConfigTable.GetData("ThrowGiftGuideLine", nGuideLineId)
if mapGuideLineData ~= nil then
local rtTrack = instantiate(self._mapNode.rtTemplateGuideTrack, self._mapNode.rtScene)
rtTrack.transform:SetAsFirstSibling()
rtTrack:SetActive(true)
local mapTrackCtrl = self:BindCtrlByNode(rtTrack.gameObject, "Game.UI.Activity.ThrowGifts.ThrowGiftLevelGuideTrackLineCtrl")
mapTrackCtrl:InitLine(mapGuideLineData, self._mapNode.rtBeginning.anchoredPosition, self.nAG, self.maxVelocity)
table.insert(self.tbGuideTrackCtrl, mapTrackCtrl)
end
end
end
end
function ThrowGiftsLevelCtrl:FlyOver(nDelayTime, tbHitGoalId)
self.nLevelType = 0
self.bProcessing = true
local waitAnim = function()
if self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.ThrowCount or self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.ThrowCountAfterTime then
self.parent:SetTarget(self.nTotalThrowGiftCount)
elseif self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.Score or self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.ScoreAfterTime then
self.parent:SetTarget(self.nLevelScore)
elseif self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.HitCount or self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.HitCountAfterTime then
self.parent:SetTarget(self.nTotalHitGoalCount)
end
if self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.ThrowCount then
self.parent:SetTarget(self.nTotalThrowGiftCount)
if self.nTotalThrowGiftCount >= self.mapLevelCfgData.throwGiftLevelParams then
self:LevelEnd(true, 0)
return
end
elseif self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.Score then
self.parent:SetTarget(self.nLevelScore)
if self.nLevelScore >= self.mapLevelCfgData.throwGiftLevelParams then
self:LevelEnd(true, 0)
return
end
elseif self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.HitCount then
self.parent:SetTarget(self.nTotalHitGoalCount)
if self.nTotalHitGoalCount >= self.mapLevelCfgData.throwGiftLevelParams then
self:LevelEnd(true, 0)
return
end
end
if self.nTotalPenguinCount ~= 0 then
self.beginningTweener = DOTween.To(function()
return self._mapNode.rtBottle.localEulerAngles.z - 360
end, function(v)
self._mapNode.rtBottle.localEulerAngles = Vector3(0, 0, v)
end, 0, 0.5):OnComplete(function()
self:SetBeginningAngle(0, 0)
NovaAPI.SetTMPText(self._mapNode.TMPBeginningCountHint, self.nTotalPenguinCount)
if self.curPenguinIdx > #self.mapFloorCfgData.InitialGiftSort then
if 0 < #self.mapFloorCfgData.GiftRandom then
self.curPenguinType = self.nNextPenguinType
else
self.curPenguinType = 1
end
else
self.curPenguinType = self.mapFloorCfgData.InitialGiftSort[self.curPenguinIdx]
end
self.curPenguinIdx = self.curPenguinIdx + 1
self._mapNode.BeginningPenguinRoot.gameObject:SetActive(true)
self._mapNode.rtBottleAnim:Play("rtBottle_in")
self._mapNode.BeginningPenguinRoot:Play("penguinRoot_jump")
WwiseAudioMgr:PostEvent("Mode_Present_shylock_jump")
local nSpecialType = self.curPenguinSpecialType == 0 and self.defaultPenguinSpecialType or self.curPenguinSpecialType
self:SetPenguinType(self._mapNode.BeginningPenguinRoot.transform, self.curPenguinType, nSpecialType)
self:SetPenguinType(self._mapNode.rtBottle:Find("AnimRoot/penguinRoot"), self.curPenguinType, nSpecialType)
self:SetBeginningAngle(0, 0)
local wait = function()
self._mapNode.imgBeginningHint:SetActive(true)
local nCurSpecialType = self.curPenguinSpecialType == 0 and self.defaultPenguinSpecialType or self.curPenguinSpecialType
self:SetPenguinType(self._mapNode.rtPenguinBeginningHint, self.curPenguinType, nCurSpecialType)
if self.nTotalPenguinCount ~= 0 then
self._mapNode.BeginningPenguinRoot.gameObject:SetActive(true)
self._mapNode.BeginningPenguinRoot:Play("penguinRoot_in")
WwiseAudioMgr:PostEvent("Mode_Present_shylock")
self.nNextPenguinType = 1
if self.curPenguinIdx > #self.mapFloorCfgData.InitialGiftSort then
if 0 < #self.mapFloorCfgData.GiftRandom then
self.nNextPenguinType = self.mapFloorCfgData.GiftRandom[math.random(#self.mapFloorCfgData.GiftRandom)]
else
self.nNextPenguinType = 1
end
else
self.nNextPenguinType = self.mapFloorCfgData.InitialGiftSort[self.curPenguinIdx]
end
self:SetPenguinType(self._mapNode.BeginningPenguinRoot.transform, self.nNextPenguinType, self.defaultPenguinSpecialType)
else
self._mapNode.BeginningPenguinRoot.gameObject:SetActive(false)
end
end
local waitAnimEnd = function()
self.nLevelType = 1
if self.mapLevelCfgData.SwitchArrow == true then
self.parent:SetViewBtn(1)
end
end
self:AddTimer(1, 0.5, wait, true, true, true)
self:AddTimer(1, 1, waitAnimEnd, true, true, true)
end)
else
self._mapNode.BeginningPenguinRoot.gameObject:SetActive(false)
self:LevelEnd(false, 1)
return
end
local bNeedProcessingItem = false
if tbHitGoalId ~= nil and 0 < #tbHitGoalId then
local tbItemsRandom = {}
local tbSpawnPointData = {}
for _, HitGoalId in ipairs(tbHitGoalId) do
local mapSpawnPointData = self.mapGoal[HitGoalId]
if mapSpawnPointData ~= nil and 0 < #mapSpawnPointData.tbOrginPool then
local tbCurPool = {}
if mapSpawnPointData.mapConfig.PoolType then
for _, mapItemData in ipairs(mapSpawnPointData.tbOrginPool) do
if 1 > table.indexof(mapSpawnPointData.tbExtractedItems, mapItemData.nItemId) then
table.insert(tbCurPool, mapItemData)
end
end
if #tbCurPool < 2 then
tbCurPool = {}
mapSpawnPointData.tbExtractedItems = {}
for _, mapItemData in ipairs(mapSpawnPointData.tbOrginPool) do
table.insert(tbCurPool, mapItemData)
end
end
else
for _, mapItemData in ipairs(mapSpawnPointData.tbOrginPool) do
table.insert(tbCurPool, mapItemData)
end
end
local tbItems = {}
for i = 1, 2 do
local selected = 0
local totalWeight = 0
for _, mapItemData in ipairs(tbCurPool) do
totalWeight = totalWeight + mapItemData.Weight
end
local random = math.random(0, totalWeight)
local curWeight = 0
for nIdx, mapItemData in ipairs(tbCurPool) do
curWeight = curWeight + mapItemData.Weight
if random <= curWeight then
table.insert(tbItems, mapItemData.nItemId)
selected = nIdx
break
end
end
table.remove(tbCurPool, selected)
end
if 0 < #tbItems then
table.insert(tbItemsRandom, tbItems)
table.insert(tbSpawnPointData, mapSpawnPointData)
end
end
end
if 0 < #tbItemsRandom then
do
local callback = function(tbIdx)
self:Pause(false)
self.bProcessing = false
for i = 1, #tbItemsRandom do
local nIdx = tbIdx[i]
local mapSpawnPointData = tbSpawnPointData[i]
if mapSpawnPointData ~= nil and mapSpawnPointData.mapConfig.PoolType then
table.insert(mapSpawnPointData.tbExtractedItems, tbItemsRandom[i][nIdx])
end
end
end
bNeedProcessingItem = true
self.parent:OpenItemSelect(tbItemsRandom, callback)
self:Pause(true)
end
end
end
if not bNeedProcessingItem then
self.bProcessing = false
end
local rtScenePos = self._mapNode.rtScene.anchoredPosition
self._mapNode.rtScene.anchoredPosition = Vector2(0, rtScenePos.y)
for nInstanceId, mapConfig in pairs(self.mapExObstacleOrigin) do
if mapConfig.mapConfig.Reset and table.indexof(self.tbExObstacleCur, nInstanceId) < 1 then
table.insert(self.tbExObstacleCur, nInstanceId)
mapConfig.gameObject:SetActive(true)
end
end
end
if nDelayTime == nil or nDelayTime == 0 then
waitAnim()
else
self:AddTimer(1, nDelayTime, waitAnim, true, true, true)
end
end
function ThrowGiftsLevelCtrl:LevelEnd(bPass, nCond)
if self.mapUpdateTimer ~= nil then
self.mapUpdateTimer:Cancel()
self.mapUpdateTimer = nil
end
self.parent:LevelEnd()
local bShowPenguin = false
if bPass and self.mapFloorCfgData.GiftNum > 0 then
self.nLevelScore = self.nLevelScore + 20 * math.max(0, self.nTotalPenguinCount)
bShowPenguin = true
end
local openSettle = function(changeInfo)
self.parent:OpenSettle(bPass, self.nLevelScore, self.nTotalHitGoalCount, self.nTotalPenguinCount, bShowPenguin, changeInfo)
end
if self.actData ~= nil then
local tbUseItems = {}
for nItemId, nCount in pairs(self.mapItemUseCount) do
table.insert(tbUseItems, {ItemId = nItemId, Count = nCount})
end
self.actData:SettleLevels(self.nLevelId, self.nTotalThrowGiftCount, self.nTotalHitGoalCount, self.nLevelScore, tbUseItems, bPass, openSettle)
else
openSettle()
end
end
function ThrowGiftsLevelCtrl:Pause(bPause)
if bPause then
WwiseAudioMgr:PostEvent("Mode_Present_sidechain_in")
else
WwiseAudioMgr:PostEvent("Mode_Present_sidechain_out")
end
if self.mapUpdateTimer ~= nil then
self.mapUpdateTimer:Pause(bPause)
end
end
function ThrowGiftsLevelCtrl:ActiveItem(nItemId)
if self.mapItemUseCount[nItemId] == nil then
self.mapItemUseCount[nItemId] = 0
end
self.mapItemUseCount[nItemId] = self.mapItemUseCount[nItemId] + 1
if nItemId == 101 then
if 0 < self.nLevelTime then
self.nLevelTime = self.nLevelTime + 11
self.parent:AddTimeAnim()
WwiseAudioMgr:PostEvent("Mode_Present_prop_overtime")
end
elseif 106 <= nItemId and nItemId <= 110 then
self.curPenguinSpecialType = nItemId
self._mapNode.rtPenguinBeginningHintAnim:Play("imgBeginningHint_in")
if not self.bFlying and (self.nLevelType == 1 or self.nLevelType == 3) then
if nItemId == 108 then
WwiseAudioMgr:PostEvent("Mode_Present_prop_anteena")
elseif nItemId == 109 then
WwiseAudioMgr:PostEvent("Mode_Present_prop_spring")
elseif nItemId == 110 then
WwiseAudioMgr:PostEvent("Mode_Present_prop_magic")
else
WwiseAudioMgr:PostEvent("Mode_Present_prop_gear")
end
self:SetPenguinType(self._mapNode.rtBottle:Find("AnimRoot/penguinRoot"), self.curPenguinType, nItemId)
self:SetPenguinType(self._mapNode.rtPenguinBeginningHint, self.curPenguinType, nItemId)
self._mapNode.rtBottleAnim:Play("rtBottle_switch")
self._mapNode.rtPenguinBeginningHintAnim:Play("imgBeginningHint_in")
else
self:SetPenguinType(self._mapNode.rtPenguinBeginningHint, self.curPenguinType, nItemId)
self:SetPenguinType(self._mapNode.BeginningPenguinRoot.transform, self.curPenguinType, nItemId)
self:SetPenguinType(self._mapNode.rtBottle:Find("AnimRoot/penguinRoot"), self.curPenguinType, nItemId)
end
else
self.mapCurActiveState[nItemId] = 16
self.parent:SetFx(self.mapCurActiveState)
if nItemId == 105 then
WwiseAudioMgr:PostEvent("Mode_Present_prop_power")
local nSpecialType = self.curPenguinSpecialType == 0 and self.defaultPenguinSpecialType or self.curPenguinSpecialType
if not self.bFlying and (self.nLevelType == 1 or self.nLevelType == 3) then
self:SetPenguinType(self._mapNode.BeginningPenguinRoot.transform, self.nNextPenguinType, self.defaultPenguinSpecialType)
self:SetPenguinType(self._mapNode.rtBottle:Find("AnimRoot/penguinRoot"), self.curPenguinType, nSpecialType)
self:SetPenguinType(self._mapNode.rtPenguinBeginningHint, self.curPenguinType, nSpecialType)
else
self:SetPenguinType(self._mapNode.BeginningPenguinRoot.transform, self.nNextPenguinType, nSpecialType)
self:SetPenguinType(self._mapNode.rtBottle:Find("AnimRoot/penguinRoot"), self.curPenguinType, nSpecialType)
self:SetPenguinType(self._mapNode.rtPenguinBeginningHint, self.curPenguinType, nSpecialType)
end
elseif nItemId == 102 then
self._mapNode.imgInfinite:SetActive(true)
WwiseAudioMgr:PostEvent("Mode_Present_prop_infinite")
self._mapNode.TMPBeginningCountHint.gameObject:SetActive(false)
elseif nItemId == 103 then
WwiseAudioMgr:PostEvent("Mode_Present_lowtime_lp")
elseif nItemId == 104 then
WwiseAudioMgr:PostEvent("Mode_Present_doubletime_lp")
end
self.parent:SetBuffShow(nItemId, true)
self.parent:SetBuffTime(nItemId, 15)
end
end
function ThrowGiftsLevelCtrl:LevelStart()
self.nLevelType = 0
local GuideCallback = function()
self.nLevelType = 1
self._mapNode.penguinRoot:SetActive(true)
if self.nTotalPenguinCount ~= 0 then
if self.nTotalPenguinCount >= 0 then
NovaAPI.SetTMPText(self._mapNode.TMPBeginningCountHint, self.nTotalPenguinCount)
self._mapNode.TMPBeginningCountHint.gameObject:SetActive(true)
self._mapNode.imgInfinite:SetActive(false)
else
self._mapNode.TMPBeginningCountHint.gameObject:SetActive(false)
self._mapNode.imgInfinite:SetActive(true)
end
if self.curPenguinIdx > #self.mapFloorCfgData.InitialGiftSort then
if 0 < #self.mapFloorCfgData.GiftRandom then
self.curPenguinType = self.mapFloorCfgData.GiftRandom[math.random(#self.mapFloorCfgData.GiftRandom)]
else
self.curPenguinType = 1
end
else
self.curPenguinType = self.mapFloorCfgData.InitialGiftSort[self.curPenguinIdx]
end
self.curPenguinIdx = self.curPenguinIdx + 1
self._mapNode.BeginningPenguinRoot.gameObject:SetActive(true)
self._mapNode.rtBottleAnim:Play("rtBottle_in")
self._mapNode.BeginningPenguinRoot:Play("penguinRoot_jump")
WwiseAudioMgr:PostEvent("Mode_Present_shylock_jump")
local nSpecialType = self.curPenguinSpecialType == 0 and self.defaultPenguinSpecialType or self.curPenguinSpecialType
self:SetPenguinType(self._mapNode.BeginningPenguinRoot.transform, self.curPenguinType, nSpecialType)
self:SetPenguinType(self._mapNode.rtBottle:Find("AnimRoot/penguinRoot"), self.curPenguinType, nSpecialType)
self:SetBeginningAngle(0, 0)
local wait = function()
if self.nTotalPenguinCount ~= 0 then
self._mapNode.BeginningPenguinRoot.gameObject:SetActive(true)
self._mapNode.BeginningPenguinRoot:Play("penguinRoot_in")
WwiseAudioMgr:PostEvent("Mode_Present_shylock")
self.nNextPenguinType = 1
if self.curPenguinIdx > #self.mapFloorCfgData.InitialGiftSort then
if 0 < #self.mapFloorCfgData.GiftRandom then
self.nNextPenguinType = self.mapFloorCfgData.GiftRandom[math.random(#self.mapFloorCfgData.GiftRandom)]
else
self.nNextPenguinType = 1
end
else
self.nNextPenguinType = self.mapFloorCfgData.InitialGiftSort[self.curPenguinIdx]
end
self:SetPenguinType(self._mapNode.BeginningPenguinRoot.transform, self.nNextPenguinType, nSpecialType)
else
self._mapNode.BeginningPenguinRoot.gameObject:SetActive(false)
end
self._mapNode.imgBeginningHint:SetActive(true)
self:SetPenguinType(self._mapNode.rtPenguinBeginningHint, self.curPenguinType, nSpecialType)
self.nLevelType = 1
if self.mapLevelCfgData.SwitchArrow == true then
self.parent:SetViewBtn(1)
end
end
wait()
else
self._mapNode.BeginningPenguinRoot.gameObject:SetActive(false)
self:LevelEnd()
end
end
local completeCallback = function()
if self.actData ~= nil then
if self.mapFloorCfgData.DictionaryID > 0 and self.actData:GetDicFirstIn(self.mapFloorCfgData.DictionaryID) then
EventManager.Hit(EventId.OpenPanel, PanelId.DictionaryEntry, self.mapFloorCfgData.DictionaryID, true, GuideCallback)
else
GuideCallback()
end
else
GuideCallback()
end
end
if self.mapLevelCfgData.SwitchArrow == true then
self.nLevelType = 3
local maxScenePosX = -math.abs((1 - self.scenePivot[1]) * self.sceneSize[1])
self.beginningTweener = DOTween.To(function()
return 0
end, function(v)
local sum = v <= 0.5 and v or v <= 2.5 and 0.5 or 3 - v
local posX = math.sin(math.pi * sum) * maxScenePosX
local rtScenePos = self._mapNode.rtScene.anchoredPosition
self._mapNode.rtScene.anchoredPosition = Vector2(posX, rtScenePos.y)
end, 3, 3):OnComplete(function()
completeCallback()
end)
else
completeCallback()
end
end
function ThrowGiftsLevelCtrl:ChangeView(bShow)
if bShow then
if self.nLevelType == 3 then
return
end
self.nLevelType = 3
local maxScenePosX = -math.abs((1 - self.scenePivot[1]) * self.sceneSize[1])
self.beginningTweener = DOTween.To(function()
return 0
end, function(v)
local sum = v <= 0.5 and v or v <= 2.5 and 0.5 or 3 - v
local posX = math.sin(math.pi * sum) * maxScenePosX
local rtScenePos = self._mapNode.rtScene.anchoredPosition
self._mapNode.rtScene.anchoredPosition = Vector2(posX, rtScenePos.y)
end, 0.5, 0.5):OnComplete(function()
self.parent:SetViewBtn(2)
end)
else
if self.nLevelType ~= 3 then
return
end
local maxScenePosX = -math.abs((1 - self.scenePivot[1]) * self.sceneSize[1])
self.beginningTweener = DOTween.To(function()
return 2.5
end, function(v)
local sum = v <= 0.5 and v or v <= 2.5 and 0.5 or 3 - v
local posX = math.sin(math.pi * sum) * maxScenePosX
local rtScenePos = self._mapNode.rtScene.anchoredPosition
self._mapNode.rtScene.anchoredPosition = Vector2(posX, rtScenePos.y)
end, 3, 0.5):OnComplete(function()
if self.mapLevelCfgData.SwitchArrow == true then
self.parent:SetViewBtn(1)
end
self.nLevelType = 1
end)
end
end
function ThrowGiftsLevelCtrl:CheckCollision(bounds1, bounds2, OffsetX1, OffsetY1, OffsetX2, OffsetY2)
local bHit = false
local bestNX, bestNY, minDepth = 0, 0, 0
bHit = bounds1[2] + OffsetX1 >= bounds2[1] + OffsetX2 and bounds1[1] + OffsetX1 <= bounds2[2] + OffsetX2 and bounds1[4] + OffsetY1 >= bounds2[3] + OffsetY2 and bounds1[3] + OffsetY1 <= bounds2[4] + OffsetY2
if bHit then
print("Check SAT")
bHit, bestNX, bestNY, minDepth = self:CheckSAT(bounds1, bounds2, OffsetX1, OffsetY1, OffsetX2, OffsetY2)
end
return bHit, bestNX, bestNY, minDepth
end
function ThrowGiftsLevelCtrl.SATGetAxes(corners)
local ex1 = corners[2].x - corners[1].x
local ey1 = corners[2].y - corners[1].y
local len1 = math.sqrt(ex1 * ex1 + ey1 * ey1)
local ex2 = corners[3].x - corners[2].x
local ey2 = corners[3].y - corners[2].y
local len2 = math.sqrt(ex2 * ex2 + ey2 * ey2)
local ax1, ay1, ax2, ay2 = 0, 1, 1, 0
if 1.0E-5 < len1 then
ax1 = -ey1 / len1
ay1 = ex1 / len1
end
if 1.0E-5 < len2 then
ax2 = -ey2 / len2
ay2 = ex2 / len2
end
return ax1, ay1, ax2, ay2
end
function ThrowGiftsLevelCtrl.SATProject(corner1, corner2, corner3, corner4, offsetX, offsetY, axisX, axisY)
local v = (corner1.x + offsetX) * axisX + (corner1.y + offsetY) * axisY
local pMin, pMax = v, v
v = (corner2.x + offsetX) * axisX + (corner2.y + offsetY) * axisY
if pMin > v then
pMin = v
end
if pMax < v then
pMax = v
end
v = (corner3.x + offsetX) * axisX + (corner3.y + offsetY) * axisY
if pMin > v then
pMin = v
end
if pMax < v then
pMax = v
end
v = (corner4.x + offsetX) * axisX + (corner4.y + offsetY) * axisY
if pMin > v then
pMin = v
end
if pMax < v then
pMax = v
end
return pMin, pMax
end
function ThrowGiftsLevelCtrl:CheckSAT(tbBounds1, tbBounds2, OffsetX1, OffsetY1, OffsetX2, OffsetY2)
local minDepth = math.huge
local bestNX, bestNY = 0, 0
local ax1, ay1, ax2, ay2 = tbBounds1[9], tbBounds1[10], tbBounds1[11], tbBounds1[12]
local ax3, ay3, ax4, ay4 = tbBounds2[9], tbBounds2[10], tbBounds2[11], tbBounds2[12]
local cornersA1, cornersB1, cornersC1, cornersD1 = tbBounds1[5], tbBounds1[6], tbBounds1[7], tbBounds1[8]
local cornersA2, cornersB2, cornersC2, cornersD2 = tbBounds2[5], tbBounds2[6], tbBounds2[7], tbBounds2[8]
local min1, max1 = 0, 0
local min2, max2 = 0, 0
local overlap = 0
min1, max1 = self.SATProject(cornersA1, cornersB1, cornersC1, cornersD1, OffsetX1, OffsetY1, ax1, ay1)
min2, max2 = self.SATProject(cornersA2, cornersB2, cornersC2, cornersD2, OffsetX2, OffsetY2, ax1, ay1)
if min2 >= max1 or min1 >= max2 then
return false, 0, 0, 0
end
overlap = math.min(max1, max2) - math.max(min1, min2)
if minDepth > overlap then
minDepth = overlap
bestNX = ax1
bestNY = ay1
end
min1, max1 = self.SATProject(cornersA1, cornersB1, cornersC1, cornersD1, OffsetX1, OffsetY1, ax2, ay2)
min2, max2 = self.SATProject(cornersA2, cornersB2, cornersC2, cornersD2, OffsetX2, OffsetY2, ax2, ay2)
if min2 >= max1 or min1 >= max2 then
return false, 0, 0, 0
end
overlap = math.min(max1, max2) - math.max(min1, min2)
if minDepth > overlap then
minDepth = overlap
bestNX = ax2
bestNY = ay2
end
min1, max1 = self.SATProject(cornersA1, cornersB1, cornersC1, cornersD1, OffsetX1, OffsetY1, ax3, ay3)
min2, max2 = self.SATProject(cornersA2, cornersB2, cornersC2, cornersD2, OffsetX2, OffsetY2, ax3, ay3)
if min2 >= max1 or min1 >= max2 then
return false, 0, 0, 0
end
overlap = math.min(max1, max2) - math.max(min1, min2)
if minDepth > overlap then
minDepth = overlap
bestNX = ax3
bestNY = ay3
end
min1, max1 = self.SATProject(cornersA1, cornersB1, cornersC1, cornersD1, OffsetX1, OffsetY1, ax4, ay4)
min2, max2 = self.SATProject(cornersA2, cornersB2, cornersC2, cornersD2, OffsetX2, OffsetY2, ax4, ay4)
if min2 >= max1 or min1 >= max2 then
return false, 0, 0, 0
end
overlap = math.min(max1, max2) - math.max(min1, min2)
if minDepth > overlap then
minDepth = overlap
bestNX = ax4
bestNY = ay4
end
local c1x = (cornersA1.x + OffsetX1 + cornersB1.x + OffsetX1 + cornersC1.x + OffsetX1 + cornersD1.x + OffsetX1) * 0.25
local c1y = (cornersA1.y + OffsetY1 + cornersB1.y + OffsetY1 + cornersC1.y + OffsetY1 + cornersD1.y + OffsetY1) * 0.25
local c2x = (cornersA2.x + OffsetX2 + cornersB2.x + OffsetX2 + cornersC2.x + OffsetX2 + cornersD2.x + OffsetX2) * 0.25
local c2y = (cornersA2.y + OffsetY2 + cornersB2.y + OffsetY2 + cornersC2.y + OffsetY2 + cornersD2.y + OffsetY2) * 0.25
if (c1x - c2x) * bestNX + (c1y - c2y) * bestNY < 0 then
bestNX = -bestNX
bestNY = -bestNY
end
return true, bestNX, bestNY, minDepth
end
function ThrowGiftsLevelCtrl.ReflectVelocity(vx, vy, nx, ny, restitution)
restitution = restitution or 1.0
local dot = vx * nx + vy * ny
if 0 <= dot then
return vx, vy
end
local scale = (1.0 + restitution) * dot
return vx - scale * nx, vy - scale * ny
end
function ThrowGiftsLevelCtrl:GetLocalSpaceRect(rectTransform, parent)
local corners = CS.System.Array.CreateInstance(typeof(Vector3), 4)
rectTransform:GetLocalCorners(corners)
local c0 = corners[0]
local c1 = corners[1]
local c2 = corners[2]
local c3 = corners[3]
local p0 = parent:InverseTransformPoint(rectTransform:TransformPoint(c0))
local p1 = parent:InverseTransformPoint(rectTransform:TransformPoint(c1))
local p2 = parent:InverseTransformPoint(rectTransform:TransformPoint(c2))
local p3 = parent:InverseTransformPoint(rectTransform:TransformPoint(c3))
local p0x, p0y = p0.x, p0.y
local p1x, p1y = p1.x, p1.y
local p2x, p2y = p2.x, p2.y
local p3x, p3y = p3.x, p3.y
local xMin = math.min(p0x, p1x, p2x, p3x)
local xMax = math.max(p0x, p1x, p2x, p3x)
local yMin = math.min(p0y, p1y, p2y, p3y)
local yMax = math.max(p0y, p1y, p2y, p3y)
local ax1, ay1, ax2, ay2 = self.SATGetAxes({
p0,
p1,
p2,
p3
})
return {
xMin,
xMax,
yMin,
yMax,
p0,
p1,
p2,
p3,
ax1,
ay1,
ax2,
ay2
}
end
function ThrowGiftsLevelCtrl:OnUpdate()
if self.mapUpdateTimer == nil then
return
end
local nDeltaTime = math.min(self.mapUpdateTimer:GetDelTime(), 0.032)
if self.nLevelTime > 0 then
if self.nLevelType == 1 then
if self.mapCurActiveState[103] ~= nil then
self.nLevelTime = self.nLevelTime - nDeltaTime * 0.5
else
self.nLevelTime = self.nLevelTime - nDeltaTime
end
end
self.nLevelTime = math.max(self.nLevelTime, 0)
self.parent:SetTime(self.nLevelTime)
if self.nLevelTime <= 0 then
if self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.ThrowCountAfterTime then
if self.nTotalThrowGiftCount >= self.mapLevelCfgData.throwGiftLevelParams then
self:LevelEnd(true, 0)
else
self:LevelEnd(false, 1)
end
elseif self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.ScoreAfterTime then
if self.nLevelScore >= self.mapLevelCfgData.throwGiftLevelParams then
self:LevelEnd(true, 0)
else
self:LevelEnd(false, 1)
end
elseif self.mapLevelCfgData.ThrowGiftLevelCond == GameEnum.ThrowGiftLevelCond.HitCountAfterTime then
if self.nTotalHitGoalCount >= self.mapLevelCfgData.throwGiftLevelParams then
self:LevelEnd(true, 0)
else
self:LevelEnd(false, 1)
end
else
self:LevelEnd(false, 2)
end
return
end
end
local tbRemovedState = {}
for nState, nTime in pairs(self.mapCurActiveState) do
self.mapCurActiveState[nState] = self.mapCurActiveState[nState] - nDeltaTime
self.parent:SetBuffTime(nState, nTime)
if 0 >= self.mapCurActiveState[nState] then
table.insert(tbRemovedState, nState)
self.parent:SetBuffShow(nState, false)
end
end
local bChange = 0 < #tbRemovedState
for _, nState in ipairs(tbRemovedState) do
self.mapCurActiveState[nState] = nil
if nState == 105 then
self:SetPenguinType(self._mapNode.BeginningPenguinRoot.transform, self.nNextPenguinType, 0)
self:SetPenguinType(self._mapNode.rtBottle:Find("AnimRoot/penguinRoot"), self.curPenguinType, self.curPenguinSpecialType)
self:SetPenguinType(self._mapNode.rtPenguinBeginningHint, self.curPenguinType, self.curPenguinSpecialType)
if self.bFlying and self.curGiftPenguin ~= nil then
local goPenguin = self.curGiftPenguin.goGiftPenguin
local rtPenguin = goPenguin:GetComponent("RectTransform")
local goImgRoot = rtPenguin:Find("imgRoot")
local imgFx = goImgRoot:Find("imgFx")
imgFx.gameObject:SetActive(false)
end
elseif nState == 103 then
WwiseAudioMgr:PostEvent("Mode_Present_lowtime_lp_stop")
elseif nState == 104 then
WwiseAudioMgr:PostEvent("Mode_Present_doubletime_lp_stop")
elseif nState == 102 and 0 <= self.nTotalPenguinCount then
self._mapNode.imgInfinite:SetActive(false)
self._mapNode.TMPBeginningCountHint.gameObject:SetActive(true)
end
end
if bChange then
self.parent:SetFx(self.mapCurActiveState)
end
for nId, mapAciveGoal in pairs(self.activeGoal) do
local mapConfig = self.mapGoal[nId]
local moveX = 0
local moveY = 0
if mapConfig ~= nil then
moveX = mapConfig.mapConfig.MoveX
moveY = mapConfig.mapConfig.MoveY
if 0 < moveX or 0 < moveY then
local curPos = mapAciveGoal.rtGoal.anchoredPosition
local rtSpawnPoint = mapConfig.rtPoint
local nXMax = rtSpawnPoint.anchoredPosition.x + moveX
local nYMax = rtSpawnPoint.anchoredPosition.y + moveY
local nXMin = rtSpawnPoint.anchoredPosition.x - moveX
local nYMin = rtSpawnPoint.anchoredPosition.y - moveY
local nCurMove = 0
if self.mapCurActiveState[103] ~= nil then
nCurMove = self.nGoalSpeed * nDeltaTime * 0.5
else
nCurMove = self.nGoalSpeed * nDeltaTime
end
local nAfterX = curPos.x + nCurMove * mapConfig.VxDir
local nAfterY = curPos.y + nCurMove * mapConfig.VyDir
if nXMax < nAfterX then
nAfterX = nXMax
mapConfig.VxDir = -mapConfig.VxDir
elseif nXMin > nAfterX then
nAfterX = nXMin
mapConfig.VxDir = -mapConfig.VxDir
end
if nYMax < nAfterY then
nAfterY = nYMax
mapConfig.VyDir = -mapConfig.VyDir
elseif nYMin > nAfterY then
nAfterY = nYMin
mapConfig.VyDir = -mapConfig.VyDir
end
mapAciveGoal.OffsetX = nAfterX - mapAciveGoal.initialPosX
mapAciveGoal.OffsetY = nAfterY - mapAciveGoal.initialPosY
mapAciveGoal.rtGoal.anchoredPosition = Vector2(nAfterX, nAfterY)
end
end
end
if not self.bFlying then
return
end
if self.curGiftPenguin == nil then
return
end
local nCurPosX, nCurPosY, tbCachedGoalId
if self.curGiftPenguin.nSpecialType == 106 then
nCurPosX, nCurPosY = self:NavigationPenguinUpdate(nDeltaTime)
elseif self.curGiftPenguin.nSpecialType == 107 then
nCurPosX, nCurPosY = self:HelmetPenguinUpdate(nDeltaTime)
elseif self.curGiftPenguin.nSpecialType == 108 then
nCurPosX, nCurPosY = self:AntennaPenguinUpdate(nDeltaTime)
elseif self.curGiftPenguin.nSpecialType == 109 then
nCurPosX, nCurPosY = self:BouncePenguinUpdate(nDeltaTime)
elseif self.curGiftPenguin.nSpecialType == 110 then
nCurPosX, nCurPosY, tbCachedGoalId = self:SplitPenguinUpdate(nDeltaTime)
else
nCurPosX, nCurPosY = self:NormalPenguinUpdate(nDeltaTime)
end
if not self.bFlying then
local tbHitGoalId = {}
if tbCachedGoalId ~= nil and 0 < #tbCachedGoalId then
for _, tbResult in ipairs(tbCachedGoalId) do
self:HitGoal(tbResult[2], tbResult[1])
table.insert(tbHitGoalId, tbResult[1])
end
end
self:FlyOver(0.5, tbHitGoalId)
return
end
local tbHitGoalId = {}
if self.curGiftPenguin.nSpecialType == 110 and self.curGiftPenguin.bSplit then
local tbCurHit = self:SplitPenguinGoalCheck()
if 0 < #tbCurHit then
for _, tbResult in ipairs(tbCurHit) do
self:HitGoal(tbResult[2], tbResult[1])
end
if not self.bFlying then
self.curGiftPenguin = nil
for _, tbResult in ipairs(tbCurHit) do
table.insert(tbHitGoalId, tbResult[1])
end
end
end
elseif self.curGiftPenguin.nSpecialType == 109 then
local hitGoalId, hitPos = self:BouncePenguinGoalCheck(nCurPosX, nCurPosY)
if 0 < hitGoalId then
self:HitGoal(hitPos, hitGoalId)
table.insert(tbHitGoalId, hitGoalId)
end
else
local hitGoalId, hitPos = self:NormalGoalCheck(nCurPosX, nCurPosY)
if 0 < hitGoalId then
self:HitGoal(hitPos, hitGoalId)
table.insert(tbHitGoalId, hitGoalId)
end
end
if not self.bFlying then
self:FlyOver(0.5, tbHitGoalId)
return
end
local rtScenePos = self._mapNode.rtScene.anchoredPosition
local curPosXInScreen = self.sceneSize[1] * 0.5 + nCurPosX + rtScenePos.x
if curPosXInScreen > self.viewSize[1] / 2 then
local sumX = curPosXInScreen - self.viewSize[1] / 2
local nFinX = rtScenePos.x - sumX
local maxScenePosX = (1 - self.scenePivot[1]) * self.sceneSize[1]
if nFinX <= -math.abs(maxScenePosX) then
nFinX = -math.abs(maxScenePosX)
end
self._mapNode.rtScene.anchoredPosition = Vector2(nFinX, rtScenePos.y)
end
end
function ThrowGiftsLevelCtrl:NormalGoalCheck(nCurPosX, nCurPosY)
local nSumX = nCurPosX - self.curGiftPenguin.mapStartPos.x
local nSumY = nCurPosY - self.curGiftPenguin.mapStartPos.y
if self.mapLevelCfgData.FlightPath == true and self.nFlyingTime - self._mapNode.rtBlindLevelTrack.nPrevTimer >= self.nLinePointInterval * 2 then
self._mapNode.rtBlindLevelTrack.nPrevTimer = self.nFlyingTime
self._mapNode.rtBlindLevelTrack:AddDot(Vector2(nCurPosX, nCurPosY))
end
local hitGoalId = 0
local hitPos
for nId, mapAciveGoal in pairs(self.activeGoal) do
local GoalParentPos = mapAciveGoal.rtGoal.anchoredPosition
local bHitGoal = self:CheckCollision(self.curGiftPenguin.tbBounds, mapAciveGoal.tbBoundsHitArea, nSumX, nSumY, mapAciveGoal.OffsetX, mapAciveGoal.OffsetY)
if bHitGoal then
local curVy = self.curGiftPenguin.nVelocityY
if 0 < curVy and self.curGiftPenguin.nSpecialType ~= 106 and self.curGiftPenguin.nSpecialType ~= 107 then
print("hit goal edge")
self:DestroyPenguin()
self.curGiftPenguin = nil
self.bFlying = false
break
else
print("hit goal")
hitPos = Vector2(nCurPosX, nCurPosY)
destroy(self.curGiftPenguin.goGiftPenguin.gameObject)
hitGoalId = nId
self.curGiftPenguin = nil
self.bFlying = false
break
end
end
if self.curGiftPenguin.nSpecialType ~= 107 then
local bHitObstacle = self:CheckCollision(self.curGiftPenguin.tbBounds, mapAciveGoal.tbBoundsObstacle, nSumX, nSumY, mapAciveGoal.OffsetX, mapAciveGoal.OffsetY)
if bHitObstacle then
self:DestroyPenguin()
self.bFlying = false
break
end
end
end
return hitGoalId, hitPos
end
function ThrowGiftsLevelCtrl:SplitPenguinGoalCheck()
local tbCurHit = {}
for _, mapSubPenguin in ipairs(self.curGiftPenguin.tbSubPenguin) do
if mapSubPenguin.bFlying then
local hitGoalId = 0
local hitPos
local nSumX = mapSubPenguin.curPosX - mapSubPenguin.mapStartPos.x
local nSumY = mapSubPenguin.curPosY - mapSubPenguin.mapStartPos.y
for nId, mapAciveGoal in pairs(self.activeGoal) do
local bHitGoal = self:CheckCollision(mapSubPenguin.tbBounds, mapAciveGoal.tbBoundsHitArea, nSumX, nSumY, mapAciveGoal.OffsetX, mapAciveGoal.OffsetY)
if bHitGoal then
print("hit goal")
hitPos = Vector2(mapSubPenguin.curPosX, mapSubPenguin.curPosY)
destroy(mapSubPenguin.goGiftPenguin.gameObject)
mapSubPenguin.goGiftPenguin = nil
hitGoalId = nId
mapSubPenguin.bFlying = false
table.insert(tbCurHit, {hitGoalId, hitPos})
table.insert(self.curGiftPenguin.tbCacheSubPenguinGoal, {hitGoalId, hitPos})
break
end
local bHitObstacle = self:CheckCollision(mapSubPenguin.tbBounds, mapAciveGoal.tbBoundsObstacle, nSumX, nSumY, mapAciveGoal.OffsetX, mapAciveGoal.OffsetY)
if bHitObstacle then
self:DestroySubPenguin(mapSubPenguin)
mapSubPenguin.bFlying = false
break
end
end
end
end
if self.mapLevelCfgData.FlightPath == true and self.nFlyingTime - self._mapNode.rtBlindLevelTrack.nPrevTimer >= self.nLinePointInterval * 2 then
self._mapNode.rtBlindLevelTrack.nPrevTimer = self.nFlyingTime
for _, mapSubPenguin in ipairs(self.curGiftPenguin.tbSubPenguin) do
if mapSubPenguin.bFlying then
self._mapNode.rtBlindLevelTrack:AddDot(Vector2(mapSubPenguin.curPosX, mapSubPenguin.curPosY))
end
end
end
local bHasSubPenguin = false
for _, mapSubPenguin in ipairs(self.curGiftPenguin.tbSubPenguin) do
if mapSubPenguin.bFlying then
bHasSubPenguin = true
end
end
self.bFlying = bHasSubPenguin
if not self.bFlying then
self.curGiftPenguin = nil
end
return tbCurHit
end
function ThrowGiftsLevelCtrl:BouncePenguinGoalCheck(nCurPosX, nCurPosY)
local nSumX = nCurPosX - self.curGiftPenguin.mapStartPos.x
local nSumY = nCurPosY - self.curGiftPenguin.mapStartPos.y
if self.mapLevelCfgData.FlightPath == true and self.nFlyingTime - self._mapNode.rtBlindLevelTrack.nPrevTimer >= self.nLinePointInterval * 2 then
self._mapNode.rtBlindLevelTrack.nPrevTimer = self.nFlyingTime
self._mapNode.rtBlindLevelTrack:AddDot(Vector2(nCurPosX, nCurPosY))
end
local hitGoalId = 0
local hitPos
local curVy = self.curGiftPenguin.nVelocityY
for nId, mapAciveGoal in pairs(self.activeGoal) do
local GoalParentPos = mapAciveGoal.rtGoal.anchoredPosition
local bHitGoal, bestNX, bestNY, minDepth = self:CheckCollision(self.curGiftPenguin.tbBounds, mapAciveGoal.tbBoundsHitArea, nSumX, nSumY, mapAciveGoal.OffsetX, mapAciveGoal.OffsetY)
if bHitGoal then
if 0 < curVy then
if self.curGiftPenguin.nHitCount < 3 then
WwiseAudioMgr:PostEvent("Mode_Present_spring")
self.curGiftPenguin.nHitCount = self.curGiftPenguin.nHitCount + 1
nCurPosX = nCurPosX + bestNX * minDepth
nCurPosY = nCurPosY + bestNY * minDepth
nSumX = nSumX + bestNX * minDepth
nSumY = nSumY + bestNY * minDepth
self.curGiftPenguin.curPosX = nCurPosX
self.curGiftPenguin.curPosY = nCurPosY
self.curGiftPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
self.curGiftPenguin.mapStartPos = self.curGiftPenguin.goGiftPenguin.anchoredPosition
local vxAfter, vyAfter = self.ReflectVelocity(self.curGiftPenguin.nVelocityX, curVy, bestNX, bestNY, 1)
self.curGiftPenguin.nHitTime = self.nFlyingTime
self.curGiftPenguin.nVelocityX = vxAfter
self.curGiftPenguin.nVelocityY = vyAfter
self.curGiftPenguin.tbBounds = self:GetLocalSpaceRect(self.curGiftPenguin.goGiftPenguin, self.curGiftPenguin.goGiftPenguin.parent)
break
else
self:DestroyPenguin()
self.bFlying = false
break
end
else
print("hit goal")
hitPos = Vector2(nCurPosX, nCurPosY)
destroy(self.curGiftPenguin.goGiftPenguin.gameObject)
hitGoalId = nId
self.curGiftPenguin = nil
self.bFlying = false
break
end
end
local bHitObstacle, bestNXObstacle, bestNYObstacle, minDepthObstacle = self:CheckCollision(self.curGiftPenguin.tbBounds, mapAciveGoal.tbBoundsObstacle, nSumX, nSumY, mapAciveGoal.OffsetX, mapAciveGoal.OffsetY)
if bHitObstacle then
if self.curGiftPenguin.nHitCount < 3 then
self.curGiftPenguin.nHitCount = self.curGiftPenguin.nHitCount + 1
nCurPosX = nCurPosX + bestNXObstacle * minDepthObstacle
nCurPosY = nCurPosY + bestNYObstacle * minDepthObstacle
nSumX = nSumX + bestNXObstacle * minDepthObstacle
nSumY = nSumY + bestNYObstacle * minDepthObstacle
self.curGiftPenguin.curPosX = nCurPosX
self.curGiftPenguin.curPosY = nCurPosY
self.curGiftPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
self.curGiftPenguin.mapStartPos = self.curGiftPenguin.goGiftPenguin.anchoredPosition
local vxAfter, vyAfter = self.ReflectVelocity(self.curGiftPenguin.nVelocityX, curVy, bestNXObstacle, bestNYObstacle, 1)
self.curGiftPenguin.nHitTime = self.nFlyingTime
self.curGiftPenguin.nVelocityX = vxAfter
self.curGiftPenguin.nVelocityY = vyAfter
self.curGiftPenguin.tbBounds = self:GetLocalSpaceRect(self.curGiftPenguin.goGiftPenguin, self.curGiftPenguin.goGiftPenguin.parent)
break
else
self:DestroyPenguin()
self.bFlying = false
break
end
end
end
return hitGoalId, hitPos
end
function ThrowGiftsLevelCtrl:NormalPenguinUpdate(nDeltaTime)
self.nFlyingTime = self.nFlyingTime + nDeltaTime
local nCurPosX = self.curGiftPenguin.curPosX + nDeltaTime * self.curGiftPenguin.nVelocityX
local nCurPosY = self.curGiftPenguin.curPosY + nDeltaTime * self.curGiftPenguin.nVelocityY - 0.5 * self.nAG * nDeltaTime * nDeltaTime
self.curGiftPenguin.nVelocityY = self.curGiftPenguin.nVelocityY - self.nAG * nDeltaTime
self.curGiftPenguin.curPosX = nCurPosX
self.curGiftPenguin.curPosY = nCurPosY
self.curGiftPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
local nSumX = nCurPosX - self.curGiftPenguin.mapStartPos.x
local nSumY = nCurPosY - self.curGiftPenguin.mapStartPos.y
local curVy = self.curGiftPenguin.nVelocityY
if self.curGiftPenguin.rtImgRoot ~= nil then
local nFlyAngle = math.deg(math.atan(curVy, self.curGiftPenguin.nVelocityX))
self.curGiftPenguin.rtImgRoot.localEulerAngles = Vector3(0, 0, nFlyAngle)
end
for _, tbBounds in ipairs(self.tbObstacle) do
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, tbBounds, nSumX, nSumY, 0, 0)
if bHit then
self:DestroyPenguin()
self.bFlying = false
break
end
end
if not self.bFlying then
return
end
if nCurPosX > 0.5 * self.sceneSize[1] or nCurPosX < -0.5 * self.sceneSize[1] or nCurPosY > 0.5 * self.sceneSize[2] or nCurPosY < -0.5 * self.sceneSize[2] then
print("hit border")
self:DestroyPenguin()
self.bFlying = false
end
if not self.bFlying then
return
end
local tbHittedObs = {}
for _, nSpecialId in ipairs(self.tbExObstacleCur) do
local mapConfig = self.mapExObstacleOrigin[nSpecialId]
if mapConfig ~= nil then
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, mapConfig.tbBounds, nSumX, nSumY, 0, 0)
if bHit then
local nType, Param, bRemove
self.bFlying, nType, Param, bRemove = self:HitSpecialObstacle(nSpecialId)
self:SpecialObstacleFunc(self.curGiftPenguin, nDeltaTime, nType, Param)
if bRemove then
table.insert(tbHittedObs, nSpecialId)
end
if not self.bFlying then
self:DestroyPenguin()
break
end
end
end
end
for _, nId in ipairs(tbHittedObs) do
table.removebyvalue(self.tbExObstacleCur, nId, true)
end
return nCurPosX, nCurPosY
end
function ThrowGiftsLevelCtrl:BouncePenguinUpdate(nDeltaTime)
self.nFlyingTime = self.nFlyingTime + nDeltaTime
local nCurPosX = self.curGiftPenguin.curPosX + nDeltaTime * self.curGiftPenguin.nVelocityX
local nCurPosY = self.curGiftPenguin.curPosY + nDeltaTime * self.curGiftPenguin.nVelocityY - 0.5 * self.nAG * nDeltaTime * nDeltaTime
self.curGiftPenguin.nVelocityY = self.curGiftPenguin.nVelocityY - self.nAG * nDeltaTime
self.curGiftPenguin.curPosX = nCurPosX
self.curGiftPenguin.curPosY = nCurPosY
local curVy = self.curGiftPenguin.nVelocityY
self.curGiftPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
local nSumX = nCurPosX - self.curGiftPenguin.mapStartPos.x
local nSumY = nCurPosY - self.curGiftPenguin.mapStartPos.y
if self.curGiftPenguin.rtImgRoot ~= nil then
local nFlyAngle = math.deg(math.atan(curVy, self.curGiftPenguin.nVelocityX))
self.curGiftPenguin.rtImgRoot.localEulerAngles = Vector3(0, 0, nFlyAngle)
end
for _, tbBounds in ipairs(self.tbObstacle) do
local bHit, bestNX, bestNY, minDepth = self:CheckCollision(self.curGiftPenguin.tbBounds, tbBounds, nSumX, nSumY, 0, 0)
if bHit then
if self.curGiftPenguin.nHitCount < 3 then
WwiseAudioMgr:PostEvent("Mode_Present_spring")
self.curGiftPenguin.nHitCount = self.curGiftPenguin.nHitCount + 1
nCurPosX = nCurPosX + bestNX * minDepth
nCurPosY = nCurPosY + bestNY * minDepth
nSumX = nSumX + bestNX * minDepth
nSumY = nSumY + bestNY * minDepth
self.curGiftPenguin.curPosX = nCurPosX
self.curGiftPenguin.curPosY = nCurPosY
self.curGiftPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
self.curGiftPenguin.mapStartPos = self.curGiftPenguin.goGiftPenguin.anchoredPosition
local vxAfter, vyAfter = self.ReflectVelocity(self.curGiftPenguin.nVelocityX, curVy, bestNX, bestNY, 1)
self.curGiftPenguin.nHitTime = self.nFlyingTime
self.curGiftPenguin.nVelocityX = vxAfter
self.curGiftPenguin.nVelocityY = vyAfter
self.curGiftPenguin.tbBounds = self:GetLocalSpaceRect(self.curGiftPenguin.goGiftPenguin, self.curGiftPenguin.goGiftPenguin.parent)
break
else
self:DestroyPenguin()
self.bFlying = false
break
end
end
end
if not self.bFlying then
return
end
if nCurPosX > 0.5 * self.sceneSize[1] or nCurPosX < -0.5 * self.sceneSize[1] or nCurPosY > 0.5 * self.sceneSize[2] or nCurPosY < -0.5 * self.sceneSize[2] then
print("hit border")
self:DestroyPenguin()
self.bFlying = false
end
if not self.bFlying then
return
end
local tbHittedObs = {}
for _, nSpecialId in ipairs(self.tbExObstacleCur) do
local mapConfig = self.mapExObstacleOrigin[nSpecialId]
if mapConfig ~= nil then
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, mapConfig.tbBounds, nSumX, nSumY, 0, 0)
if bHit then
local nType, Param, bRemove
self.bFlying, nType, Param, bRemove = self:HitSpecialObstacle(nSpecialId)
self:SpecialObstacleFunc(self.curGiftPenguin, nDeltaTime, nType, Param)
if bRemove then
table.insert(tbHittedObs, nSpecialId)
end
if not self.bFlying then
self:DestroyPenguin()
break
end
end
end
end
for _, nId in ipairs(tbHittedObs) do
table.removebyvalue(self.tbExObstacleCur, nId, true)
end
return nCurPosX, nCurPosY
end
function ThrowGiftsLevelCtrl:AntennaPenguinUpdate(nDeltaTime)
self.nFlyingTime = self.nFlyingTime + nDeltaTime
local nCurPosX = self.curGiftPenguin.curPosX + nDeltaTime * self.curGiftPenguin.nVelocityX
local nCurPosY = self.curGiftPenguin.curPosY + nDeltaTime * self.curGiftPenguin.nVelocityY - 0.5 * self.nAG * nDeltaTime * nDeltaTime
self.curGiftPenguin.nVelocityY = self.curGiftPenguin.nVelocityY - self.nAG * nDeltaTime
self.curGiftPenguin.curPosX = nCurPosX
self.curGiftPenguin.curPosY = nCurPosY
local curVy = self.curGiftPenguin.nVelocityY
self.curGiftPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
local nSumX = nCurPosX - self.curGiftPenguin.mapStartPos.x
local nSumY = nCurPosY - self.curGiftPenguin.mapStartPos.y
if self.tbItemTrackCtrl[self.curGiftPenguin.nTrackIdx] ~= nil then
local mapTrackCtrl = self.tbItemTrackCtrl[self.curGiftPenguin.nTrackIdx]
if self.nFlyingTime - mapTrackCtrl.nPrevTimer >= self.nLinePointInterval * 2 then
mapTrackCtrl.nPrevTimer = self.nFlyingTime
mapTrackCtrl:AddDot(Vector2(nCurPosX, nCurPosY))
end
end
if self.curGiftPenguin.rtImgRoot ~= nil then
local nFlyAngle = math.deg(math.atan(curVy, self.curGiftPenguin.nVelocityX))
self.curGiftPenguin.rtImgRoot.localEulerAngles = Vector3(0, 0, nFlyAngle)
end
for _, tbBounds in ipairs(self.tbObstacle) do
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, tbBounds, nSumX, nSumY, 0, 0)
if bHit then
self:DestroyPenguin()
self.bFlying = false
break
end
end
if not self.bFlying then
return
end
if nCurPosX > 0.5 * self.sceneSize[1] or nCurPosX < -0.5 * self.sceneSize[1] or nCurPosY > 0.5 * self.sceneSize[2] or nCurPosY < -0.5 * self.sceneSize[2] then
print("hit border")
self:DestroyPenguin()
self.bFlying = false
end
if not self.bFlying then
return
end
local tbHittedObs = {}
for _, nSpecialId in ipairs(self.tbExObstacleCur) do
local mapConfig = self.mapExObstacleOrigin[nSpecialId]
if mapConfig ~= nil then
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, mapConfig.tbBounds, nSumX, nSumY, 0, 0)
if bHit then
local nType, Param, bRemove
self.bFlying, nType, Param, bRemove = self:HitSpecialObstacle(nSpecialId)
self:SpecialObstacleFunc(self.curGiftPenguin, nDeltaTime, nType, Param)
if bRemove then
table.insert(tbHittedObs, nSpecialId)
end
if not self.bFlying then
self:DestroyPenguin()
break
end
end
end
end
for _, nId in ipairs(tbHittedObs) do
table.removebyvalue(self.tbExObstacleCur, nId, true)
end
return nCurPosX, nCurPosY
end
function ThrowGiftsLevelCtrl:HelmetPenguinUpdate(nDeltaTime)
self.nFlyingTime = self.nFlyingTime + nDeltaTime
local nCurPosX = self.curGiftPenguin.curPosX + nDeltaTime * self.curGiftPenguin.nVelocityX
local nCurPosY = self.curGiftPenguin.curPosY + nDeltaTime * self.curGiftPenguin.nVelocityY - 0.5 * self.nAG * nDeltaTime * nDeltaTime
self.curGiftPenguin.nVelocityY = self.curGiftPenguin.nVelocityY - self.nAG * nDeltaTime
self.curGiftPenguin.curPosX = nCurPosX
self.curGiftPenguin.curPosY = nCurPosY
local curVy = self.curGiftPenguin.nVelocityY
self.curGiftPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
local nSumX = nCurPosX - self.curGiftPenguin.mapStartPos.x
local nSumY = nCurPosY - self.curGiftPenguin.mapStartPos.y
if self.curGiftPenguin.rtImgRoot ~= nil then
local nFlyAngle = math.deg(math.atan(curVy, self.curGiftPenguin.nVelocityX))
self.curGiftPenguin.rtImgRoot.localEulerAngles = Vector3(0, 0, nFlyAngle)
end
if nCurPosX > 0.5 * self.sceneSize[1] or nCurPosX < -0.5 * self.sceneSize[1] or nCurPosY > 0.5 * self.sceneSize[2] or nCurPosY < -0.5 * self.sceneSize[2] then
print("hit border")
self:DestroyPenguin()
self.bFlying = false
end
if not self.bFlying then
return
end
local tbHittedObs = {}
for _, nSpecialId in ipairs(self.tbExObstacleCur) do
local mapConfig = self.mapExObstacleOrigin[nSpecialId]
if mapConfig ~= nil then
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, mapConfig.tbBounds, nSumX, nSumY, 0, 0)
if bHit then
local bFlying, nType, Param, bRemove
bFlying, nType, Param, bRemove = self:HitSpecialObstacle(nSpecialId)
self:SpecialObstacleFunc(self.curGiftPenguin, nDeltaTime, nType, Param)
if bRemove then
table.insert(tbHittedObs, nSpecialId)
end
end
end
end
for _, nId in ipairs(tbHittedObs) do
table.removebyvalue(self.tbExObstacleCur, nId, true)
end
return nCurPosX, nCurPosY
end
function ThrowGiftsLevelCtrl:NavigationPenguinUpdate(nDeltaTime)
local checkGetGoal = function(nCurPosX, nCurPosY)
for nId, mapAciveGoal in pairs(self.activeGoal) do
if nCurPosX >= mapAciveGoal.tbBoundsHitArea[1] and nCurPosX <= mapAciveGoal.tbBoundsHitArea[2] and nCurPosY >= mapAciveGoal.tbBoundsHitArea[4] then
return mapAciveGoal.rtGoal
end
end
return nil
end
self.nFlyingTime = self.nFlyingTime + nDeltaTime
self.curGiftPenguin.nVelocityY = math.max(0, self.curGiftPenguin.nVelocityY - self.nAG * nDeltaTime)
local nCurPosY = 0
local nCurPosX = 0
if self.curGiftPenguin.targetGoal == nil then
if self.curGiftPenguin.nVelocityY > 0 then
nCurPosX = self.curGiftPenguin.curPosX + nDeltaTime * self.curGiftPenguin.nVelocityX
nCurPosY = self.curGiftPenguin.curPosY + nDeltaTime * self.curGiftPenguin.nVelocityY - 0.5 * self.nAG * nDeltaTime * nDeltaTime
else
nCurPosY = self.curGiftPenguin.curPosY
local nVelocityX = self.curGiftPenguin.nVelocityX < 600 and 600 or self.curGiftPenguin.nVelocityX
nCurPosX = self.curGiftPenguin.curPosX + nDeltaTime * nVelocityX
self.curGiftPenguin.nVelocityY = 0
end
local checkGoal = checkGetGoal(nCurPosX, nCurPosY)
if checkGoal ~= nil then
self.curGiftPenguin.targetGoal = checkGoal
self.curGiftPenguin.nGetTargetTime = self.nFlyingTime
end
else
nCurPosY = self.curGiftPenguin.curPosY - nDeltaTime * self.nNavigationPenguinSpeed
local nTargetX = self.curGiftPenguin.targetGoal.anchoredPosition.x
nCurPosX = self.curGiftPenguin.goGiftPenguin.anchoredPosition.x
local sumMove = math.min(self.maxVelocity, (nTargetX - nCurPosX) / 0.1) * nDeltaTime
nCurPosX = sumMove + nCurPosX
end
self.curGiftPenguin.curPosX = nCurPosX
self.curGiftPenguin.curPosY = nCurPosY
self.curGiftPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
local nSumX = nCurPosX - self.curGiftPenguin.mapStartPos.x
local nSumY = nCurPosY - self.curGiftPenguin.mapStartPos.y
local curVy = self.curGiftPenguin.nVelocityY
if self.curGiftPenguin.rtImgRoot ~= nil then
if self.curGiftPenguin.targetGoal == nil then
local nFlyAngle = math.deg(math.atan(curVy, self.curGiftPenguin.nVelocityX))
self.curGiftPenguin.rtImgRoot.localEulerAngles = Vector3(0, 0, nFlyAngle)
else
local nCurAngle = self.curGiftPenguin.rtImgRoot.localEulerAngles.z
local nAngle = 90 * nDeltaTime
nCurAngle = math.min(nCurAngle + nAngle, 90)
self.curGiftPenguin.rtImgRoot.localEulerAngles = Vector3(0, 0, nCurAngle)
end
end
for _, tbBounds in ipairs(self.tbObstacle) do
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, tbBounds, nSumX, nSumY, 0, 0)
if bHit then
print("hit Obstacle")
self:DestroyPenguin()
self.curGiftPenguin = nil
self.bFlying = false
break
end
end
if not self.bFlying then
return
end
if nCurPosX > 0.5 * self.sceneSize[1] or nCurPosX < -0.5 * self.sceneSize[1] or nCurPosY > 0.5 * self.sceneSize[2] or nCurPosY < -0.5 * self.sceneSize[2] then
print("hit border")
self:DestroyPenguin()
self.bFlying = false
end
if not self.bFlying then
return
end
local tbHittedObs = {}
for _, nSpecialId in ipairs(self.tbExObstacleCur) do
local mapConfig = self.mapExObstacleOrigin[nSpecialId]
if mapConfig ~= nil then
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, mapConfig.tbBounds, nSumX, nSumY, 0, 0)
if bHit then
local nType, Param, bRemove
self.bFlying, nType, Param, bRemove = self:HitSpecialObstacle(nSpecialId)
self:SpecialObstacleFunc(self.curGiftPenguin, nDeltaTime, nType, Param)
if bRemove then
table.insert(tbHittedObs, nSpecialId)
end
if not self.bFlying then
self:DestroyPenguin()
break
end
end
end
end
for _, nId in ipairs(tbHittedObs) do
table.removebyvalue(self.tbExObstacleCur, nId, true)
end
return nCurPosX, nCurPosY
end
function ThrowGiftsLevelCtrl:SplitPenguinUpdate(nDeltaTime)
local nCurPosX, nCurPosY = 0, 0
local tbCachedGoalId = {}
local Split = function(mapPenguin, nAngle, nVelocity, initPos)
mapPenguin.bSplit = true
local goPenguin = instantiate(self._mapNode.templateBullet, self._mapNode.rtPenguinRoot)
local rtPenguin = goPenguin:GetComponent("RectTransform")
local goImgRoot = rtPenguin:Find("imgRoot")
local imgFx = goImgRoot:Find("imgFx")
local rtRed = goImgRoot:Find("penguin_red")
local rtYellow = goImgRoot:Find("penguin_yellow")
local rtGreen = goImgRoot:Find("penguin_green")
local rtGoggles = goImgRoot:Find("penguin_goggles")
local rtAntenna = goImgRoot:Find("penguin_antenna")
local rtHelmet = goImgRoot:Find("penguin_helmet")
local rtImgRoot
if goImgRoot ~= nil then
rtImgRoot = goImgRoot:GetComponent("RectTransform")
end
rtPenguin.anchoredPosition = initPos
rtRed.gameObject:SetActive(mapPenguin.nType == 2)
rtYellow.gameObject:SetActive(mapPenguin.nType == 3)
rtGreen.gameObject:SetActive(mapPenguin.nType == 1)
rtGoggles.gameObject:SetActive(false)
rtAntenna.gameObject:SetActive(false)
rtHelmet.gameObject:SetActive(false)
imgFx.gameObject:SetActive(self.mapCurActiveState[105] ~= nil)
rtPenguin.anchoredPosition = initPos
goPenguin:SetActive(true)
local mapGiftPenguin = {
goGiftPenguin = rtPenguin,
nState = 0,
nType = mapPenguin.nType,
nStartAngle = nAngle,
nVelocityX = nVelocity * math.cos(math.rad(nAngle)),
nVelocityY = nVelocity * math.sin(math.rad(nAngle)),
mapStartPos = initPos,
rtImgRoot = rtImgRoot,
tbBounds = self:GetLocalSpaceRect(rtPenguin, rtPenguin.parent),
curPosX = initPos.x,
curPosY = initPos.y,
bFlying = true,
nHitTime = 0
}
return mapGiftPenguin
end
if self.curGiftPenguin.bSplit then
local bHasSubPenguin = false
self.nFlyingTime = self.nFlyingTime + nDeltaTime
for _, mapSubPenguin in ipairs(self.curGiftPenguin.tbSubPenguin) do
if mapSubPenguin.bFlying then
nCurPosX = mapSubPenguin.curPosX + nDeltaTime * mapSubPenguin.nVelocityX
nCurPosY = mapSubPenguin.curPosY + nDeltaTime * mapSubPenguin.nVelocityY - 0.5 * self.nAG * nDeltaTime * nDeltaTime
mapSubPenguin.nVelocityY = mapSubPenguin.nVelocityY - self.nAG * nDeltaTime
mapSubPenguin.curPosX = nCurPosX
mapSubPenguin.curPosY = nCurPosY
mapSubPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
local nSumX = nCurPosX - mapSubPenguin.mapStartPos.x
local nSumY = nCurPosY - mapSubPenguin.mapStartPos.y
local curVy = mapSubPenguin.nVelocityY
if mapSubPenguin.rtImgRoot ~= nil then
local nFlyAngle = math.deg(math.atan(curVy, mapSubPenguin.nVelocityX))
mapSubPenguin.rtImgRoot.localEulerAngles = Vector3(0, 0, nFlyAngle)
end
for _, tbBounds in ipairs(self.tbObstacle) do
local bHit = self:CheckCollision(mapSubPenguin.tbBounds, tbBounds, nSumX, nSumY, 0, 0)
if bHit then
print("hit Obstacle")
self:DestroySubPenguin(mapSubPenguin)
mapSubPenguin.bFlying = false
break
end
end
if mapSubPenguin.bFlying and (nCurPosX > 0.5 * self.sceneSize[1] or nCurPosX < -0.5 * self.sceneSize[1] or nCurPosY > 0.5 * self.sceneSize[2] or nCurPosY < -0.5 * self.sceneSize[2]) then
print("hit border")
self:DestroySubPenguin(mapSubPenguin)
mapSubPenguin.bFlying = false
end
if mapSubPenguin.bFlying then
local tbHittedObs = {}
for _, nSpecialId in ipairs(self.tbExObstacleCur) do
local mapConfig = self.mapExObstacleOrigin[nSpecialId]
if mapConfig ~= nil then
local bHit = self:CheckCollision(mapSubPenguin.tbBounds, mapConfig.tbBounds, nSumX, nSumY, 0, 0)
if bHit then
local nType, Param, bRemove
mapSubPenguin.bFlying, nType, Param, bRemove = self:HitSpecialObstacle(nSpecialId)
self:SpecialObstacleFunc(mapSubPenguin, nDeltaTime, nType, Param)
if bRemove then
table.insert(tbHittedObs, nSpecialId)
end
if not mapSubPenguin.bFlying then
self:DestroySubPenguin(mapSubPenguin)
break
end
end
end
end
for _, nId in ipairs(tbHittedObs) do
table.removebyvalue(self.tbExObstacleCur, nId, true)
end
end
if mapSubPenguin.bFlying then
bHasSubPenguin = true
end
end
end
self.bFlying = bHasSubPenguin
if not self.bFlying then
tbCachedGoalId = clone(self.curGiftPenguin.tbCacheSubPenguinGoal)
self.curGiftPenguin = nil
end
else
self.nFlyingTime = self.nFlyingTime + nDeltaTime
nCurPosX = self.curGiftPenguin.curPosX + nDeltaTime * self.curGiftPenguin.nVelocityX
nCurPosY = self.curGiftPenguin.curPosY + nDeltaTime * self.curGiftPenguin.nVelocityY - 0.5 * self.nAG * nDeltaTime * nDeltaTime
self.curGiftPenguin.nVelocityY = self.curGiftPenguin.nVelocityY - self.nAG * nDeltaTime
self.curGiftPenguin.curPosX = nCurPosX
self.curGiftPenguin.curPosY = nCurPosY
self.curGiftPenguin.goGiftPenguin.anchoredPosition = Vector2(nCurPosX, nCurPosY)
local nSumX = nCurPosX - self.curGiftPenguin.mapStartPos.x
local nSumY = nCurPosY - self.curGiftPenguin.mapStartPos.y
local curVy = self.curGiftPenguin.nVelocityY
if self.curGiftPenguin.rtImgRoot ~= nil then
local nFlyAngle = math.deg(math.atan(curVy, self.curGiftPenguin.nVelocityX))
self.curGiftPenguin.rtImgRoot.localEulerAngles = Vector3(0, 0, nFlyAngle)
end
for _, tbBounds in ipairs(self.tbObstacle) do
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, tbBounds, nSumX, nSumY, 0, 0)
if bHit then
self:DestroyPenguin()
self.bFlying = false
break
end
end
if not self.bFlying then
return 0, 0, tbCachedGoalId
end
if nCurPosX > 0.5 * self.sceneSize[1] or nCurPosX < -0.5 * self.sceneSize[1] or nCurPosY > 0.5 * self.sceneSize[2] or nCurPosY < -0.5 * self.sceneSize[2] then
print("hit border")
self:DestroyPenguin()
self.bFlying = false
end
if not self.bFlying then
return 0, 0, {}
end
local tbHittedObs = {}
for _, nSpecialId in ipairs(self.tbExObstacleCur) do
local mapConfig = self.mapExObstacleOrigin[nSpecialId]
if mapConfig ~= nil then
local bHit = self:CheckCollision(self.curGiftPenguin.tbBounds, mapConfig.tbBounds, nSumX, nSumY, 0, 0)
if bHit then
local nType, Param, bRemove
self.bFlying, nType, Param, bRemove = self:HitSpecialObstacle(nSpecialId)
self:SpecialObstacleFunc(self.curGiftPenguin, nDeltaTime, nType, Param)
if bRemove then
table.insert(tbHittedObs, nSpecialId)
end
if not self.bFlying then
self:DestroyPenguin()
break
end
end
end
end
for _, nId in ipairs(tbHittedObs) do
table.removebyvalue(self.tbExObstacleCur, nId, true)
end
if self.bFlying and curVy <= 0 then
self.curGiftPenguin.bSplit = true
local initPos = self.curGiftPenguin.goGiftPenguin.anchoredPosition
local nCurVelocity = math.sqrt(self.curGiftPenguin.nVelocityY * self.curGiftPenguin.nVelocityY + self.curGiftPenguin.nVelocityX * self.curGiftPenguin.nVelocityX)
local nFlyAngle = math.deg(math.atan(self.curGiftPenguin.nVelocityY, self.curGiftPenguin.nVelocityX))
for i = -1, 1 do
local mapSubPenguin = Split(self.curGiftPenguin, nFlyAngle + 20 * i, nCurVelocity, initPos)
table.insert(self.curGiftPenguin.tbSubPenguin, mapSubPenguin)
end
WwiseAudioMgr:PostEvent("Mode_Present_split")
self:DestroySubPenguin(self.curGiftPenguin, true)
end
end
return nCurPosX, nCurPosY, tbCachedGoalId
end
function ThrowGiftsLevelCtrl:SetBeginningAngle(nAngle, nVelocity)
local fixedAngle = nAngle == 0 and 0 or nAngle - 90
self._mapNode.rtBottle.localEulerAngles = Vector3(0, 0, fixedAngle)
self._mapNode.goBeginningMark.transform.localEulerAngles = Vector3(0, 0, fixedAngle)
local sumScale = nVelocity / self.maxVelocity * 0.2
local sumHeight = nVelocity / self.maxVelocity * 3
self._mapNode.rtBottle.localScale = Vector3(1 + sumScale, 1 - sumScale, 1)
self._mapNode.rtBeginningMark.sizeDelta = Vector2(nMarkWidth, nMarkHeight * (1 + sumHeight))
end
function ThrowGiftsLevelCtrl:SetBeginningLine(nAngle, nVelocity)
if self.curPenguinSpecialType == 106 then
if nVelocity == 0 then
self._mapNode.rtBeginningLine.gameObject:SetActive(false)
return
end
self._mapNode.rtBeginningLine.gameObject:SetActive(true)
self._mapNode.rtBeginningLine.position = self._mapNode.rtBeginningPos.position
local vX = nVelocity * math.cos(math.rad(nAngle))
local vY = nVelocity * math.sin(math.rad(nAngle))
local t_stop = vY / self.nAG
if t_stop < 0 then
t_stop = 0
end
for i = 1, 30 do
if i <= 10 then
local dotx = self.nLinePointInterval * i * vX
local dotY = 0
if t_stop >= self.nLinePointInterval * i then
dotY = self.nLinePointInterval * i * vY - 0.5 * self.nAG * (self.nLinePointInterval * i) * (self.nLinePointInterval * i)
else
dotY = t_stop * vY - 0.5 * self.nAG * t_stop * t_stop
end
self._mapNode.BeginningDot[i].anchoredPosition = Vector2(dotx, dotY)
self._mapNode.BeginningDot[i].gameObject:SetActive(true)
else
self._mapNode.BeginningDot[i].gameObject:SetActive(false)
end
end
elseif self.curPenguinSpecialType == 108 then
if nVelocity == 0 then
self._mapNode.rtBeginningLine.gameObject:SetActive(false)
return
end
self._mapNode.rtBeginningLine.gameObject:SetActive(true)
self._mapNode.rtBeginningLine.position = self._mapNode.rtBeginningPos.position
local vX = nVelocity * math.cos(math.rad(nAngle))
local vY = nVelocity * math.sin(math.rad(nAngle))
for i = 1, 30 do
local dotx = self.nLinePointInterval * i * vX
local dotY = self.nLinePointInterval * i * vY - 0.5 * self.nAG * (self.nLinePointInterval * i) * (self.nLinePointInterval * i)
self._mapNode.BeginningDot[i].anchoredPosition = Vector2(dotx, dotY)
self._mapNode.BeginningDot[i].gameObject:SetActive(true)
end
else
if nVelocity == 0 then
self._mapNode.rtBeginningLine.gameObject:SetActive(false)
return
end
self._mapNode.rtBeginningLine.gameObject:SetActive(true)
self._mapNode.rtBeginningLine.position = self._mapNode.rtBeginningPos.position
local vX = nVelocity * math.cos(math.rad(nAngle))
local vY = nVelocity * math.sin(math.rad(nAngle))
for i = 1, 30 do
if i <= 10 then
local dotx = self.nLinePointInterval * i * vX
local dotY = self.nLinePointInterval * i * vY - 0.5 * self.nAG * (self.nLinePointInterval * i) * (self.nLinePointInterval * i)
self._mapNode.BeginningDot[i].anchoredPosition = Vector2(dotx, dotY)
self._mapNode.BeginningDot[i].gameObject:SetActive(true)
else
self._mapNode.BeginningDot[i].gameObject:SetActive(false)
end
end
end
end
function ThrowGiftsLevelCtrl:HitSpecialObstacle(nSpecialId)
local mapOriginConfig = self.mapExObstacleOrigin[nSpecialId]
local nType = 0
local Param = {}
if mapOriginConfig ~= nil then
if mapOriginConfig.mapConfig.Type == GameEnum.SpecialObstacleType.Obstacle then
mapOriginConfig.gameObject:SetActive(false)
return false, nType, Param, true
elseif mapOriginConfig.mapConfig.Type == GameEnum.SpecialObstacleType.Score then
mapOriginConfig.gameObject:SetActive(false)
local nScore = mapOriginConfig.mapConfig.Param[1]
if nScore ~= nil then
self:AddScore(nScore)
end
return true, nType, Param, true
elseif mapOriginConfig.mapConfig.Type == GameEnum.SpecialObstacleType.WindForce then
nType = 1
Param.WindForce = mapOriginConfig.mapConfig.Param[1] * 10
Param.nAngle = mapOriginConfig.gameObject.transform.localEulerAngles.z
return true, nType, Param, false
elseif mapOriginConfig.mapConfig.Type == GameEnum.SpecialObstacleType.Portal then
nType = 2
Param.Exit = mapOriginConfig.mapConfig.Param[1]
return true, nType, Param, false
end
end
return true, nType, Param, true
end
function ThrowGiftsLevelCtrl:SpecialObstacleFunc(mapPenguin, nDeltaTime, nType, Param)
if nType == nil or Param == nil then
return
end
if nType == 1 then
local nAcceleration = Param.WindForce * nDeltaTime
local nAccelerationX = nAcceleration * math.cos(math.rad(Param.nAngle))
local nAccelerationY = nAcceleration * math.sin(math.rad(Param.nAngle))
mapPenguin.nVelocityX = mapPenguin.nVelocityX + nAccelerationX
mapPenguin.nVelocityY = mapPenguin.nVelocityY + nAccelerationY
elseif nType == 2 then
WwiseAudioMgr:PostEvent("Mode_Present_portals")
local nExitId = Param.Exit
local mapExitConfig
for nInstanceId, mapObstacle in pairs(self.mapExObstacleOrigin) do
if mapObstacle.mapConfig.Id == nExitId then
mapExitConfig = mapObstacle
break
end
end
if mapExitConfig ~= nil then
local rtExit = mapExitConfig.gameObject:GetComponent("RectTransform")
local nCurVelocity = math.sqrt(mapPenguin.nVelocityY * mapPenguin.nVelocityY + mapPenguin.nVelocityX * mapPenguin.nVelocityX)
local nFlyAngle = rtExit.localEulerAngles.z
mapPenguin.goGiftPenguin.anchoredPosition = rtExit.anchoredPosition
mapPenguin.nVelocityX = nCurVelocity * math.cos(math.rad(nFlyAngle))
mapPenguin.nVelocityY = nCurVelocity * math.sin(math.rad(nFlyAngle))
mapPenguin.tbBounds = self:GetLocalSpaceRect(mapPenguin.goGiftPenguin.transform, mapPenguin.goGiftPenguin.transform.parent)
mapPenguin.curPosX = rtExit.anchoredPosition.x
mapPenguin.curPosY = rtExit.anchoredPosition.y
mapPenguin.mapStartPos = rtExit.anchoredPosition
end
end
end
function ThrowGiftsLevelCtrl:AddScore(nScore)
self.nLevelScore = self.nLevelScore + nScore
if self.mapCurActiveState[104] ~= nil then
self.nLevelScore = self.nLevelScore + nScore
end
self.parent:SetScore(self.nLevelScore)
end
function ThrowGiftsLevelCtrl:SetPenguinType(rtPenguinRoot, nType, nSpecialType)
if rtPenguinRoot == nil then
return
end
local rtRed = rtPenguinRoot:Find("penguin_red")
local rtYellow = rtPenguinRoot:Find("penguin_yellow")
local rtGreen = rtPenguinRoot:Find("penguin_green")
local rtGoggles = rtPenguinRoot:Find("penguin_goggles")
local rtAntenna = rtPenguinRoot:Find("penguin_antenna")
local rtHelmet = rtPenguinRoot:Find("penguin_helmet")
local rtSplit = rtPenguinRoot:Find("Penguin_split")
local rtSpring = rtPenguinRoot:Find("Penguin_spring")
local imgFx = rtPenguinRoot:Find("imgFx")
rtRed.gameObject:SetActive(nType == 2)
rtYellow.gameObject:SetActive(nType == 3)
rtGreen.gameObject:SetActive(nType == 1)
rtGoggles.gameObject:SetActive(nSpecialType == 106)
rtAntenna.gameObject:SetActive(nSpecialType == 108)
rtHelmet.gameObject:SetActive(nSpecialType == 107)
if rtSplit ~= nil then
rtSplit.gameObject:SetActive(nSpecialType == 110)
rtSpring.gameObject:SetActive(nSpecialType == 109)
end
imgFx.gameObject:SetActive(self.mapCurActiveState[105] ~= nil)
end
function ThrowGiftsLevelCtrl:CreateGoal(nSpawnPointId, mapConfig)
if self.activeGoal[nSpawnPointId] ~= nil then
return
end
local pointOriginPosX = mapConfig.rtPoint.anchoredPosition.x
local pointOriginPosY = mapConfig.rtPoint.anchoredPosition.y
local randomX = math.random(-mapConfig.mapConfig.SpawnRangeTypeX, mapConfig.mapConfig.SpawnRangeTypeX)
local randomY = math.random(-mapConfig.mapConfig.SpawnRangeTypeY, mapConfig.mapConfig.SpawnRangeTypeY)
local nType = 0
if mapConfig.mapConfig.IsRandom then
nType = mapConfig.mapConfig.GoalType[math.random(1, #mapConfig.mapConfig.GoalType)]
else
if mapConfig.nCurGoalIdx > #mapConfig.mapConfig.GoalType then
mapConfig.nCurGoalIdx = 1
end
nType = mapConfig.mapConfig.GoalType[mapConfig.nCurGoalIdx]
mapConfig.nCurGoalIdx = mapConfig.nCurGoalIdx + 1
end
local sPath = string.format(self.rootPath, nType)
local goGoalPerfab = GameResourceLoader.LoadAsset(ResTypeAny, Settings.AB_ROOT_PATH .. sPath, typeof(Object))
if goGoalPerfab ~= nil then
local goGoal = instantiate(goGoalPerfab, self._mapNode.rtGoalRoot)
self.activeGoal[nSpawnPointId] = {}
local rtGoal = goGoal:GetComponent("RectTransform")
rtGoal.anchoredPosition = Vector2(pointOriginPosX + randomX, pointOriginPosY + randomY)
local rtHitArea = rtGoal:Find("HitArea")
local rtObstacle = rtGoal:Find("Obstacle")
local rtItemBuff = rtGoal:Find("AnimRoot/imgItembuff")
if rtItemBuff ~= nil then
rtItemBuff.gameObject:SetActive(0 < mapConfig.mapConfig.ItemPool)
end
if rtHitArea == nil or rtObstacle == nil then
printError("预制体结构错误:" .. sPath)
destroy(goGoal)
return
end
self.activeGoal[nSpawnPointId].rtGoal = rtGoal
self.activeGoal[nSpawnPointId].nType = nType
local rtCompHitArea = rtHitArea:GetComponent("RectTransform")
local rtCompObstacle = rtObstacle:GetComponent("RectTransform")
self.activeGoal[nSpawnPointId].tbBoundsHitArea = self:GetLocalSpaceRect(rtCompHitArea, rtGoal.parent)
self.activeGoal[nSpawnPointId].tbBoundsObstacle = self:GetLocalSpaceRect(rtCompObstacle, rtGoal.parent)
self.activeGoal[nSpawnPointId].OffsetX = 0
self.activeGoal[nSpawnPointId].OffsetY = 0
self.activeGoal[nSpawnPointId].initialPosX = pointOriginPosX + randomX
self.activeGoal[nSpawnPointId].initialPosY = pointOriginPosY + randomY
local TMPNode
local rtTMPScore = rtGoal:Find("AnimRoot/TMPLevelScoreAdd")
if rtTMPScore ~= nil then
TMPNode = rtTMPScore:GetComponent("TMP_Text")
end
self.activeGoal[nSpawnPointId].TMPScore = TMPNode
end
end
function ThrowGiftsLevelCtrl:CreateThrowPenguin(nAngle, nVelocity, initPos, nType, nSpecialType)
self._mapNode.imgBeginningHint:SetActive(false)
local goPenguin = instantiate(self._mapNode.templateBullet, self._mapNode.rtPenguinRoot)
local rtPenguin = goPenguin:GetComponent("RectTransform")
local goImgRoot = rtPenguin:Find("imgRoot")
local imgFx = goImgRoot:Find("imgFx")
local rtRed = goImgRoot:Find("penguin_red")
local rtYellow = goImgRoot:Find("penguin_yellow")
local rtGreen = goImgRoot:Find("penguin_green")
local rtGoggles = goImgRoot:Find("penguin_goggles")
local rtAntenna = goImgRoot:Find("penguin_antenna")
local rtHelmet = goImgRoot:Find("penguin_helmet")
local rtSplit = goImgRoot:Find("Penguin_split")
local rtSpring = goImgRoot:Find("Penguin_spring")
local rtImgRoot
if goImgRoot ~= nil then
rtImgRoot = goImgRoot:GetComponent("RectTransform")
end
rtRed.gameObject:SetActive(nType == 2)
rtYellow.gameObject:SetActive(nType == 3)
rtGreen.gameObject:SetActive(nType == 1)
rtGoggles.gameObject:SetActive(nSpecialType == 106)
rtAntenna.gameObject:SetActive(nSpecialType == 108)
rtHelmet.gameObject:SetActive(nSpecialType == 107)
rtSplit.gameObject:SetActive(nSpecialType == 110)
rtSpring.gameObject:SetActive(nSpecialType == 109)
imgFx.gameObject:SetActive(self.mapCurActiveState[105] ~= nil)
rtPenguin.anchoredPosition = initPos
goPenguin:SetActive(true)
if self.mapLevelCfgData.FlightPath == true then
self._mapNode.rtBlindLevelTrack:Reset()
end
local mapGiftPenguin = {
goGiftPenguin = rtPenguin,
nState = 0,
nSpecialType = nSpecialType,
nType = nType,
nStartAngle = nAngle,
nVelocityX = nVelocity * math.cos(math.rad(nAngle)),
nVelocityY = nVelocity * math.sin(math.rad(nAngle)),
mapStartPos = initPos,
rtImgRoot = rtImgRoot,
tbBounds = self:GetLocalSpaceRect(rtPenguin, rtPenguin.parent),
curPosX = initPos.x,
curPosY = initPos.y,
targetGoal = nil,
nGetTargetTime = 0,
nTrackIdx = 0,
nHitCount = 0,
tbSubPenguin = {},
bSplit = false,
tbCacheSubPenguinGoal = {},
nHitTime = 0
}
if nSpecialType == 108 then
local rtTrack = instantiate(self._mapNode.rtTemplateTrack, self._mapNode.rtScene)
rtTrack.transform:SetAsFirstSibling()
rtTrack:SetActive(true)
local mapTrackCtrl = self:BindCtrlByNode(rtTrack.gameObject, "Game.UI.Activity.ThrowGifts.ThrowGiftLevelTrackLineCtrl")
mapTrackCtrl:Reset()
table.insert(self.tbItemTrackCtrl, mapTrackCtrl)
mapGiftPenguin.nTrackIdx = #self.tbItemTrackCtrl
end
return mapGiftPenguin
end
function ThrowGiftsLevelCtrl:HitGoal(hitPos, hitGoalId)
local mapSpawnPointData = self.mapGoal[hitGoalId]
if mapSpawnPointData == nil then
return
end
local mapCurGoalCfg = self.activeGoal[hitGoalId]
if mapCurGoalCfg == nil then
return
end
if self.tbGuideTrackCtrl ~= nil and #self.tbGuideTrackCtrl ~= 0 then
self:ClearGuideLine()
end
local nType = self.activeGoal[hitGoalId].nType % 10
local nScore = (self.curPenguinType == nType or self.mapCurActiveState[105] ~= nil) and 200 or 100
self:AddScore(nScore)
if self.activeGoal[hitGoalId].TMPScore ~= nil then
if self.mapCurActiveState[104] ~= nil then
nScore = nScore * 2
end
NovaAPI.SetTMPText(self.activeGoal[hitGoalId].TMPScore, string.format("+%d", nScore))
end
self.nTotalHitGoalCount = self.nTotalHitGoalCount + 1
WwiseAudioMgr:PostEvent("Mode_Present_in")
self.activeGoal[hitGoalId] = nil
local AfterAnim = function()
destroy(mapCurGoalCfg.rtGoal.gameObject)
if mapSpawnPointData.mapConfig.ActiveCond == GameEnum.ThrowGiftSpawnCond.Random then
local tbRandom = {}
for _, nCondSpawnId in ipairs(mapSpawnPointData.mapConfig.SpawnParam) do
if self.activeGoal[nCondSpawnId] == nil then
table.insert(tbRandom, nCondSpawnId)
end
end
if 0 < #tbRandom then
local nRandomId = tbRandom[math.random(1, #tbRandom)]
if nRandomId ~= nil then
local mapConfig = self.mapGoal[nRandomId]
if mapConfig ~= nil then
self:CreateGoal(nRandomId, mapConfig)
end
end
end
else
for nId, mapGoalCfg in pairs(self.mapGoal) do
if mapGoalCfg.mapConfig.ActiveCond > 0 and #mapGoalCfg.mapConfig.SpawnParam > 0 and 0 < table.indexof(mapGoalCfg.mapConfig.SpawnParam, hitGoalId) then
if mapGoalCfg.mapConfig.ActiveCond == GameEnum.ThrowGiftSpawnCond.Partial then
if self.activeGoal[nId] == nil then
self:CreateGoal(nId, mapGoalCfg)
end
elseif mapGoalCfg.mapConfig.ActiveCond == GameEnum.ThrowGiftSpawnCond.All then
table.insert(mapGoalCfg.curCondId, hitGoalId)
local bActive = true
for _, nCondSpawnId in ipairs(mapGoalCfg.mapConfig.SpawnParam) do
if 1 > table.indexof(mapGoalCfg.curCondId, nCondSpawnId) then
bActive = false
break
end
end
if bActive and self.activeGoal[nId] == nil then
mapGoalCfg.curCondId = {}
self:CreateGoal(nId, mapGoalCfg)
end
end
end
end
end
end
local rtAnimRoot = mapCurGoalCfg.rtGoal:Find("AnimRoot")
local rtItemBuff = mapCurGoalCfg.rtGoal:Find("AnimRoot/imgItembuff")
if rtItemBuff ~= nil then
rtItemBuff.gameObject:SetActive(false)
end
if rtAnimRoot == nil then
AfterAnim()
else
local animComp = rtAnimRoot:GetComponent("Animator")
if animComp == nil then
AfterAnim()
else
animComp:Play("BasketFx_in")
self:AddTimer(1, 0.5, AfterAnim, true, true, true)
end
end
end
function ThrowGiftsLevelCtrl:DestroyPenguin()
WwiseAudioMgr:PostEvent("Mode_Present_out")
local tempPenguin = self.curGiftPenguin.goGiftPenguin.gameObject.transform
self.curGiftPenguin = nil
local wait = function()
destroy(tempPenguin.gameObject)
end
local imgRoot = tempPenguin:Find("imgRoot")
local imgSmoke = tempPenguin:Find("imgSmoke")
if imgRoot == nil or imgSmoke == nil then
wait()
return
end
imgRoot.gameObject:SetActive(false)
imgSmoke.gameObject:SetActive(true)
self:AddTimer(1, 0.5, wait, true, true, true)
end
function ThrowGiftsLevelCtrl:DestroySubPenguin(mapSubPenguin, bMainPenguin)
if bMainPenguin ~= true then
WwiseAudioMgr:PostEvent("Mode_Present_out")
end
local tempPenguin = mapSubPenguin.goGiftPenguin.gameObject.transform
local wait = function()
destroy(tempPenguin.gameObject)
end
mapSubPenguin.goGiftPenguin = nil
local imgRoot = tempPenguin:Find("imgRoot")
local imgSmoke = tempPenguin:Find("imgSmoke")
if imgRoot == nil or imgSmoke == nil then
wait()
return
end
imgRoot.gameObject:SetActive(false)
imgSmoke.gameObject:SetActive(true)
self:AddTimer(1, 0.5, wait, true, true, true)
end
function ThrowGiftsLevelCtrl:OnDrag_Beginning(mDrag)
if self.nLevelType ~= 1 or self.bFlying then
return
end
if mDrag.DragEventType == AllEnum.UIDragType.DragStart then
local a = self.sceneSize[1] * self.scenePivot[1]
local b = self.sceneSize[1] / 2
local c = a - b
self.curDragBeginPos = {
x = self._mapNode.rtBeginning.anchoredPosition.x - c,
y = self._mapNode.rtBeginning.anchoredPosition.y
}
local uipos = GameUIUtils.ScreenPointToLocalPoint(mDrag.EventData.position, self._mapNode.rtScene)
local nSumX = self.curDragBeginPos.x - uipos.x
local nSumY = self.curDragBeginPos.y - uipos.y
local nVelocity = 0
if 0 < nSumX then
nVelocity = math.sqrt(nSumY * nSumY + nSumX * nSumX) * 2.5
if nVelocity > self.maxVelocity then
nVelocity = self.maxVelocity
elseif nVelocity < 10 then
nVelocity = 0
end
end
local nAngle = math.atan(nSumY, nSumX) * 180 / math.pi
if nAngle > self.nAngelMax then
nAngle = self.nAngelMax
elseif nAngle < self.nAngleMin then
nAngle = self.nAngleMin
end
self.nCurAngle = nAngle
if nVelocity < self.minVelovity then
nVelocity = self.minVelovity
end
self.nCurVelocity = nVelocity
self._mapNode.goBeginningMark:SetActive(true)
self:SetBeginningAngle(nAngle, nVelocity)
self:SetBeginningLine(nAngle, nVelocity)
WwiseAudioMgr:PostEvent("Mode_Present_pre_lp")
self.parent:SetViewBtn(0)
elseif mDrag.DragEventType == AllEnum.UIDragType.Drag then
if self.curDragBeginPos == nil then
return
end
local uipos = GameUIUtils.ScreenPointToLocalPoint(mDrag.EventData.position, self._mapNode.rtScene)
local nSumX = self.curDragBeginPos.x - uipos.x
local nSumY = self.curDragBeginPos.y - uipos.y
local nVelocity = 0
if 0 < nSumX then
nVelocity = math.min(1, math.sqrt(nSumY * nSumY + nSumX * nSumX) / 400) * self.maxVelocity
if nVelocity > self.maxVelocity then
nVelocity = self.maxVelocity
elseif nVelocity < 10 then
nVelocity = 0
end
end
local nAngle = math.atan(nSumY, nSumX) * 180 / math.pi
if nAngle > self.nAngelMax then
nAngle = self.nAngelMax
elseif nAngle < self.nAngleMin then
nAngle = self.nAngleMin
end
self.nCurAngle = nAngle
if nVelocity < self.minVelovity then
nVelocity = self.minVelovity
end
self.nCurVelocity = nVelocity
self:SetBeginningAngle(nAngle, nVelocity)
self:SetBeginningLine(nAngle, nVelocity)
if self.tbGuideTrackCtrl ~= nil then
for _, mapLineCtrl in ipairs(self.tbGuideTrackCtrl) do
mapLineCtrl:SetLineActive(nAngle, nVelocity)
end
end
elseif mDrag.DragEventType == AllEnum.UIDragType.DragEnd then
WwiseAudioMgr:PostEvent("Mode_Present_pre_lp_stop")
self._mapNode.goBeginningMark:SetActive(false)
if self.curDragBeginPos == nil then
return
end
if self.nCurVelocity == 0 then
if self.mapLevelCfgData.SwitchArrow == true then
self.parent:SetViewBtn(1)
end
self.curDragBeginPos = nil
return
end
self.nTotalThrowGiftCount = self.nTotalThrowGiftCount + 1
self.curDragBeginPos = nil
self.bFlying = true
self.nFlyingTime = 0
self:SetBeginningAngle(self.nCurAngle, 0)
self:SetBeginningLine(0, 0)
local nStartVelocity = self.nCurVelocity
local nStartAngle = self.nCurAngle
self.nCurAngle = 0
self.nCurVelocity = 0
self._mapNode.rtBottleAnim:Play("rtBottle_out")
WwiseAudioMgr:PostEvent("Mode_Present_fire")
local wait = function()
local worldPos = self._mapNode.rtBeginningPos:TransformPoint(Vector3.zero)
local sumPos = self._mapNode.rtBeginning:InverseTransformPoint(worldPos)
local beginningPos = self._mapNode.rtBeginning.anchoredPosition
local nSpecialType = self.curPenguinSpecialType == 0 and self.defaultPenguinSpecialType or self.curPenguinSpecialType
local mapGiftPenguin = self:CreateThrowPenguin(nStartAngle, nStartVelocity, Vector2(beginningPos.x + sumPos.x, beginningPos.y + sumPos.y), self.curPenguinType, nSpecialType)
self.curPenguinSpecialType = 0
self.curGiftPenguin = mapGiftPenguin
if 0 < self.nTotalPenguinCount and self.mapCurActiveState[102] == nil then
self.nTotalPenguinCount = self.nTotalPenguinCount - 1
end
NovaAPI.SetTMPText(self._mapNode.TMPBeginningCountHint, self.nTotalPenguinCount)
end
self:AddTimer(1, 0.12, wait, true, true, true)
end
end
return ThrowGiftsLevelCtrl