Анимация

l1ght777

Активный
Автор темы
345
53
Версия MoonLoader
Другое
Ку, недавно начал создавать анимацию с плавным переходом значений в ImVec2, но для корректной работы кода мне нужно выполнить проверку - если ImVec2(переменная) равна нулю (ImVec2(0, 0), то что то будет, но я не понимаю, как это сделать т.к выводятся другие данные, из за чего не работает проверка

Lua:
anim_value = imgui. ImVec2(0, 0)

function bringVec2To(from, to, start_time, duration)
   local timer = os.clock() - start_time
   if timer >= 0.00 and timer <= duration then
      local count = timer / (duration / 100)
      return imgui.ImVec2(
         from.x + (count * (to.x - from.x) / 100),
         from.y + (count * (to.y - from.y) / 100)
         ), true
   end
   return (timer > duration) and to or from, false
end


function anim_start()
   -- Проверка, что переменная равна стандартному значению
   start_time = os.clock()
   lua_thread.create(function()
      
      while true do wait(0)
         local a = bringVec2To(imgui.ImVec2(0, 0), imgui.ImVec2(400, 0), start_time, 1)
         anim_value = a
      end
   end)
end

Я думал мб как то конвертировать, но значения задаются по x y
 
Решение
Lua:
local imgui = require 'mimgui'

local renderWindow = imgui.new.bool(true)
local anim_value = imgui.ImVec2(0, 0)

local function is_vec2_zero(vec)
   return vec.x == 0.0 and vec.y == 0.0
end

function bringVec2To(from, to, start_time, duration)
   local timer = os.clock() - start_time
   if timer >= 0.00 and timer <= duration then
      local count = timer / (duration / 100)
      return imgui.ImVec2(
         from.x + (count * (to.x - from.x) / 100),
         from.y + (count * (to.y - from.y) / 100)
      ), true
   end
   return (timer > duration) and to or from, false
end

imgui.OnFrame(function() return renderWindow end, function(player)
   imgui.SetNextWindowPos(imgui.ImVec2(anim_value.x, anim_value.y), imgui.Cond.Always)...

e11evated

Участник
63
22
Нужно сравнивать отдельные компоненты вектора (x и y).


547e5fb900b2a057.gif


Пример того что выше:

Lua:
local mimgui = require 'mimgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

local window_active = mimgui.new.bool(false)

local function vec2(x, y)
    local v = mimgui.new.ImVec2()
    v[0].x = x
    v[0].y = y
    return v
end

local animation_pos = vec2(0, 0)
local animation_start_time = 0

mimgui.OnFrame(function() return window_active[0] end, function()
    mimgui.SetNextWindowSize(vec2(500, 100)[0], mimgui.Cond.FirstUseEver)

    if mimgui.Begin(u8'Тест Анимации', window_active) then
        mimgui.SetCursorPos(animation_pos[0])

        if mimgui.Button(u8'Поехали!') then
            animation_start_time = os.clock()
            lua_thread.create(run_animation)
        end

        mimgui.End()
    end
end)

local function interpolate_vec2(from, to, start_time, duration)
    local elapsed = os.clock() - start_time

    if elapsed >= 0 and elapsed <= duration then
        local t = elapsed / duration
        t = t * t * (3 - 2 * t)

        return vec2(
            from[0].x + (to[0].x - from[0].x) * t,
            from[0].y + (to[0].y - from[0].y) * t
        ), true
    end

    local final_pos = (elapsed > duration) and to or from
    return vec2(final_pos[0].x, final_pos[0].y), false
end

function run_animation()
    local is_animating = true

    local start_pos = vec2(20, 50)
    local end_pos = vec2(350, 50)

    while is_animating and window_active[0] do
        wait(0)

        local current_pos, still_active = interpolate_vec2(start_pos, end_pos, animation_start_time, 1.0)

        animation_pos[0].x = current_pos[0].x
        animation_pos[0].y = current_pos[0].y

        is_animating = still_active
    end
end

function main()
    while not isSampLoaded() do
        wait(100)
    end

    sampRegisterChatCommand('animtest', function()
        window_active[0] = not window_active[0]

        if window_active[0] then
            local initial_pos = vec2(20, 50)
            animation_pos[0].x = initial_pos[0].x
            animation_pos[0].y = initial_pos[0].y
        end
    end)

    wait(-1)
end
 
Последнее редактирование:

l1ght777

Активный
Автор темы
345
53
Нужно сравнивать отдельные компоненты вектора (x и y).


547e5fb900b2a057.gif


Пример того что выше:

Lua:
local mimgui = require 'mimgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
local u8 = encoding.UTF8

local window_active = mimgui.new.bool(false)

local function vec2(x, y)
    local v = mimgui.new.ImVec2()
    v[0].x = x
    v[0].y = y
    return v
end

local animation_pos = vec2(0, 0)
local animation_start_time = 0

mimgui.OnFrame(function() return window_active[0] end, function()
    mimgui.SetNextWindowSize(vec2(500, 100)[0], mimgui.Cond.FirstUseEver)

    if mimgui.Begin(u8'Тест Анимации', window_active) then
        mimgui.SetCursorPos(animation_pos[0])

        if mimgui.Button(u8'Поехали!') then
            animation_start_time = os.clock()
            lua_thread.create(run_animation)
        end

        mimgui.End()
    end
end)

local function interpolate_vec2(from, to, start_time, duration)
    local elapsed = os.clock() - start_time

    if elapsed >= 0 and elapsed <= duration then
        local t = elapsed / duration
        t = t * t * (3 - 2 * t)

        return vec2(
            from[0].x + (to[0].x - from[0].x) * t,
            from[0].y + (to[0].y - from[0].y) * t
        ), true
    end

    local final_pos = (elapsed > duration) and to or from
    return vec2(final_pos[0].x, final_pos[0].y), false
end

function run_animation()
    local is_animating = true

    local start_pos = vec2(20, 50)
    local end_pos = vec2(350, 50)

    while is_animating and window_active[0] do
        wait(0)

        local current_pos, still_active = interpolate_vec2(start_pos, end_pos, animation_start_time, 1.0)

        animation_pos[0].x = current_pos[0].x
        animation_pos[0].y = current_pos[0].y

        is_animating = still_active
    end
end

function main()
    while not isSampLoaded() do
        wait(100)
    end

    sampRegisterChatCommand('animtest', function()
        window_active[0] = not window_active[0]

        if window_active[0] then
            local initial_pos = vec2(20, 50)
            animation_pos[0].x = initial_pos[0].x
            animation_pos[0].y = initial_pos[0].y
        end
    end)

    wait(-1)
end
Немного не так, лучше покажу пример кода. В коде есть проверка if anim_value == 0.00 then, она нужна, чтобы альфа канал окон не мерцал в цикле, и точно такую же проверку надо сделать в bringVec2to, чтобы анимация не запускалась циклично, а лишь тогда, когда переменная будет равна, например, нулю, только в данной функции надо проверять vec2 данные, а не флот

Lua:
anim_value = 0.00

function anim_start()
  if anim_value == 0.00 then -- та самая проверка
      start_anim = os.clock()
      lua_thread.create(function()
      
         while true do wait(0)
            local a = bringFloatTo(0.00, 0.7, start_anim, 3)
            anim_value = anim_value > 0.00 and a or 0.7 - a
            if a == 0.7 then break end
         end
      end)
   end
end
 

e11evated

Участник
63
22
Lua:
local imgui = require 'mimgui'

local renderWindow = imgui.new.bool(true)
local anim_value = imgui.ImVec2(0, 0)

local function is_vec2_zero(vec)
   return vec.x == 0.0 and vec.y == 0.0
end

function bringVec2To(from, to, start_time, duration)
   local timer = os.clock() - start_time
   if timer >= 0.00 and timer <= duration then
      local count = timer / (duration / 100)
      return imgui.ImVec2(
         from.x + (count * (to.x - from.x) / 100),
         from.y + (count * (to.y - from.y) / 100)
      ), true
   end
   return (timer > duration) and to or from, false
end

imgui.OnFrame(function() return renderWindow end, function(player)
   imgui.SetNextWindowPos(imgui.ImVec2(anim_value.x, anim_value.y), imgui.Cond.Always)
   imgui.SetNextWindowSize(imgui.ImVec2(200, 100), imgui.Cond.FirstUseEver)
  
   imgui.Begin("Окно анимации", renderWindow)
   imgui.Text(string.format("X: %.1f Y: %.1f", anim_value.x, anim_value.y))
   imgui.End()
end)

function anim_start()
   if is_vec2_zero(anim_value) then
      sampAddChatMessage("{00FF00}[Клондайк] {FFFFFF}Анимация запущена!", -1)
      local start_anim = os.clock()
      
      lua_thread.create(function()
         while true do
            wait(0)
            local res_vec, animating = bringVec2To(imgui.ImVec2(0, 0), imgui.ImVec2(400, 300), start_anim, 2.0)
            anim_value = res_vec
            
            if not animating then
               sampAddChatMessage("{00FF00}[Клондайк] {FFFFFF}Анимация завершена.", -1)
               break
            end
         end
      end)
   else
      sampAddChatMessage("{FF0000}[Ошибка] {FFFFFF}Анимация уже идет или значение не 0,0!", -1)
   end
end

function main()
   while not isSampAvailable() do wait(100) end
  
   sampRegisterChatCommand("testanim", function()
      anim_value.x = 0
      anim_value.y = 0
      anim_start()
   end)

   wait(-1)
end
 
  • Нравится
Реакции: l1ght777 и kyrtion