更新
This commit is contained in:
parent
f440012952
commit
e13d346923
@ -1,70 +0,0 @@
|
|||||||
--> Services
|
|
||||||
local Players = game:GetService("Players")
|
|
||||||
local UserInputService = game:GetService("UserInputService")
|
|
||||||
|
|
||||||
--> Dependencies
|
|
||||||
local UIManager = require(script.Parent.Parent.UI.UIManager)
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
local LocalPlayer = Players.LocalPlayer
|
|
||||||
|
|
||||||
-- 测试执行记录
|
|
||||||
local testExecutionRecords = {
|
|
||||||
{
|
|
||||||
runeName = "RuneFireDamage",
|
|
||||||
runeUniqueId = 1,
|
|
||||||
index = 1,
|
|
||||||
timestamp = tick(),
|
|
||||||
action = "Execute",
|
|
||||||
attributesBefore = {attack = 100, hp = 1000, atkSpeed = 100},
|
|
||||||
attributesAfter = {attack = 150, hp = 1000, atkSpeed = 120},
|
|
||||||
behaviorListBefore = {"Attack"},
|
|
||||||
behaviorListAfter = {"Attack", "FireDamage"},
|
|
||||||
nextIndex = 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
runeName = "RuneIceCoffin",
|
|
||||||
runeUniqueId = 2,
|
|
||||||
index = 2,
|
|
||||||
timestamp = tick(),
|
|
||||||
action = "Execute",
|
|
||||||
attributesBefore = {attack = 150, hp = 1000, atkSpeed = 120},
|
|
||||||
attributesAfter = {attack = 150, hp = 1200, atkSpeed = 120, fireAtk = 50},
|
|
||||||
behaviorListBefore = {"Attack", "FireDamage"},
|
|
||||||
behaviorListAfter = {"Attack", "FireDamage", "IceCoffin"},
|
|
||||||
nextIndex = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-- 键盘输入测试
|
|
||||||
UserInputService.InputBegan:Connect(function(input, gameProcessed)
|
|
||||||
if gameProcessed then return end
|
|
||||||
|
|
||||||
if input.KeyCode == Enum.KeyCode.R then
|
|
||||||
-- 打开符文状态窗口
|
|
||||||
print("打开符文状态窗口")
|
|
||||||
UIManager:OpenWindow("RuneStateWindow")
|
|
||||||
|
|
||||||
elseif input.KeyCode == Enum.KeyCode.T then
|
|
||||||
-- 模拟接收符文执行记录
|
|
||||||
print("模拟符文执行记录")
|
|
||||||
local runeStateWindow = UIManager:GetWindow("RuneStateWindow")
|
|
||||||
if runeStateWindow then
|
|
||||||
runeStateWindow:OnRuneExecutionRecord(testExecutionRecords)
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif input.KeyCode == Enum.KeyCode.C then
|
|
||||||
-- 关闭符文状态窗口
|
|
||||||
print("关闭符文状态窗口")
|
|
||||||
UIManager:CloseWindow("RuneStateWindow")
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
print("符文状态窗口测试脚本已启动")
|
|
||||||
print("按 R 键打开符文状态窗口")
|
|
||||||
print("按 T 键模拟符文执行记录")
|
|
||||||
print("按 C 键关闭符文状态窗口")
|
|
||||||
|
|
||||||
-- 返回一个空表作为模块返回值
|
|
||||||
return {}
|
|
@ -21,7 +21,7 @@ function AbilityStateWindows:Init(UIManager: table, Data: table?)
|
|||||||
["__listAbility"] = 0,
|
["__listAbility"] = 0,
|
||||||
["__listWearAbility"] = 0,
|
["__listWearAbility"] = 0,
|
||||||
}
|
}
|
||||||
self.UIRootName = "ui_w_abilityState"
|
self.UIRootName = "ui_w_ability_state"
|
||||||
self.UIParentName = UIEnums.UIParent.UIRoot
|
self.UIParentName = UIEnums.UIParent.UIRoot
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ local UIWindow = require(ReplicatedStorage.Base.UIWindow)
|
|||||||
local UIEnums = require(ReplicatedStorage.Base.UIEnums)
|
local UIEnums = require(ReplicatedStorage.Base.UIEnums)
|
||||||
local Localization = require(ReplicatedStorage.Tools.Localization)
|
local Localization = require(ReplicatedStorage.Tools.Localization)
|
||||||
local Utils = require(ReplicatedStorage.Tools.Utils)
|
local Utils = require(ReplicatedStorage.Tools.Utils)
|
||||||
|
local FormatNumber = require(ReplicatedStorage.Modules.FormatNumber)
|
||||||
|
|
||||||
--> Json
|
--> Json
|
||||||
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
|
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
|
||||||
@ -24,6 +25,8 @@ function RuneStateWindow:Init(UIManager: table, Data: table?)
|
|||||||
setmetatable(self, RuneStateWindow)
|
setmetatable(self, RuneStateWindow)
|
||||||
self.Variables = {
|
self.Variables = {
|
||||||
["__listRune"] = 0,
|
["__listRune"] = 0,
|
||||||
|
["_tmpCombatValue"] = 0,
|
||||||
|
["_goCombatValue"] = 0,
|
||||||
}
|
}
|
||||||
self.UIRootName = "ui_w_rune_state"
|
self.UIRootName = "ui_w_rune_state"
|
||||||
self.UIParentName = UIEnums.UIParent.UIRoot
|
self.UIParentName = UIEnums.UIParent.UIRoot
|
||||||
@ -38,6 +41,175 @@ function RuneStateWindow:Init(UIManager: table, Data: table?)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 计算战力值
|
||||||
|
function RuneStateWindow:CalculateCombatValue(attributes: table): number
|
||||||
|
if not attributes then return 0 end
|
||||||
|
|
||||||
|
local totalCombatValue = 0
|
||||||
|
|
||||||
|
for attrName, attrValue in pairs(attributes) do
|
||||||
|
-- 通过effectAttribute查找对应的属性配置
|
||||||
|
local attributeData = Utils:GetSpecialKeyDataFromJson(JsonAttributes, "effectAttribute", attrName)
|
||||||
|
if attributeData and attributeData.battleValue then
|
||||||
|
totalCombatValue = math.floor(totalCombatValue + (attrValue / attributeData.battleValue[1]) * attributeData.battleValue[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return math.floor(totalCombatValue)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 获取当前玩家属性
|
||||||
|
function RuneStateWindow:GetCurrentPlayerAttributes(attributesBefore: table?): table
|
||||||
|
local Players = game:GetService("Players")
|
||||||
|
local LocalPlayer = Players.LocalPlayer
|
||||||
|
|
||||||
|
-- 获取玩家数据文件夹
|
||||||
|
local PlayerDataFolder = ReplicatedStorage:WaitForChild("PlayerData")
|
||||||
|
local PlayerFolder = PlayerDataFolder:FindFirstChild(LocalPlayer.UserId)
|
||||||
|
if not PlayerFolder then
|
||||||
|
return attributesBefore or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local attributes = {}
|
||||||
|
|
||||||
|
-- 获取装备属性
|
||||||
|
local EquipmentFolder = PlayerFolder:FindFirstChild("Equipment")
|
||||||
|
if EquipmentFolder then
|
||||||
|
for _, equipmentInstance in pairs(EquipmentFolder:GetChildren()) do
|
||||||
|
local wearing = equipmentInstance:GetAttribute("wearing")
|
||||||
|
if wearing and tonumber(wearing) > 0 then
|
||||||
|
-- 基础属性
|
||||||
|
local baseAttributes = equipmentInstance:GetAttribute("attributes")
|
||||||
|
if baseAttributes and typeof(baseAttributes) == "table" then
|
||||||
|
for attrName, attrValue in pairs(baseAttributes) do
|
||||||
|
attributes[attrName] = (attributes[attrName] or 0) + attrValue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 额外属性
|
||||||
|
local exAttributes = equipmentInstance:GetAttribute("exAttributes")
|
||||||
|
if exAttributes then
|
||||||
|
for attrName, attrValue in pairs(exAttributes) do
|
||||||
|
attributes[attrName] = (attributes[attrName] or 0) + attrValue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 元素属性
|
||||||
|
local elements = equipmentInstance:GetAttribute("elements")
|
||||||
|
if elements then
|
||||||
|
for attrName, attrValue in pairs(elements) do
|
||||||
|
attributes[attrName] = (attributes[attrName] or 0) + attrValue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 元素抗性
|
||||||
|
local elementDef = equipmentInstance:GetAttribute("elementDef")
|
||||||
|
if elementDef then
|
||||||
|
for attrName, attrValue in pairs(elementDef) do
|
||||||
|
attributes[attrName] = (attributes[attrName] or 0) + attrValue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 获取符文属性
|
||||||
|
local RuneFolder = PlayerFolder:FindFirstChild("Rune")
|
||||||
|
if RuneFolder then
|
||||||
|
for _, runeInstance in pairs(RuneFolder:GetChildren()) do
|
||||||
|
local wearing = runeInstance:GetAttribute("wearing")
|
||||||
|
if wearing and tonumber(wearing) > 0 then
|
||||||
|
-- 符文属性(这里需要根据符文的具体实现来获取)
|
||||||
|
-- 暂时跳过符文属性计算
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 获取角色基础属性(从角色配置中获取)
|
||||||
|
local CharacterFolder = PlayerFolder:FindFirstChild("Character")
|
||||||
|
if CharacterFolder then
|
||||||
|
local characterId = CharacterFolder:GetAttribute("characterId")
|
||||||
|
if characterId then
|
||||||
|
local JsonCharacter = require(ReplicatedStorage.Json.Character)
|
||||||
|
local characterData = Utils:GetIdDataFromJson(JsonCharacter, characterId)
|
||||||
|
if characterData then
|
||||||
|
for attrName, attrValue in pairs(characterData) do
|
||||||
|
if type(attrValue) == "number" and attrName ~= "id" and attrName ~= "name" then
|
||||||
|
attributes[attrName] = (attributes[attrName] or 0) + attrValue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 如果属性为空,使用传入的attributesBefore作为默认值
|
||||||
|
if next(attributes) == nil then
|
||||||
|
if attributesBefore then
|
||||||
|
for attrName, attrValue in pairs(attributesBefore) do
|
||||||
|
attributes[attrName] = attrValue
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- 如果没有传入attributesBefore,使用硬编码的测试属性
|
||||||
|
attributes.attack = 100
|
||||||
|
attributes.hp = 1000
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 播放战力值滚动动画
|
||||||
|
function RuneStateWindow:PlayCombatValueAnimation(beforeValue: number, afterValue: number)
|
||||||
|
if beforeValue == afterValue then return end
|
||||||
|
|
||||||
|
local combatValueUI = self.Variables["_goCombatValue"]
|
||||||
|
local tmpCombatValueUI = self.Variables["_tmpCombatValue"]
|
||||||
|
|
||||||
|
if not combatValueUI or not tmpCombatValueUI then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 显示动画战力值组件
|
||||||
|
combatValueUI.Visible = true
|
||||||
|
|
||||||
|
local duration = 1.0 -- 动画持续时间
|
||||||
|
local steps = 30 -- 动画步数
|
||||||
|
local stepDuration = duration / steps
|
||||||
|
local valueDiff = afterValue - beforeValue
|
||||||
|
local valueStep = valueDiff / steps
|
||||||
|
|
||||||
|
local currentValue = beforeValue
|
||||||
|
|
||||||
|
-- 创建动画协程
|
||||||
|
task.spawn(function()
|
||||||
|
for i = 1, steps do
|
||||||
|
currentValue = currentValue + valueStep
|
||||||
|
tmpCombatValueUI.Text = FormatNumber(math.floor(currentValue), "Suffix")
|
||||||
|
task.wait(stepDuration)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 确保最终值正确
|
||||||
|
tmpCombatValueUI.Text = FormatNumber(afterValue, "Suffix")
|
||||||
|
|
||||||
|
-- 动画播放完成后隐藏组件
|
||||||
|
task.wait(0.5) -- 等待0.5秒让玩家看到最终值
|
||||||
|
combatValueUI.Visible = false
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 更新战力值显示
|
||||||
|
function RuneStateWindow:UpdateCombatValueDisplay(attributesBefore: table?)
|
||||||
|
-- local currentAttributes = self:GetCurrentPlayerAttributes(attributesBefore)
|
||||||
|
local currentCombatValue = self:CalculateCombatValue(attributesBefore)
|
||||||
|
|
||||||
|
local combatValueUI = self.Variables["_tmpCombatValue"]
|
||||||
|
if combatValueUI then
|
||||||
|
combatValueUI.Text = FormatNumber(currentCombatValue, "Suffix")
|
||||||
|
end
|
||||||
|
|
||||||
|
return currentCombatValue
|
||||||
|
end
|
||||||
|
|
||||||
function RuneStateWindow:OnOpenWindow()
|
function RuneStateWindow:OnOpenWindow()
|
||||||
UIWindow.OnOpenWindow(self)
|
UIWindow.OnOpenWindow(self)
|
||||||
|
|
||||||
@ -48,6 +220,11 @@ function RuneStateWindow:OnOpenWindow()
|
|||||||
|
|
||||||
-- 初始化符文列表
|
-- 初始化符文列表
|
||||||
self:RefreshRuneList()
|
self:RefreshRuneList()
|
||||||
|
|
||||||
|
-- 更新战力值显示
|
||||||
|
self:UpdateCombatValueDisplay()
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function RuneStateWindow:OnCloseWindow()
|
function RuneStateWindow:OnCloseWindow()
|
||||||
@ -57,6 +234,11 @@ function RuneStateWindow:OnCloseWindow()
|
|||||||
|
|
||||||
-- 断开符文执行记录事件连接
|
-- 断开符文执行记录事件连接
|
||||||
self:DisconnectRuneExecutionEvent()
|
self:DisconnectRuneExecutionEvent()
|
||||||
|
|
||||||
|
-- 隐藏动画战力值组件
|
||||||
|
if self.Variables["_goCombatValue"] then
|
||||||
|
self.Variables["_goCombatValue"].Visible = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 刷新符文列表
|
-- 刷新符文列表
|
||||||
@ -144,6 +326,9 @@ function RuneStateWindow:OnRuneExecutionRecord(executionRecords: table)
|
|||||||
if not self.isPlayingAnimation then
|
if not self.isPlayingAnimation then
|
||||||
self:PlayRuneAnimation()
|
self:PlayRuneAnimation()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 更新战力值显示
|
||||||
|
self:UpdateCombatValueDisplay()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 播放符文动画
|
-- 播放符文动画
|
||||||
@ -155,6 +340,7 @@ function RuneStateWindow:PlayRuneAnimation()
|
|||||||
|
|
||||||
self.isPlayingAnimation = true
|
self.isPlayingAnimation = true
|
||||||
local record = table.remove(self.runeExecutionQueue, 1)
|
local record = table.remove(self.runeExecutionQueue, 1)
|
||||||
|
|
||||||
-- 播放小丑牌动画
|
-- 播放小丑牌动画
|
||||||
self:PlayJokerCardAnimation(record)
|
self:PlayJokerCardAnimation(record)
|
||||||
end
|
end
|
||||||
@ -171,8 +357,18 @@ function RuneStateWindow:PlayJokerCardAnimation(record: table)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 计算战力值变化
|
||||||
|
local beforeCombatValue = self:UpdateCombatValueDisplay(record.attributesBefore)
|
||||||
|
|
||||||
-- 创建动画效果
|
-- 创建动画效果
|
||||||
self:CreateJokerCardEffect(runeItem, record)
|
self:CreateJokerCardEffect(runeItem, record)
|
||||||
|
|
||||||
|
-- 等待动画播放一段时间后计算新的战力值
|
||||||
|
task.wait(0.3)
|
||||||
|
local afterCombatValue = self:UpdateCombatValueDisplay(record.attributesAfter)
|
||||||
|
|
||||||
|
-- 播放战力值滚动动画
|
||||||
|
self:PlayCombatValueAnimation(beforeCombatValue, afterCombatValue)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 查找符文UI元素(通过名称和唯一ID)
|
-- 查找符文UI元素(通过名称和唯一ID)
|
||||||
@ -198,15 +394,16 @@ function RuneStateWindow:FindRuneItemByName(runeName: string)
|
|||||||
-- 在符文列表中查找对应的符文
|
-- 在符文列表中查找对应的符文
|
||||||
local runeList = self.Variables["__listRune"]
|
local runeList = self.Variables["__listRune"]
|
||||||
|
|
||||||
if runeList and runeList.Instances then
|
if not runeList or not runeList.Instances then
|
||||||
for _, component in pairs(runeList.Instances) do
|
return nil
|
||||||
if component.Data then
|
end
|
||||||
if component.Data.runeName == runeName then
|
|
||||||
return component
|
for _, component in pairs(runeList.Instances) do
|
||||||
end
|
if component.Data and component.Data.runeName == runeName then
|
||||||
end
|
return component
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -294,6 +491,19 @@ function RuneStateWindow:CreateAttributeChangeDisplay(runeUI: Instance, record:
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 计算战力值变化并添加到显示中
|
||||||
|
local beforeCombatValue = self:CalculateCombatValue(record.attributesBefore or {})
|
||||||
|
local afterCombatValue = self:CalculateCombatValue(record.attributesAfter or {})
|
||||||
|
local combatValueChange = afterCombatValue - beforeCombatValue
|
||||||
|
|
||||||
|
if combatValueChange ~= 0 then
|
||||||
|
table.insert(attributeChanges, {
|
||||||
|
name = "战力值",
|
||||||
|
change = combatValueChange,
|
||||||
|
isCombatValue = true
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
-- 如果没有属性变化,直接返回
|
-- 如果没有属性变化,直接返回
|
||||||
if #attributeChanges == 0 then
|
if #attributeChanges == 0 then
|
||||||
return
|
return
|
||||||
@ -306,7 +516,7 @@ end
|
|||||||
-- 创建属性变化容器
|
-- 创建属性变化容器
|
||||||
function RuneStateWindow:CreateAttributeChangeContainer(runeUI: Instance, attributeChanges: table)
|
function RuneStateWindow:CreateAttributeChangeContainer(runeUI: Instance, attributeChanges: table)
|
||||||
-- 计算容器高度
|
-- 计算容器高度
|
||||||
local containerHeight = #attributeChanges * 25 + 10
|
local containerHeight = #attributeChanges * 30 + 10
|
||||||
|
|
||||||
-- 创建属性变化显示容器
|
-- 创建属性变化显示容器
|
||||||
local changeContainer = Instance.new("Frame")
|
local changeContainer = Instance.new("Frame")
|
||||||
@ -332,13 +542,23 @@ function RuneStateWindow:CreateAttributeChangeContainer(runeUI: Instance, attrib
|
|||||||
for i, change in ipairs(attributeChanges) do
|
for i, change in ipairs(attributeChanges) do
|
||||||
local changeText = Instance.new("TextLabel")
|
local changeText = Instance.new("TextLabel")
|
||||||
changeText.Size = UDim2.new(1, -10, 0, 20)
|
changeText.Size = UDim2.new(1, -10, 0, 20)
|
||||||
changeText.Position = UDim2.new(0, 5, 0, 5 + (i-1) * 25)
|
changeText.Position = UDim2.new(0, 5, 0, 5 + (i-1) * 30)
|
||||||
changeText.Text = string.format("%s +%d", change.name, change.change)
|
|
||||||
|
-- 格式化显示文本
|
||||||
|
local displayValue = change.isCombatValue and FormatNumber(change.change, "Suffix") or tostring(change.change)
|
||||||
|
changeText.Text = string.format("%s %s%s", change.name, change.change > 0 and "+" or "", displayValue)
|
||||||
|
|
||||||
changeText.TextColor3 = change.change > 0 and Color3.fromRGB(0, 255, 100) or Color3.fromRGB(255, 100, 100)
|
changeText.TextColor3 = change.change > 0 and Color3.fromRGB(0, 255, 100) or Color3.fromRGB(255, 100, 100)
|
||||||
changeText.TextScaled = true
|
changeText.TextScaled = true
|
||||||
changeText.Font = Enum.Font.SourceSansBold
|
changeText.Font = Enum.Font.SourceSansBold
|
||||||
changeText.BackgroundTransparency = 1
|
changeText.BackgroundTransparency = 1
|
||||||
changeText.Parent = changeContainer
|
changeText.Parent = changeContainer
|
||||||
|
|
||||||
|
-- 如果是战力值,使用特殊颜色
|
||||||
|
if change.isCombatValue then
|
||||||
|
changeText.TextColor3 = Color3.fromRGB(255, 215, 0) -- 金色
|
||||||
|
changeText.Font = Enum.Font.SourceSansBold
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 创建向上移动动画
|
-- 创建向上移动动画
|
||||||
@ -395,3 +615,4 @@ function RuneStateWindow:Destroy()
|
|||||||
end
|
end
|
||||||
|
|
||||||
return RuneStateWindow
|
return RuneStateWindow
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user