Как создать текстовое поле в love2d

Я пытался создать окно для ввода данных пользователем, как только пользователь щелкнет поле. Это то, что у меня есть, но нажатие на поле не приводит к добавлению ввода текста. Где проблема?

function love.load ()
    txt1 = ""

    columnx = { 50, 160, 260, 375, 495, 600, 710 }
    columny = { 130, 230, 330, 440, 540, 640 }


     if show1 == true then
        function love.textinput(t)
            txt1 = t
        end
    end
end

function love.mousepressed (x, y)
    if
        x >= columnx[4] and
        x <= 435 and
        y >= columny[1] and
        y >= 145 then
        show1 = true
    end
end

function love.draw ()
    love.graphics.print(txt1, columnx[4], columny[1])
end

2 ответа

Решение

Вы в значительной степени в пути, но я дам вам несколько советов о том, как создать простое текстовое поле.

Во-первых, рассмотрите концептуальное текстовое поле как отдельную таблицу, которая содержит все, что нужно знать о себе для правильного обновления и рендеринга. Гораздо проще рассуждать о чем-то самодостаточном.

Текстовое поле должно знать свою позицию, его размер, активно ли оно и какой текст оно содержит. Мы можем сжать это в таблицу, которая выглядит следующим образом.

local textbox = {
    x = 40,
    y = 40,
    width = 400,
    height = 200,
    text = '',
    active = false,
    colors = {
        background = { 255, 255, 255, 255 },
        text = { 40, 40, 40, 255 }
    }
}

(Мы также храним некоторую информацию о цвете.)

После этого простой способ добавить текст через love.textinput, как вы видели. В вашем коде мы только проверяем, активен ли текстовый блок один раз, в love.load Конечно, это не так, поскольку мы, вероятно, еще не принимали пользовательский ввод. Вместо того, чтобы пытаться перегрузить функцию, мы просто проверяем, активно ли текстовое поле внутри обработчика, и действуем соответствующим образом.

function love.textinput (text)
    if textbox.active then
        textbox.text = textbox.text .. text
    end
end

Мы рассмотрели, как проверить, щелкнул ли пользователь в прямоугольной области в вопросе: позиции курсора Love2d. Мы хотим деактивировать текстовое поле, если оно активно в данный момент и пользователь щелкает за пределами своего пространства.

function love.mousepressed (x, y)
    if
        x >= textbox.x and
        x <= textbox.x + textbox.width and
        y >= textbox.y and 
        y <= textbox.y + textbox.height 
    then
        textbox.active = true
    elseif textbox.active then
        textbox.active = false
    end
end

И, наконец, нам нужно визуализировать наше текстовое поле. Мы используем unpack расширить наши таблицы цветов, и love.graphics.printf чтобы наш текст переместился в пространство нашего текстового поля.

function love.draw ()
    love.graphics.setColor(unpack(textbox.colors.background))
    love.graphics.rectangle('fill',
        textbox.x, textbox.y,
        textbox.width, textbox.height)

    love.graphics.setColor(unpack(textbox.colors.text))
    love.graphics.printf(textbox.text,
        textbox.x, textbox.y,
        textbox.width, 'left')
end

Это основные идеи создания очень грубого текстового поля. Это не идеально. Обратите внимание, что вам нужно будет рассмотреть, что произойдет, когда текст станет длиннее по высоте, чем мы изначально установили для высоты нашего текстового поля, так как они только слабо связаны.


Чтобы сделать вашу программу более удобной для чтения и расширения, все, что вы видели выше, должно быть действительно помещено в их собственные функции, которые обрабатывают таблицы текстовых полей, вместо того, чтобы загромождать love обработчики с общим кодом. Взгляните на главу 16 " Программирование на Lua", в которой рассматривается объектно-ориентированное программирование - как правило, важная тема для разработки игр.


Увидеть love.textinput страница о том, как обрабатывать клавишу возврата, чтобы удалить символы.


Некоторые дополнительные вещи, чтобы думать о:

  • Как мы можем отличить активное текстовое поле от неактивного?
  • Как мы можем создать список текстовых полей, чтобы у нас было несколько на экране (но только один активный)?

Я думаю, функция обратного вызова love.textinput() - это то, что вы ищете. Но, как следует из термина "обратный вызов", он будет вызываться механизмом LÖVE, а не вашим кодом. Он будет вызываться всякий раз, когда пользователь вводит текст во время игры. Поэтому вы должны поставить его за пределы love.load() функция.
В вики love2d.org пример для этого (нижний).

Что касается вашего примера, переместите love.textinput() снаружи love.load() и добавить if заявление:

function love.load()
    txt1 = ""

    columnx = {50, 160, 260, 375, 495, 600, 710}
    columny = {130, 230, 330, 440, 540, 640}
end

function love.textinput(t)
    if (show1) then
        txt1 = txt1 .. t
    end
end

-- The rest of your code.
-- And maybe mix it with the 'backspace example' from the wiki...

-- But you also might want to have some function to set 'show1' back to 'false' after the text input. Maybe something like this:
function love.keypressed(key)
    if (key == "return") and (show1) then
        show1 = false
    end
end

Я надеюсь, что смогу вам немного помочь!

Другие вопросы по тегам