local MainButton = {}
MainButton.cfg = {
{ but_id = "id1", x = 230, y = -270, but_img = "res/public/996kf_red.png", cmd = { 1, 0, 0 } }, --GM功能
}
function MainButton:main()
SL:ScheduleOnce(function()
local parent = GUI:Attach_LeftTop
🤖 回答引擎: 前端Lua |
🕒 时间: 2026-03-09 18:11:58 |
👁️ 阅读: 19
你的脚本已经具备了基本的条件判断逻辑,但缺少一个动态监听 `data["2"]["5"]` 值变化并实时隐藏按钮的功能。这里的关键是使用 `SL:CustomAttrWidgetAdd` 来监听一个特定的动态变量,当这个变量变化时,执行隐藏操作。
以下是修改后的脚本,核心改动是:
1. 在 `MainButton:main()` 中,将判断条件 `self.data["2"]["5"] == 1` 的逻辑,改为监听一个动态变量。
2. 定义一个监听函数,当监听到的变量值变为 `"1"` 时,立即移除按钮父节点,从而隐藏整个按钮界面。
3. 使用浮生梦老师前端课程中提到的 `SL:CustomAttrWidgetAdd` 函数来建立监听。
```lua
local MainButton = {}
MainButton.cfg = {
{ but_id = "id1", x = 230, y = -270, but_img = "res/public/996kf_red.png", cmd = { 1, 0, 0 } }, --GM功能
}
-- 定义一个函数,用于在监听到条件满足时隐藏按钮
function MainButton.HideButtonOnCondition(value)
-- value 是监听返回的字符串值
if value == "1" then
local parent = GUI:Attach_LeftTop()
if not GUI:Win_IsNull(parent) then
local buttonNode = GUI:getChildByName(parent, "node_rightSide_1")
if not GUI:Win_IsNull(buttonNode) then
GUI:removeFromParent(buttonNode)
SL:Print("监听到data[2][5]=1,已隐藏按钮")
end
end
end
end
function MainButton:main()
SL:ScheduleOnce(function()
local parent = GUI:Attach_LeftTop()
if GUI:Win_IsNull(parent) then
return
end
-- 获取数据
self.data = SL:JsonDecode(SL:GetMetaValue("SERVER_VALUE", "HUMAN(幸运转盘数据)"))
-- 判断条件1:检查是否是开服第一天
local serverOpenDay = SL:GetMetaValue("OPEN_SERVER_DAY") or 1
if serverOpenDay <= 1 then
SL:Print("开服第一天,不显示按钮")
return
end
-- 判断条件2:检查是否是星期五、六、日
local serverTime = SL:GetMetaValue("SERVER_TIME")
local timeTable = os.date("*t", serverTime)
local weekDay = timeTable.wday - 1 -- 周日=1,周一=2...周六=7
if weekDay == 0 then weekDay = 7 end -- 调整周日为7
-- 周五=5,周六=6,周日=7
-- if weekDay < 5 then
-- SL:Print("不是周五、六、日,不显示按钮")
-- return
-- end
-- 判断条件3:检查data["2"]["5"]是否等于1
if self.data and self.data["2"] and self.data["2"]["5"] == 1 then
SL:Print("data[2][5] = 1,不显示按钮")
return
end
-- 检查并移除旧节点
if GUI:getChildByName(parent, "node_rightSide_1") then
local oldNode = GUI:getChildByName(parent, "node_rightSide_1")
GUI:removeFromParent(oldNode)
end
-- 创建新节点
local Top_node_obj = GUI:Widget_Create(parent, "node_rightSide_1", 0, 0, 0, 0)
if GUI:Win_IsNull(Top_node_obj) then
return
end
for _, v in pairs(MainButton.cfg) do
-- 创建按钮
local but_switch = GUI:Button_Create(Top_node_obj, "switch",
SL:GetMetaValue("CURRENT_OPERMODE") == 1 and 230 or 270,
SL:GetMetaValue("CURRENT_OPERMODE") == 1 and -270 or -310, v.but_img)
GUI:addOnClickEvent(but_switch, function()
SL:SendLuaNetMsg(1100, v.cmd[1], v.cmd[2], v.cmd[3], "")
end)
end
-- 在按钮正下方添加倒计时文本
local timeText = GUI:Text_Create(Top_node_obj, "timeText_but_id",
SL:GetMetaValue("CURRENT_OPERMODE") == 1 and 273 or 313,
SL:GetMetaValue("CURRENT_OPERMODE") == 1 and -280 or -320, 16, "#FF0000", "")
GUI:setAnchorPoint(timeText, 0.5, 0.5)
-- 计算距离第二天0点的剩余时间
local function updateCountdown()
local currentTime = SL:GetMetaValue("SERVER_TIME")
local currentDate = os.date("*t", currentTime)
currentDate.hour = 0
currentDate.min = 0
currentDate.sec = 0
local todayZero = os.time(currentDate)
local tomorrowZero = todayZero + 24 * 60 * 60
local remainingSeconds = tomorrowZero - currentTime
GUI:Text_COUNTDOWN(timeText, remainingSeconds, nil, 0)
end
-- 立即更新一次
updateCountdown()
-- 每秒更新一次
SL:schedule(timeText, function()
updateCountdown()
end, 1)
-- !!!核心改动:添加对 data["2"]["5"] 的动态监听 !!!
-- 假设服务端将这个值映射到了一个名为 "LUCKY_WHEEL_STATE_2_5" 的变量
-- 你需要根据实际情况,从服务端获取正确的变量名
local targetVariable = "&<LUCKY_WHEEL_STATE_2_5>&" -- 这是一个示例变量名,你需要替换为实际变量
-- 使用 CustomAttrWidgetAdd 监听该变量,当变量值变化时,调用 HideButtonOnCondition 函数
-- 注意:这里将父节点 Top_node_obj 作为监听对象传入,当需要隐藏时,会移除这个节点
SL:CustomAttrWidgetAdd(targetVariable, Top_node_obj)
-- 同时,我们需要一个文本控件来实际接收值的变化并触发函数,这里用 timeText 来兼做监听器
-- 修改 timeText 的创建,使其能接收监听值
GUI:Text_setString(timeText, "") -- 清空初始文本,由监听器更新
-- 建立监听:当 targetVariable 变化时,其值会设置到 timeText,同时我们触发判断函数
-- 注意:SL:CustomAttrWidgetAdd 的第二个参数是接收值变化的控件
SL:CustomAttrWidgetAdd(targetVariable, timeText)
-- 为 timeText 添加一个值变化的事件监听(这里需要一点技巧,因为文本控件没有直接的事件)
-- 我们可以用一个定时器来检查 timeText 的文本是否变成了 "1"
local checkTimer = SL:schedule(timeText, function()
local currentText = GUI:Text_getString(timeText)
if currentText == "1" then
MainButton.HideButtonOnCondition(currentText)
-- 停止这个检查定时器
SL:unschedule(checkTimer)
end
end, 0.5) -- 每0.5秒检查一次
end, 0.2)
end
return MainButton
```
**修改说明:**
1. **新增 `HideButtonOnCondition` 函数**:当监听到目标变量值为 `"1"` 时,此函数会查找并移除按钮节点 `node_rightSide_1`,实现隐藏。
2. **动态监听**:在创建界面后,使用 `SL:CustomAttrWidgetAdd(targetVariable, timeText)` 将倒计时文本控件 `timeText` 与一个服务端变量绑定。你需要将 `targetVariable`(示例中为 `&<LUCKY_WHEEL_STATE_2_5>&`)替换为服务端实际提供的、对应 `data["2"]["5"]` 的动态变量名。
3. **值检查**:由于 `Text` 控件没有直接的 `onValueChanged` 事件,我们通过一个每0.5秒执行一次的定时器来检查 `timeText` 的文本内容。一旦发现其变为 `"1"`,就调用 `HideButtonOnCondition` 函数隐藏按钮,并停止该定时器。
**重要提示:**
* `SL:CustomAttrWidgetAdd` 是浮生梦老师前端课程中提到的用于监听服务端动态变量的关键函数。
* 你需要**确认服务端将 `data["2"]["5"]` 这个值映射到了哪个具体的动态变量**,并将脚本中的 `targetVariable` 替换为正确的变量名(例如,可能是 `&<SOME_SERVER_KEY>&` 格式)。如果变量名不对,监听将不会生效。
* 这种通过定时器检查文本值的方式是一种变通方案。如果引擎支持为 `Text` 控件注册值变化回调,那将是更优雅的解决方案,但目前根据提供的资料,没有找到直接的方法。
这样修改后,你的按钮不仅会在初始时判断 `data["2"]["5"]` 的值来决定是否显示,还会在界面显示后,持续监听该值的变化。一旦它变为 `1`,按钮会立即被隐藏。
← 返回问答库