This commit is contained in:
gechangfu 2025-08-21 11:47:33 +08:00
parent f440012952
commit e13d346923
3 changed files with 232 additions and 81 deletions

View File

@ -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 {}

View File

@ -21,7 +21,7 @@ function AbilityStateWindows:Init(UIManager: table, Data: table?)
["__listAbility"] = 0,
["__listWearAbility"] = 0,
}
self.UIRootName = "ui_w_abilityState"
self.UIRootName = "ui_w_ability_state"
self.UIParentName = UIEnums.UIParent.UIRoot

View File

@ -6,6 +6,7 @@ local UIWindow = require(ReplicatedStorage.Base.UIWindow)
local UIEnums = require(ReplicatedStorage.Base.UIEnums)
local Localization = require(ReplicatedStorage.Tools.Localization)
local Utils = require(ReplicatedStorage.Tools.Utils)
local FormatNumber = require(ReplicatedStorage.Modules.FormatNumber)
--> Json
local JsonAttributes = require(ReplicatedStorage.Json.Attributes)
@ -24,6 +25,8 @@ function RuneStateWindow:Init(UIManager: table, Data: table?)
setmetatable(self, RuneStateWindow)
self.Variables = {
["__listRune"] = 0,
["_tmpCombatValue"] = 0,
["_goCombatValue"] = 0,
}
self.UIRootName = "ui_w_rune_state"
self.UIParentName = UIEnums.UIParent.UIRoot
@ -38,6 +41,175 @@ function RuneStateWindow:Init(UIManager: table, Data: table?)
return self
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()
UIWindow.OnOpenWindow(self)
@ -48,6 +220,11 @@ function RuneStateWindow:OnOpenWindow()
-- 初始化符文列表
self:RefreshRuneList()
-- 更新战力值显示
self:UpdateCombatValueDisplay()
end
function RuneStateWindow:OnCloseWindow()
@ -57,6 +234,11 @@ function RuneStateWindow:OnCloseWindow()
-- 断开符文执行记录事件连接
self:DisconnectRuneExecutionEvent()
-- 隐藏动画战力值组件
if self.Variables["_goCombatValue"] then
self.Variables["_goCombatValue"].Visible = false
end
end
-- 刷新符文列表
@ -144,6 +326,9 @@ function RuneStateWindow:OnRuneExecutionRecord(executionRecords: table)
if not self.isPlayingAnimation then
self:PlayRuneAnimation()
end
-- 更新战力值显示
self:UpdateCombatValueDisplay()
end
-- 播放符文动画
@ -155,6 +340,7 @@ function RuneStateWindow:PlayRuneAnimation()
self.isPlayingAnimation = true
local record = table.remove(self.runeExecutionQueue, 1)
-- 播放小丑牌动画
self:PlayJokerCardAnimation(record)
end
@ -171,8 +357,18 @@ function RuneStateWindow:PlayJokerCardAnimation(record: table)
return
end
-- 计算战力值变化
local beforeCombatValue = self:UpdateCombatValueDisplay(record.attributesBefore)
-- 创建动画效果
self:CreateJokerCardEffect(runeItem, record)
-- 等待动画播放一段时间后计算新的战力值
task.wait(0.3)
local afterCombatValue = self:UpdateCombatValueDisplay(record.attributesAfter)
-- 播放战力值滚动动画
self:PlayCombatValueAnimation(beforeCombatValue, afterCombatValue)
end
-- 查找符文UI元素通过名称和唯一ID
@ -198,15 +394,16 @@ function RuneStateWindow:FindRuneItemByName(runeName: string)
-- 在符文列表中查找对应的符文
local runeList = self.Variables["__listRune"]
if runeList and runeList.Instances then
for _, component in pairs(runeList.Instances) do
if component.Data then
if component.Data.runeName == runeName then
return component
end
end
if not runeList or not runeList.Instances then
return nil
end
for _, component in pairs(runeList.Instances) do
if component.Data and component.Data.runeName == runeName then
return component
end
end
return nil
end
@ -294,6 +491,19 @@ function RuneStateWindow:CreateAttributeChangeDisplay(runeUI: Instance, record:
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
return
@ -306,7 +516,7 @@ end
-- 创建属性变化容器
function RuneStateWindow:CreateAttributeChangeContainer(runeUI: Instance, attributeChanges: table)
-- 计算容器高度
local containerHeight = #attributeChanges * 25 + 10
local containerHeight = #attributeChanges * 30 + 10
-- 创建属性变化显示容器
local changeContainer = Instance.new("Frame")
@ -332,13 +542,23 @@ function RuneStateWindow:CreateAttributeChangeContainer(runeUI: Instance, attrib
for i, change in ipairs(attributeChanges) do
local changeText = Instance.new("TextLabel")
changeText.Size = UDim2.new(1, -10, 0, 20)
changeText.Position = UDim2.new(0, 5, 0, 5 + (i-1) * 25)
changeText.Text = string.format("%s +%d", change.name, change.change)
changeText.Position = UDim2.new(0, 5, 0, 5 + (i-1) * 30)
-- 格式化显示文本
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.TextScaled = true
changeText.Font = Enum.Font.SourceSansBold
changeText.BackgroundTransparency = 1
changeText.Parent = changeContainer
-- 如果是战力值,使用特殊颜色
if change.isCombatValue then
changeText.TextColor3 = Color3.fromRGB(255, 215, 0) -- 金色
changeText.Font = Enum.Font.SourceSansBold
end
end
-- 创建向上移动动画
@ -395,3 +615,4 @@ function RuneStateWindow:Destroy()
end
return RuneStateWindow