почему не работает?

$Mr.R1ch$

Активный
Автор темы
258
37
Версия MoonLoader
Другое
приветствую, недавно из своих старых наработок воссоздал таймер на мимгуи с фиксами, но проблема в том, что таймер не работает в фоновом режиме, когда закрыто окно с таймером, и это ломает всю логику работы (он работает только с включенным окном). Очень долго копался в коде и ничего не смог исправить, что я сделал не так?

Lua:
local function formatTime(remaining)
        local hours = math.floor(remaining / 3600) % 24
        local minutes = math.floor(remaining / 60) % 60
        local seconds = remaining % 60
        return hours, minutes, seconds
     end

local timer_remaining = 0  -- Время, оставшееся на таймере в секундах
  local update_interval = 1 / 60 --  Интервал обновления таймера в секундах
    
  imgui.OnFrame(function() return timer_window[0] and not isGamePaused() end, function(timer)
     imgui.SetNextWindowPos(imgui.ImVec2(sizeX / 2, sizeY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
     imgui.Begin(u8'Таймер', timer_window, imgui.WindowFlags.AlwaysAutoResize)
    
     imgui.Text(u8'Секунды:')
     if not timer_active then
        imgui.SetCursorPos(imgui.ImVec2(300, 60))
        imgui.Text(u8'Таймер ещё не запущен.')
     end
     imgui.PushItemWidth(200)
     imgui.SliderInt('##second', seconds_timer, 0, 59) imgui.SameLine(300)
     imgui.PopItemWidth()
     imgui.Spacing()
    
     imgui.Text(u8'Минуты:')
    
     imgui.PushItemWidth(200)
     imgui.SliderInt('##minut', minutes_timer, 0, 59)
     imgui.PopItemWidth()
     imgui.Spacing()
    
     imgui.Text(u8'Часы')
    
     imgui.PushItemWidth(200)
     imgui.SliderInt("##hour", hours_timer, 0, 23)
     imgui.PopItemWidth()
    
     imgui.NewLine()
     imgui.Spacing()
    
     if not timer_active then
        timer_remaining = seconds_timer[0] + (minutes_timer[0] * 60) + (hours_timer[0] * 3600)
        
        if imgui.Button(u8'Запустить таймер', imgui.ImVec2(600, 40)) then
           timer_active = not (seconds_timer[0] == 0 and minutes_timer[0] == 0 and hours_timer[0] == 0)
        end
   else
      if timer_remaining > 0 then
         timer_remaining = timer_remaining - update_interval -- Уменьшаем оставшееся время
         local hours, minutes, seconds = formatTime(timer_remaining)
        
         imgui.SetCursorPos(imgui.ImVec2(300, 60))
         imgui.Text(u8'Осталось времени:')
         imgui.SetCursorPos(imgui.ImVec2(300, 85))
        
         if timer_remaining < 30 then
            imgui.TextColoredRGB(string.format('{FF0000}%0d:%0d:%02d', hours, minutes, seconds))
        else
           imgui.Text(string.format('%0d:%0d:%02d', hours, minutes, seconds))
         end
    else
       sampAddChatMessage(tag.. ' Таймер остановлен.', -1)
       timer_active = false -- Останавливаем таймер, если время закончилось
    end
    
     if timer_active then
        imgui.SetCursorPosY(330)
        if imgui.Button(u8'Остановить таймер', imgui.ImVec2(600, 40)) then
           timer_active = false
        end
     end
   end

  imgui.End()
  end)
 
  • Клоун
Реакции: qdIbp и Corenale

Кот в пиджаке

Участник
61
16
Таймер в твоём коде обновляется только через imgui.OnFrame, которая работает, пока открыто окно. Если окно закрывается, обновление останавливается, и таймер зависает. Вот в этом и проблема.

Попробуй вот это:
Lua:
local function formatTime(remaining)
    local hours = math.floor(remaining / 3600) % 24
    local minutes = math.floor(remaining / 60) % 60
    local seconds = remaining % 60
    return hours, minutes, seconds
end

local timer_remaining = 0  -- Время, оставшееся на таймере в секундах
local update_interval = 1 / 60 -- Интервал обновления таймера в секундах
local last_update_time = os.clock()

-- Поток для обновления таймера
lua_thread.create(function()
    while true do
        wait(0)
        if timer_active and timer_remaining > 0 then
            local current_time = os.clock()
            local delta_time = current_time - last_update_time
            timer_remaining = math.max(0, timer_remaining - delta_time)
            last_update_time = current_time
            if timer_remaining == 0 then
                sampAddChatMessage(tag .. ' Таймер завершён.', -1)
                timer_active = false
            end
        end
    end
end)

imgui.OnFrame(function() return timer_window[0] and not isGamePaused() end, function(timer)
    imgui.SetNextWindowPos(imgui.ImVec2(sizeX / 2, sizeY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin(u8'Таймер', timer_window, imgui.WindowFlags.AlwaysAutoResize)

    imgui.Text(u8'Секунды:')
    if not timer_active then
        imgui.SetCursorPos(imgui.ImVec2(300, 60))
        imgui.Text(u8'Таймер ещё не запущен.')
    end
    imgui.PushItemWidth(200)
    imgui.SliderInt('##second', seconds_timer, 0, 59) imgui.SameLine(300)
    imgui.PopItemWidth()
    imgui.Spacing()

    imgui.Text(u8'Минуты:')

    imgui.PushItemWidth(200)
    imgui.SliderInt('##minut', minutes_timer, 0, 59)
    imgui.PopItemWidth()
    imgui.Spacing()

    imgui.Text(u8'Часы')

    imgui.PushItemWidth(200)
    imgui.SliderInt("##hour", hours_timer, 0, 23)
    imgui.PopItemWidth()

    imgui.NewLine()
    imgui.Spacing()

    if not timer_active then
        timer_remaining = seconds_timer[0] + (minutes_timer[0] * 60) + (hours_timer[0] * 3600)

        if imgui.Button(u8'Запустить таймер', imgui.ImVec2(600, 40)) then
            timer_active = not (seconds_timer[0] == 0 and minutes_timer[0] == 0 and hours_timer[0] == 0)
            last_update_time = os.clock()
        end
    else
        if timer_remaining > 0 then
            local hours, minutes, seconds = formatTime(timer_remaining)

            imgui.SetCursorPos(imgui.ImVec2(300, 60))
            imgui.Text(u8'Осталось времени:')
            imgui.SetCursorPos(imgui.ImVec2(300, 85))

            if timer_remaining < 30 then
                imgui.TextColoredRGB(string.format('{FF0000}%0d:%0d:%02d', hours, minutes, seconds))
            else
                imgui.Text(string.format('%0d:%0d:%02d', hours, minutes, seconds))
            end
        end

        if timer_active then
            imgui.SetCursorPosY(330)
            if imgui.Button(u8'Остановить таймер', imgui.ImVec2(600, 40)) then
                timer_active = false
            end
        end
    end

    imgui.End()
end)
 
  • Клоун
Реакции: Corenale

$Mr.R1ch$

Активный
Автор темы
258
37
Таймер в твоём коде обновляется только через imgui.OnFrame, которая работает, пока открыто окно. Если окно закрывается, обновление останавливается, и таймер зависает. Вот в этом и проблема.

Попробуй вот это:
Lua:
local function formatTime(remaining)
    local hours = math.floor(remaining / 3600) % 24
    local minutes = math.floor(remaining / 60) % 60
    local seconds = remaining % 60
    return hours, minutes, seconds
end

local timer_remaining = 0  -- Время, оставшееся на таймере в секундах
local update_interval = 1 / 60 -- Интервал обновления таймера в секундах
local last_update_time = os.clock()

-- Поток для обновления таймера
lua_thread.create(function()
    while true do
        wait(0)
        if timer_active and timer_remaining > 0 then
            local current_time = os.clock()
            local delta_time = current_time - last_update_time
            timer_remaining = math.max(0, timer_remaining - delta_time)
            last_update_time = current_time
            if timer_remaining == 0 then
                sampAddChatMessage(tag .. ' Таймер завершён.', -1)
                timer_active = false
            end
        end
    end
end)

imgui.OnFrame(function() return timer_window[0] and not isGamePaused() end, function(timer)
    imgui.SetNextWindowPos(imgui.ImVec2(sizeX / 2, sizeY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin(u8'Таймер', timer_window, imgui.WindowFlags.AlwaysAutoResize)

    imgui.Text(u8'Секунды:')
    if not timer_active then
        imgui.SetCursorPos(imgui.ImVec2(300, 60))
        imgui.Text(u8'Таймер ещё не запущен.')
    end
    imgui.PushItemWidth(200)
    imgui.SliderInt('##second', seconds_timer, 0, 59) imgui.SameLine(300)
    imgui.PopItemWidth()
    imgui.Spacing()

    imgui.Text(u8'Минуты:')

    imgui.PushItemWidth(200)
    imgui.SliderInt('##minut', minutes_timer, 0, 59)
    imgui.PopItemWidth()
    imgui.Spacing()

    imgui.Text(u8'Часы')

    imgui.PushItemWidth(200)
    imgui.SliderInt("##hour", hours_timer, 0, 23)
    imgui.PopItemWidth()

    imgui.NewLine()
    imgui.Spacing()

    if not timer_active then
        timer_remaining = seconds_timer[0] + (minutes_timer[0] * 60) + (hours_timer[0] * 3600)

        if imgui.Button(u8'Запустить таймер', imgui.ImVec2(600, 40)) then
            timer_active = not (seconds_timer[0] == 0 and minutes_timer[0] == 0 and hours_timer[0] == 0)
            last_update_time = os.clock()
        end
    else
        if timer_remaining > 0 then
            local hours, minutes, seconds = formatTime(timer_remaining)

            imgui.SetCursorPos(imgui.ImVec2(300, 60))
            imgui.Text(u8'Осталось времени:')
            imgui.SetCursorPos(imgui.ImVec2(300, 85))

            if timer_remaining < 30 then
                imgui.TextColoredRGB(string.format('{FF0000}%0d:%0d:%02d', hours, minutes, seconds))
            else
                imgui.Text(string.format('%0d:%0d:%02d', hours, minutes, seconds))
            end
        end

        if timer_active then
            imgui.SetCursorPosY(330)
            if imgui.Button(u8'Остановить таймер', imgui.ImVec2(600, 40)) then
                timer_active = false
            end
        end
    end

    imgui.End()
end)
попробовал сделать как ты сказал, и таймер сразу же останавливается при запуске (даже не зависит на сколько его завести)
 

Кот в пиджаке

Участник
61
16
Таймер в твоём коде обновляется только через imgui.OnFrame, которая работает, пока открыто окно. Если окно закрывается, обновление останавливается, и таймер зависает. Вот в этом и проблема.

Попробуй вот это:
Lua:
local function formatTime(remaining)
    local hours = math.floor(remaining / 3600) % 24
    local minutes = math.floor(remaining / 60) % 60
    local seconds = remaining % 60
    return hours, minutes, seconds
end

local timer_remaining = 0  -- Время, оставшееся на таймере в секундах
local update_interval = 1 / 60 -- Интервал обновления таймера в секундах
local last_update_time = os.clock()

-- Поток для обновления таймера
lua_thread.create(function()
    while true do
        wait(0)
        if timer_active and timer_remaining > 0 then
            local current_time = os.clock()
            local delta_time = current_time - last_update_time
            timer_remaining = math.max(0, timer_remaining - delta_time)
            last_update_time = current_time
            if timer_remaining == 0 then
                sampAddChatMessage(tag .. ' Таймер завершён.', -1)
                timer_active = false
            end
        end
    end
end)

imgui.OnFrame(function() return timer_window[0] and not isGamePaused() end, function(timer)
    imgui.SetNextWindowPos(imgui.ImVec2(sizeX / 2, sizeY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin(u8'Таймер', timer_window, imgui.WindowFlags.AlwaysAutoResize)

    imgui.Text(u8'Секунды:')
    if not timer_active then
        imgui.SetCursorPos(imgui.ImVec2(300, 60))
        imgui.Text(u8'Таймер ещё не запущен.')
    end
    imgui.PushItemWidth(200)
    imgui.SliderInt('##second', seconds_timer, 0, 59) imgui.SameLine(300)
    imgui.PopItemWidth()
    imgui.Spacing()

    imgui.Text(u8'Минуты:')

    imgui.PushItemWidth(200)
    imgui.SliderInt('##minut', minutes_timer, 0, 59)
    imgui.PopItemWidth()
    imgui.Spacing()

    imgui.Text(u8'Часы')

    imgui.PushItemWidth(200)
    imgui.SliderInt("##hour", hours_timer, 0, 23)
    imgui.PopItemWidth()

    imgui.NewLine()
    imgui.Spacing()

    if not timer_active then
        timer_remaining = seconds_timer[0] + (minutes_timer[0] * 60) + (hours_timer[0] * 3600)

        if imgui.Button(u8'Запустить таймер', imgui.ImVec2(600, 40)) then
            timer_active = not (seconds_timer[0] == 0 and minutes_timer[0] == 0 and hours_timer[0] == 0)
            last_update_time = os.clock()
        end
    else
        if timer_remaining > 0 then
            local hours, minutes, seconds = formatTime(timer_remaining)

            imgui.SetCursorPos(imgui.ImVec2(300, 60))
            imgui.Text(u8'Осталось времени:')
            imgui.SetCursorPos(imgui.ImVec2(300, 85))

            if timer_remaining < 30 then
                imgui.TextColoredRGB(string.format('{FF0000}%0d:%0d:%02d', hours, minutes, seconds))
            else
                imgui.Text(string.format('%0d:%0d:%02d', hours, minutes, seconds))
            end
        end

        if timer_active then
            imgui.SetCursorPosY(330)
            if imgui.Button(u8'Остановить таймер', imgui.ImVec2(600, 40)) then
                timer_active = false
            end
        end
    end

    imgui.End()
end)
@Corenale отвечай за клоуна, вместо смайликов помоги автору если такой умный
 

chromiusj

R&B-baby-queen
Модератор
5,584
3,887
@Corenale отвечай за клоуна, вместо смайликов помоги автору если такой умный
с чего он должен отвечать за что-то
с смайликов ущемляться много ума не надо, наверное
да и все равно у тебя твой поток в итоге к окну привязывается, в чем прикол то
 

chromiusj

R&B-baby-queen
Модератор
5,584
3,887
попробовал сделать как ты сказал, и таймер сразу же останавливается при запуске (даже не зависит на сколько его завести)
???
Lua:
local function formatTime(remaining)
    return math.floor(remaining / 3600) % 24, math.floor(remaining / 60) % 60, remaining % 60
end

local imgui = require 'mimgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local renderWindow = imgui.new.bool(true)
local timer_active = false
local timer_remaining = 0
local seconds_timer = imgui.new.int(0)
local minutes_timer = imgui.new.int(0)
local hours_timer = imgui.new.int(0)

imgui.OnFrame(function() return renderWindow[0] end, function()
    local resX, resY = getScreenResolution()
    imgui.SetNextWindowPos(imgui.ImVec2(resX / 2, resY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(300, 200), imgui.Cond.FirstUseEver)
    if imgui.Begin(u8'Таймер', renderWindow) then
        if not timer_active then
            imgui.SliderInt(u8'Часы', hours_timer, 0, 23)
            imgui.SliderInt(u8'Минуты', minutes_timer, 0, 59)
            imgui.SliderInt(u8'Секунды', seconds_timer, 0, 59)
            if imgui.Button(u8'Старт') then
                timer_remaining = seconds_timer[0] + minutes_timer[0] * 60 + hours_timer[0] * 3600
                timer_active = timer_remaining > 0
            end
        else
            local hours, minutes, seconds = formatTime(timer_remaining)
            imgui.Text(string.format(u8'Осталось: %02d:%02d:%02d', hours, minutes, seconds))
            if imgui.Button(u8'Стоп') then timer_active = false end
        end
        imgui.End()
    end
end)

lua_thread.create(function()
    while true do
        wait(0)
        if timer_active and timer_remaining > 0 then
            local start_time = os.clock()
            while os.clock() - start_time < 1 do wait(0) end
            timer_remaining = timer_remaining - 1
            if timer_remaining <= 0 then
                timer_active = false
                sampAddChatMessage('Таймер завершён', -1)
            end
        end
    end
end)

function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('таймер', function() renderWindow[0] = not renderWindow[0] end)
    while true do wait(0) end
end
 
Последнее редактирование:

$Mr.R1ch$

Активный
Автор темы
258
37
???
Lua:
local function formatTime(remaining)
    return math.floor(remaining / 3600) % 24, math.floor(remaining / 60) % 60, remaining % 60
end

local imgui = require 'mimgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local renderWindow = imgui.new.bool(true)
local timer_active = false
local timer_remaining = 0
local seconds_timer = imgui.new.int(0)
local minutes_timer = imgui.new.int(0)
local hours_timer = imgui.new.int(0)

imgui.OnFrame(function() return renderWindow[0] end, function()
    local resX, resY = getScreenResolution()
    imgui.SetNextWindowPos(imgui.ImVec2(resX / 2, resY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.SetNextWindowSize(imgui.ImVec2(300, 200), imgui.Cond.FirstUseEver)
    if imgui.Begin(u8'Таймер', renderWindow) then
        if not timer_active then
            imgui.SliderInt(u8'Часы', hours_timer, 0, 23)
            imgui.SliderInt(u8'Минуты', minutes_timer, 0, 59)
            imgui.SliderInt(u8'Секунды', seconds_timer, 0, 59)
            if imgui.Button(u8'Старт') then
                timer_remaining = seconds_timer[0] + minutes_timer[0] * 60 + hours_timer[0] * 3600
                timer_active = timer_remaining > 0
            end
        else
            local hours, minutes, seconds = formatTime(timer_remaining)
            imgui.Text(string.format(u8'Осталось: %02d:%02d:%02d', hours, minutes, seconds))
            if imgui.Button(u8'Стоп') then timer_active = false end
        end
        imgui.End()
    end
end)

lua_thread.create(function()
    while true do
        wait(0)
        if timer_active and timer_remaining > 0 then
            local start_time = os.clock()
            while os.clock() - start_time < 1 do wait(0) end
            timer_remaining = timer_remaining - 1
            if timer_remaining <= 0 then
                timer_active = false
                sampAddChatMessage('Таймер завершён', -1)
            end
        end
    end
end)

function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('таймер', function() renderWindow[0] = not renderWindow[0] end)
    while true do wait(0) end
end
теперь работает, но считает время слишком быстро, секунды идут в 2 раза быстрее