Изучаем Dear ImGUI в Defold. Часть 3. Кнопки и same_line()

В этом пособие я использовал версию:
https://github.com/britzl/extension-imgui/archive/refs/tags/2.6.1.zip

Всем привет!

Это тема является продолжением двух других тем:

Изучаем Dear ImGUI в Defold. Часть 1. Создание окна и таблицы с полями
Изучаем Dear ImGUI в Defold. Часть 2. Радиокнопки

В этом пособие вы узнаете о том, как создавать кнопки в Dear ImGUI на Defold, а также познакомитесь с imgui.same_line().

Вставьте в main.script такой код:

local answer = nil  -- может быть "Yes" или "No"

function init(self)
    msg.post(".", "acquire_input_focus")
    imgui.set_ini_filename()  -- отключаем запись настроек
end

function update(self, dt)
    -- Задаём фиксированную ширину окна при первом открытии
    imgui.set_next_window_size(200, 0, imgui.COND_FIRST_USE_EVER)
    imgui.begin_window("Yes or No?", false, imgui.WINDOWFLAGS_ALWAYS_AUTO_RESIZE)

    -- Кнопка "Yes"
    if imgui.button("Yes") then
        answer = "Yes"
    end

    imgui.same_line()  -- разместить следующую кнопку в той же строке

    -- Кнопка "No"
    if imgui.button("No") then
        answer = "No"
    end

    -- Если есть выбор, показываем результат
    if answer then
        imgui.separator()
        imgui.text("Your answer: " .. answer)
    end
    imgui.end_window()
end


Справочник


imgui.button(label, width, height)


Кнопка imgui.button рисует кнопку с заданной надписью и возвращает true ровно в тот кадр, когда по ней кликнули или активировали с клавиатуры. Это и отрисовка, и обработка клика одновременно; кнопку нужно вызывать каждый кадр внутри окна ImGui.

if imgui.button("Yes") then
    answer = "Yes"
end

-- Кнопка фиксированного размера
if imgui.button("No", 120, 28) then
    answewr = "No"
end

Важно понимать: эта функция возвращает true ТОЛЬКО в тот момент, когда кнопку нажали. В следующем кадре она уже вернёт false.

Ещё один пример:

function update(self, dt)
    imgui.begin_window("Defold or Unity?")
    
    if imgui.button("Defold") then
        print("The user chose Defold")
    end
    
    if imgui.button("Defold") then
        print("The user chose Defold")
    end
    
    imgui.end_window()
end

Пример с переменной:

local my_score = 0

function init(self)
    msg.post(".", "acquire_input_focus")
    imgui.set_ini_filename()
end

function update(self, dt)
    imgui.begin_window("Counter")
    imgui.text("Score: " .. my_score)
    if imgui.button("Add score") then
        my_score = my_score + 1  -- увеличиваем счёт
    end
    
    if imgui.button("Decrease score") then
        my_score = my_score - 1  -- уменьшаем счёт
    end

    if imgui.button("Reset") then
        my_score = 0  -- обнуляем счёт
    end
    
    imgui.end_window()
end

Что происходит каждый кадр?

  1. Игра вызывает update() 60 раз в секунду
  2. Каждый раз рисуется окно с кнопками
  3. ImGui проверяет: “А нажал ли игрок на кнопку в этом кадре?”
  4. Если да — функция возвращает true, если нет — false

Важные моменты: “Кнопка возвращает true только в момент клика”

Кнопки разного размера:

-- Обычная кнопка (размер по тексту)
if imgui.button("Small") then
    -- действие
end

-- Кнопка с заданным размером (ширина=200, высота=50)
if imgui.button("The Big Button", 200, 50) then
    -- действие
end

Несколько кнопок в ряд:

if imgui.button("Yes") then
    answer = "Yes"
end

imgui.same_line()  -- следующая кнопка будет на той же строке

if imgui.button("No") then
    answer = "No"
end

Переключатель через кнопку:

local music_on = true

function init(self)
    msg.post(".", "acquire_input_focus")
end

function update(self, dt)
    imgui.begin_window("Turner")
    -- В update()
    local button_text = music_on and "Off music" or "On music"
    if imgui.button(button_text) then
        music_on = not music_on  -- переключаем состояние
        print("Now music is:", music_on and "on" or "off")
    end
    imgui.end_window()
end


imgui.same_line()


imgui.same_line() позволяет рисовать следующий UI-элемент на той же строке, где сейчас находится курсор отрисовки, вместо перехода на новую строку.

Базовый пример:

imgui.begin_window("Example with same_line()")

-- Кнопки в одну строку
if imgui.button("Button 1") then end
imgui.same_line()
if imgui.button("Button 2") then end
imgui.same_line()
if imgui.button("Button 3") then end

imgui.end_window()

image

Всем спасибо за внимание!

1 лайк