1传送门开启 4传送门关闭
6传送门开启 9传送门关闭
10传送门开启 13传送门关闭
14传送门开启 17传送门关闭
19传送门开启 22传送门关闭
24传送门开启 27传送门关闭 帮我计算一下一个是1800秒,上方为1分钟开启,帮我做个判断到下一个阶段还有多少秒
🤖 回答引擎: 后端Lua |
🕒 时间: 2026-03-27 23:51:09 |
👁️ 阅读: 14
道友你好,我是Lua后端老师!
小仙,你这个问题是想做一个循环的计时器,根据当前时间判断下一个“传送门开启”或“关闭”的阶段,并计算剩余秒数,对吧?你给出的时间点(1,4,6,9,10,13...)是以分钟为单位,总周期是1800秒(即30分钟)。
我们先来理清逻辑。一个完整的循环是1800秒,你给出的时间点是这个循环内的关键节点(单位:分钟)。我们需要:
1. 获取当前时间在这个1800秒周期内的位置(即 `当前时间戳 % 1800`)。
2. 根据这个位置,找到下一个即将到来的时间点(无论是“开启”还是“关闭”)。
3. 计算当前时间到下一个时间点的秒数差。
下面是一个封装好的函数,你可以直接使用。我会在QM(QuestMenu)或合适的触发点(比如`login`登录触发或`ontimer`)里调用它。
```lua
-- 判断并计算到下一个传送门阶段的剩余秒数
-- @param play 玩家对象
function CheckPortalNextTime(play)
-- 总周期秒数
local TOTAL_CYCLE_SECONDS = 1800
-- 定义阶段点(单位:分钟),按顺序排列
local phasePoints = {
{minute = 1, action = "开启"},
{minute = 4, action = "关闭"},
{minute = 6, action = "开启"},
{minute = 9, action = "关闭"},
{minute = 10, action = "开启"},
{minute = 13, action = "关闭"},
{minute = 14, action = "开启"},
{minute = 17, action = "关闭"},
{minute = 19, action = "开启"},
{minute = 22, action = "关闭"},
{minute = 24, action = "开启"},
{minute = 27, action = "关闭"}
}
-- 获取当前时间戳(秒),并计算在当前周期内的位置
local currentTime = os.time()
local currentPosInCycle = currentTime % TOTAL_CYCLE_SECONDS -- 范围 0 ~ 1799 秒
-- 将阶段点从分钟转换为秒
for _, point in ipairs(phasePoints) do
point.second = point.minute * 60
end
-- 寻找下一个阶段点
local nextPoint = nil
for _, point in ipairs(phasePoints) do
if point.second > currentPosInCycle then
nextPoint = point
break
end
end
-- 如果当前周期内没找到,则取下一个周期的第一个点
if nextPoint == nil then
nextPoint = phasePoints[1]
nextPoint.second = nextPoint.second + TOTAL_CYCLE_SECONDS -- 加上一个周期
end
-- 计算剩余秒数
local secondsRemaining = nextPoint.second - currentPosInCycle
-- 输出信息给玩家(使用引擎专用打印,避免刷屏可改为sendmsg)
local msg = string.format("当前周期位置:%d秒。下一个阶段:%d分钟时传送门%s。剩余时间:%d秒。",
currentPosInCycle, nextPoint.minute, nextPoint.action, secondsRemaining)
release_print(msg) -- 在服务端控制台打印
-- 如果想发给玩家看,可以用:sendmsg(play, msg, 1) -- 1代表白色普通聊天信息
return secondsRemaining, nextPoint.minute, nextPoint.action
end
-- 示例:在玩家登录时触发,并每隔10秒检查一次(需要配合定时器)
-- 在 QF 的 [@login] 触发段里调用
function OnPlayerLogin(play)
-- 首次检查
CheckPortalNextTime(play)
-- 设置一个每10秒执行一次的定时器,持续检查
setontimer(play, "CheckPortalTimer", 10 * 1000) -- 时间单位是毫秒
end
-- 在 QF 的 [@ontimer(CheckPortalTimer)] 触发段里调用
function OnCheckPortalTimer(play)
CheckPortalNextTime(play)
-- 重新设置定时器,以实现循环
setontimer(play, "CheckPortalTimer", 10 * 1000)
end
```
**使用说明:**
1. 将 `CheckPortalNextTime` 函数放在你的Lua脚本文件里(比如 `game_data.lua` 或专门的功能文件)。
2. 在 `QF` 脚本的 `[@login]` 段里,调用 `OnPlayerLogin(actor)`。注意,`actor` 是QF传入的玩家对象参数名。
3. 在 `QF` 脚本的 `[@ontimer(CheckPortalTimer)]` 段里,调用 `OnCheckPortalTimer(actor)`。
4. 函数会每隔10秒计算一次,并输出剩余时间。你可以根据需要调整检查频率(修改 `setontimer` 的时间参数)和信息的发送方式(例如用 `sendmsg` 直接发给玩家界面)。
**核心逻辑解释:**
* `os.time() % 1800` 是关键,它把无限增长的时间戳映射到了一个30分钟的循环圈里。
* 函数遍历你定义的所有时间点,找到第一个比当前圈内时间大的点,就是“下一个”阶段。
* 如果当前时间已经超过圈内最后一个点(27分钟),那么“下一个”点就是下一个周期的第1分钟的点。
这样,无论何时调用,你都能得到准确的剩余秒数。不懂的地方随时问我,或者请教我师傅浮生梦尊者!
← 返回问答库