如何在 love2d 中创建文本框

How to create textbox in 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

你已经差不多了,但我会给你一些关于如何创建基本文本框的提示。

首先,将概念性的 文本框 视为一个单一的 table,其中包含正确更新和呈现所需的有关自身的所有信息。对独立的东西进行推理要容易得多。

文本框需要知道它的位置、大小、是否处于活动状态以及它包含哪些文本。我们可以将其压缩成如下所示的 table。

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, as you've seen. In your code we only check if the textbox is active once, in love.load,当然不是,因为我们可能还没有接受任何用户输入。我们没有尝试重载该函数,而是简单地检查文本框在处理程序中是否处于活动状态,然后进行相应处理。

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

我们已经介绍了如何检查用户是否在问题的矩形区域内单击:。如果文本框当前处于活动状态并且用户单击其 space.

外部 ,我们希望停用该文本框
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 to expand our color tables, and love.graphics.printf 来确保我们的文本在文本框的 space.

中换行
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

这些是创建非常粗糙的文本框的基本思路。这并不完美。请注意,您需要考虑当文本的高度比我们最初设置的文本框高度更长时会发生什么,因为这两者只是松散相关。


为了使您的程序更易于阅读和扩展,您在上面看到的所有内容都应该真正放入它们自己的处理文本框 table 的函数中,而不是使 love 具有通用代码的处理程序。看看 Programming in Lua, which covers Object-Oriented Programming 的第 16 章 - 一个对游戏开发来说通常很重要的话题。


请参阅 love.textinput 页面,了解如何处理后退space,以删除字符。


需要考虑的一些额外事项:

  • 我们如何区分活动文本框和非活动文本框?
  • 我们如何创建一个文本框列表,以便我们可以在屏幕上显示多个(但只有一个处于活动状态)?

我想,love.textinput() 回调函数就是您要找的。但正如术语 'callback' 所暗示的那样,它将由 LÖVE 引擎调用,而不是您的代码。当您的游戏处于 运行 时,只要用户输入一些文本,它就会被调用。因此你需要把它放在 love.load() 函数之外。
在 love2d.org wiki 中有一个例子(下一个)。

对于您的示例,将 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

希望能帮到你!