Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create textbox in love2d

Tags:

lua

love2d

I have been trying to make a box for a user to input data once the user clicks the box. This is what I have so far, but clicking the box does not cause text input to be added to it. Where is the issue?

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
like image 396
laquishabonquiquithe3rd Avatar asked Dec 02 '25 09:12

laquishabonquiquithe3rd


2 Answers

You're pretty much on the way, but I'll give you some tips on how to create a basic textbox.

Firstly, consider a conceptual textbox to be a singular table, that contains everything it needs to know about itself to properly update and render. It's much easier to reason about something that is self contained.

A textbox needs to know its position, its size, whether it is active, and which text it contains. We can condense that into a table that looks like the following.

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

(We also store some color info.)

After that the simple way to add text is through love.textinput, as you've seen. In your code we only check if the textbox is active once, in love.load, which it of course isn't since we likely haven't taken any user input yet. Instead of attempting to overload the function, we simply check if the textbox is active or not inside the handler, and proceed accordingly.

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

We've covered how to check if the user has clicked within a rectangular area in the question: Love2d cursor positions. We want to deactivate the textbox if it is currently active and the user clicks outside of its 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

And finally we need to render our textbox. We use unpack to expand our color tables, and love.graphics.printf to make sure our text wraps within our textbox's 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

These are the basic ideas of creating a very rough textbox. It's not perfect. Note that you will need to consider what happens when the text gets longer height-wise than we initially set our textbox's height to, as the two are only loosely related.


To make your program easier to read, and easier to extend, everything you've seen above should really be placed into their own functions that handle textbox tables, instead of cluttering the love handlers with common code. Take a look at Chapter 16 of Programming in Lua, which covers Object-Oriented Programming - a generally vital topic for game development.


See the love.textinput page on how to handle a backspace, to delete characters.


Some extra things to think about:

  • How can we distinguish an active textbox from an inactive one?
  • How can we create a list of textboxes, so we can have multiple on screen (but only one active)?
like image 163
Oka Avatar answered Dec 04 '25 18:12

Oka


I guess, the love.textinput() callback function is what you are looking for. But as the term 'callback' implies, it will be called by the LÖVE engine, not your code. It will be called whenever the user inputs some text while your game is running. Therefore you need to put it outside the love.load() function.
In the love2d.org wiki is an example for this (the lower one).

As for your example, move the love.textinput() out of love.load() and add an if statement:

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

I hope I could help you a bit!

like image 42
nehegeb Avatar answered Dec 04 '25 18:12

nehegeb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!