having problems getting keyboard input in LÖVE - lua

heyo!
I'm trying to get input from my keyboard in LOVE2D but no input is being registered. getting no errors.
here's the code:
ESCdown=love.keyboard.isDown('escape')
function love.update()
if ESCdown then
love.event.quit()
end
end

love.update is called every frame.
ESCdown is assigned a value once and then never changes.
Consider using keyboard events:
https://love2d.org/wiki/love.keypressed
It even gives an example for what you want to do:
function love.keypressed(key, scancode, isrepeat)
if key == "escape" then
love.event.quit()
end
end

Related

Pico-8 coroutines are occasionally dead

I was trying to replace a for-loop with coroutines to move the stars:
--fine
function _update()
for c in all(boids) do
move_boid(c)
end
end
--broken
function _update()
for c in all(boids) do
coresume(cocreate(move_boid),c)
end
end
Notice that a fixed number of stars are frozen (I'm pretty sure the number is fixed):
But why? How can I handle this? The complete code is on itch.
Thanks for #Vald and #Egor's comments. Seems the problem is caused by "too-long coroutines" to finish in a PICO-8 cycle. So the solution is that I store unfinished coroutines in a table and resume them if not finished. But somehow the movement is changed, kinda like "lost frame".
Here's my edited code:
function _init()
-- code
cors={}
end
function _update()
for i=1,#boids do
local co=cocreate(move_boid)
local c=boids[i]
add(cors,co)
coresume(co,c)
end
for co in all(cors) do
if (co and costatus(co)!="dead") then
coresume(co)
else
del(cors,co)
end
end
end
And also modify the calculation function, adding a new line in the middle:
function move_boid(c)
-- code
yield()
-- code
end
Just to yield before it's completed.
Update: another way to do it is reusing coroutines.
function _init()
-- code
-- create coroutines
cors={}
for i=1,#boids do
local co=cocreate(move_boid)
local c=boids[i]
add(cors,co)
coresume(co,c)
end
end
function _update()
foreach(cors,coresume)
end
-- and wrap the move function with a loop
function move_boid(c)
while true do
-- code
yield()
-- code
yield()
end
end

PICO-8 making a button press show an output of text only once?

I'm a complete newbie to both Lua, PICO-8, and coding in general. I'm having trouble with a function I want to put in my first program. The text is all placeholder, I will change it once I get the code right and comprehend it.
Basically, before the _init() I have a function ow() defined where I press a button and the program displays the text "ow." I put the function name in _update() so that it will update 30x/second to see if the button is pressed; however, this is making the "ow" appear 30 times a second (or however long the button is pressed) instead of appearing once when I initially press the button. How do I fix this? Thank you for your tolerance of a new coder's question in advance. Here's my code:
function ow()
if btn((X))
then print "ow"
--how do i make it do this
--only once?
end
end
function _init()
print "hello."
print "i have been waiting for you."
end
function _update()
ow()
end
function _draw()
end
You need a global variable to save previous status of the button.
function ow()
if btn((X)) then
if not button_was_pressed then
button_was_pressed = true
print "ow"
end
else
button_was_pressed = false
end
end

How to tell if a key has been released in Love2d

I want to add an ability in my game where if you hold t then the enemies are slowed down. love.keyboard.isDown won't let me put the enemies back to their original speed once the t key has been released. Is their another way I could do this?
Use love.keyreleased.
Note that unlike love.keyboard.isDown, it's a callback function. Use it to register the action when the key t is released.
Using love.keyboard.isDown will let you put their original speed back if you check when it's false, like so:
if love.keyboard.isDown('t') then
enemy_speed = 15
else
enemy_speed = 30 -- 't' key has been released
end
but there is an another way to do this. Use love.keypressed and love.keyreleased, like so:
function love.keypressed(key)
if key == 't' then
enemy_speed = 15
end
end
function love.keyreleased(key)
if key == 't' then
enemy_speed = 30 -- 't' key has been released
end
end
if I understand, love.keyboard.isDown("t") is for to the love.update() function, and it will just repeat the function no matter what. so in this case create a function like this in your main.lua file:
function love.keypressed(k)
if k == "t" then
// Code goes in here
end
end
like this, it should activate once the key is pressed.

call a function from inside a table that's inside another table in lua

I am attempting to build my first game using love2D, I have hit a problem.
The game is a bubble popping game, I want to assign a bubble to each letter on the keyboard so that when a letter is pressed, the bubble will pop.
I have an external file called "bubble.lua" which I have tried to make an object "bubble" with.
to do that I have created a table "bubble" in the bubble.lua which contains functions and variables. Now, this file works when called from main.lua using just one bubble, however I am going to need 26 bubbles so I thought it would be best to store each bubble in another table. For the purpose of trying this I just stored one bubble using 1 as the key.This is where I have problems.
require "bubble"
local bubbles = {}
function love.load()
bubbles[1] = bubble.load(100, 100)
end
function love.draw()
for bubble in bubbles do
bubble.draw()
end
end
function love.keypressed(key)
bubbles[key].bubble.pop()
end
Firstly, I know that the for loop in love.draw() does not work, and the line "bubble[key].bubble.pop" seems to return nil as well
The for loop I can probably find the solution myself online, my main problem is the "bubble[key].bubble.pop()" line, I cannot work out what's wrong or how to fix it.
Can anybody help me?
You may want to look at this as well:
bubble.lua
bubble = {}
function bubble.load(posX, posY)
bubble.x = posX
bubble.y = posY
bubble.popped = false
end
function bubble.draw()
if not bubble.popped then
love.graphics.rectangle("line", bubble.x, bubble.y, 37, 37)
else
love.graphics.rectangle("line", bubble.x, bubble.y, 37, 100)
end
end
function bubble.pop()
bubble.popped = true
end
Edit:
Following the advice of the answer below I now have the following error when I press "a":
main.lua:14: attempt to index a nil value
the updated code is below
main.lua
require "bubble"
local bubbles = {}
function love.load()
bubbles["a"] = bubble.load(100, 100)
end
function love.draw()
for key, bubble in pairs(bubbles) do
bubble.draw()
end
end
function love.keypressed(key)
bubbles[key].pop()
end
any thoughts?
There are several issues with this code. First, you index by number when you initialize bubbles (bubbles[1]), but access them using the key as the index (bubbles[key]), which is NOT a number. You need to settle on one mechanism to index the bubbles. Let's say you picked using key as the index (instead of the number).
This loop:
for bubble in bubbles do
bubble.draw()
end
should be written as:
for key, bubble in pairs(bubbles) do
bubble.draw()
end
and instead of bubbles[key].bubble.pop() you can simply do bubbles[key].pop() as bubbles[key] already returns the bubble you can pop.
To initialize, instead of bubbles[1] you need to do bubbles['a'] (or whatever other value is used by key in love.keypressed(key)).

Having trouble with some computercraft/lua code

Hi I want my lua code in Computercraft to allow the user to turn the redstone signal on/off by right clicking on a monitor on top, but I can't get it to work.
monitor = peripheral.wrap("top")
monitor.clear()
monitor.setTextColor(colors.red)
monitor.setCursorPos(1, 1)
monitor.setTextScale(1)
monitor.write("Hello")
function rubber()
monitor.setCursorPos(1, 2)
monitor.clearLine()
if rs.getOutput("right", true) then
monitor.write("Rubber farm is on")
elseif rs.getOutput("right", false) then
monitor.write("Rubber farm is off")
end
local event = { os.pullEvent() }
if event == "monitor_touch" then
if rs.getOutput("right") == true then
rs.setOutput("right", false)
else
rs.setOutput("right", true)
end
else
write("test")
end
rubber()
end
Right now all it displays is 'hello' and I don't know how to fix it, anyone know how? Also I'm a beginner at Lua so I've probably made some pretty simple mistakes. Thanks
local event = { os.pullEvent() }
if event == "monitor_touch" then
os.pullEvent returns a tuple. In your code, you're packing this tuple into a table. That's fine, but you then compare that table to a string. Tables can't be equal to strings - they're a table. Either don't pack the tuple into a table, and keep the first return value (the type):
local event = os.pullEvent()
if event == "monitor_touch" then
Or extract the first element when comparing
local event = { os.pullEvent() }
if event[1] == "monitor_touch" then
The problem is you wanted to have that function infinitly looping, but you have not called your function outside your function.... also you should look into using while loops
while true do
//stuff here
end
just add
rubber()
to the last line after your last end tag.
You have to call the function.
rubber()
You need to close your function
function rubber()
monitor.setCursorPos(1,1)
monitor.clearLine()
end
The end is it you need to make this little word
this is a simple fix, simply add rubber() after you finish the function rubber, cause while you have created the function rubber, you have not called for it to start yet.
The "monitor_touch" event is what you should be using. Also, make sure the monitor you are using is an advanced monitor (the one with the yellow border).
If you need help in understanding the event, check out this page: http://computercraft.info/wiki/Monitor_touch_(event)

Resources