Minecraft计时器脚本新增计时值存本地文件功能后失效,求排查解决
Minecraft计时器脚本故障排查与修复
故障原因
新增代码存在多处语法、逻辑错误,同时原有代码也存在一处隐藏的时间计算错误,具体问题如下:
- 语法错误:
io.open参数写法错误,local关键字不能放在函数参数内,字符串拼接缺少Lua的拼接运算符..,且没有将io.open的返回值赋值给file变量,直接调用file相关方法会报空值错误 - 变量错误:写入文件用的
time变量不存在,原有计时器的当前计时值为os.time() - startTime - 逻辑错误:读文件没有判断文件是否存在,首次进入没有存档文件的新世界时会直接报错
- 执行位置错误:新增代码如果直接放在
update函数中,会导致state为0时反复读文件、state为1时每秒频繁写入文件,既浪费性能也容易触发文件IO冲突 - 原有代码隐藏错误:
timeText函数中计算小时的逻辑写错,每次循环错误减去86400(一天的秒数)而非3600(一小时的秒数),会导致小时计算完全错误
修复方案
- 先修复原有
timeText函数的小时计算逻辑 - 将文件读写逻辑迁移到状态切换的触发位置(按下按键切换状态时仅执行一次)
- 修正文件读写的语法,增加文件存在性判断
- 读取到存档计时值后,正确赋值给
startTime变量恢复计时
修复后完整代码
name = "Timer" description = "Just a normal Timer." positionX = 0 positionY = 0 sizeX = 24 sizeY = 10 scale = 1 START_STOP_KEY = 0x55 --or 'U' RESET_KEY = 0x4A --or 'J' --[[ if you wish to change the key you can take the key code from virtual key code table ]] -------------script-code------------- previoustime = 0 state = 0 startTime = 0 stopTime = 0 ImportedLib = importLib("readfile.lua") -- 封装存档读取函数 function loadTimer(worldName) local file = io.open(worldName..".txt", "r") if not file then return 0 end local savedTime = tonumber(file:read()) file:close() return savedTime or 0 end -- 封装存档写入函数 function saveTimer(worldName, time) local file = io.open(worldName..".txt", "w") if not file then return end file:write(tostring(time)) file:close() end function keyboard(key, isDown) if (isDown == true) then if (key == RESET_KEY) then -- 重置时删除当前世界的存档 local worldName = server.worldName() os.remove(worldName..".txt") state = 0 elseif (key == START_STOP_KEY) then if (state == 0) then state = 1 -- 开始计时前读取存档 local worldName = server.worldName() local savedTime = loadTimer(worldName) startTime = os.time() - savedTime elseif (state == 1) then state = 2 stopTime = os.time() -- 暂停时写入存档 local worldName = server.worldName() saveTimer(worldName, stopTime - startTime) elseif (state == 2) then state = 1 startTime = startTime + os.time() - stopTime end end end end TimerText = "00:00" TextColor = {r = 30, g = 255, b = 30, a = 255} function doubleDigit(number) if (number < 10) then return "0" .. math.floor(number) else return math.floor(number) end end function timeText(time) local result = "" local days = 0 while (time > 86399) do days = days + 1 time = time - 86400 end local hours = 0 -- 修复此处的减法错误,原代码错误减了86400 while (time > 3599) do hours = hours + 1 time = time - 3600 end local minutes = 0 while (time > 59) do minutes = minutes + 1 time = time - 60 end if (days == 0) then if (hours == 0) then return doubleDigit(minutes) .. ":" .. doubleDigit(time) else return math.floor(hours) .. " : " .. doubleDigit(minutes) .. ":" .. doubleDigit(time) end else return math.floor(days) .. " : " .. doubleDigit(hours) .. " : " .. doubleDigit(minutes) .. ":" .. doubleDigit(time) end end function update() if (state == 0) then TextColor = {r = 255, g = 0, b = 0, a = 255} TimerText = "00:00" elseif (state == 1) then TimerText = timeText(os.time() - startTime) TextColor = {r = 0, g = 255, b = 255, a = 255} elseif (state == 2) then TimerText = timeText(stopTime - startTime) TextColor = {r = 255, g = 255, b = 0, a = 255} end end function render() local font = gui.font() local tw = font.width(TimerText) gfx.color(0, 0, 0, 0) gfx.rect(0, 0, tw + 4, 10) gfx.color(TextColor.r, TextColor.g, TextColor.b, TextColor.a) gfx.text(2, 1, TimerText) end
功能说明
- 切换到新世界首次按下U键开始计时时,自动读取对应世界的存档计时值,没有存档则从零开始
- 按下U键暂停计时时,自动将当前计时值保存到对应世界的txt文件中
- 按下J键重置计时时,自动删除当前世界的计时存档
- 修复了原有代码小时计算错误的问题
内容的提问来源于stack exchange,提问作者SebyGHG
相关产品推荐
相关产品推荐

