Y'know, these your "Edit: never mind"s really annoy me
Best practices and things you'd like changed about Love2D
- Gunroar:Cannon()
- Party member
- Posts: 1142
- Joined: Thu Dec 10, 2020 1:57 am
Re: Best practices and things you'd like changed about Love2D
- Gunroar:Cannon()
- Party member
- Posts: 1142
- Joined: Thu Dec 10, 2020 1:57 am
Re: Best practices and things you'd like changed about Love2D
Okay, I see. Thnx for the info.
Y'know, these your "Edit: never mind"s really annoy me
- Gunroar:Cannon()
- Party member
- Posts: 1142
- Joined: Thu Dec 10, 2020 1:57 am
Re: Best practices and things you'd like changed about Love2D
Okay, I see. Thnx for the info.
Y'know, these your "Edit: never mind"s really annoy me
Re: Best practices and things you'd like changed about Love2D
I posted an opinion but changed my mind. The forum doesn't allow deleting posts, so that's all I can do. It was about Xii's complaint about lack of edge detection for keys; I said it was no big deal, as I don't think it's a frequent use case, but then this whole thread is about opinions, so it felt out of place.
Here's a complete example of how to implement what he was requesting. It may feel hacky to use love.draw, but I believe that's more stable across versions than modifying love.run, which is prone to change. love.draw is the last user code executed before events are read, so adding it at the end of love.draw guarantees that the keys are stored before the next events come.
If you know that you're reading each key always and only once, i.e. calling justPressed exactly once per frame for each key, and don't care about missing a press and a release in the same frame, there's a shortcut that doesn't need you to hook the events:
Here's a complete example of how to implement what he was requesting. It may feel hacky to use love.draw, but I believe that's more stable across versions than modifying love.run, which is prone to change. love.draw is the last user code executed before events are read, so adding it at the end of love.draw guarantees that the keys are stored before the next events come.
Code: Select all
local oldlevels = {}
local newlevels = {}
function love.keypressed(k, s)
newlevels[s] = true
end
function love.keyreleased(k, s)
newlevels[s] = false
end
local function justPressed(key)
return newlevels[key] and not oldlevels[key]
end
local function justReleased(key)
return oldlevels[key] and not newlevels[key]
end
function love.draw()
if justPressed("space") then
love.graphics.clear(255, 255, 255)
end
love.graphics.print("Press space to flash")
for k, v in pairs(newlevels) do
oldlevels[k] = v
end
end
Code: Select all
local edges = {}
local function justPressed(k)
local old = edges[k]
edges[k] = love.keyboard.isScancodeDown(k)
return edges[k] and not old
end
- Gunroar:Cannon()
- Party member
- Posts: 1142
- Joined: Thu Dec 10, 2020 1:57 am
Re: Best practices and things you'd like changed about Love2D
Yeeeessshhhhhh, I just saw how much I double posted. Sorry about that. When I pressed submit I didn't see it was on the second page so I thought it didn't go, then pasted what I typed(I always copy it so in case something bad happens I don't have to retype) and submitted again...twice.
Okay, sorry, it's just that it pokes my curiosity and feels incomplete, plus you did it last time but didn't see when I asked you what you said. . I don't know, maybe you could put the edit at the bottom of the original post so people(read: me) knows what you're talking about. But your way is still okay, I guess.pgimeno wrote: ↑Sat Jun 05, 2021 11:06 am I posted an opinion but changed my mind. The forum doesn't allow deleting posts, so that's all I can do. It was about Xii's complaint about lack of edge detection for keys; I said it was no big deal, as I don't think it's a frequent use case, but then this whole thread is about opinions, so it felt out of place.
Re: Best practices and things you'd like changed about Love2D
framestart and/or frameend events would be nice to have. Doing this stuff in love.update between input and output is often wrong, doing it at the end of love.draw feels dirty, and a custom love.run is not really an option for libraries.
A number of game state libraries people have posted here don't even care and switch between menu and game in love.update. One or two lines of code in the default love.run would make these things so much easier.
Re: Best practices and things you'd like changed about Love2D
+1. The best currently available workaround is to monkey-patch love.event.grump wrote: ↑Sat Jun 05, 2021 12:29 pm framestart and/or frameend events would be nice to have. Doing this stuff in love.update between input and output is often wrong, doing it at the end of love.draw feels dirty, and a custom love.run is not really an option for libraries.
A number of game state libraries people have posted here don't even care and switch between menu and game in love.update. One or two lines of code in the default love.run would make these things so much easier.
Also, it would be nice if love.handlers.update()/draw() was defined and called, instead of calling love.update and love.draw directly, for consistency with the rest of events and ease of hooking for libraries. I guess that asking for them to be enqueued like the rest of events is asking too much, due to the unpredictability in the ordering of the other events. You don't want a keypressed event to be processed between love.update and love.draw, for example.
Edit: I think I over-complicated my implementation of the edge detection code. This one also has the advantage of detecting a key press/release within one frame:
Code: Select all
local raisingEdges = {}
local fallingEdges = {}
function love.keypressed(k, s)
raisingEdges[s] = true
end
function love.keyreleased(k, s)
fallingEdges[s] = true
end
function justPressed(k)
return raisingEdges[k] or false
end
function love.draw()
...
for k in pairs(raisingEdges) do raisingEdges[k] = false end
for k in pairs(fallingEdges) do fallingEdges[k] = false end
end
Re: Best practices and things you'd like changed about Love2D
Jumping in a platformer. Shooting in a shooter. Activating a special ability. Pressing undo. It's a very frequent use case to detect single key presses. And every dev has to write this boilerplate. It's not a big deal, it's simple and easy, but it's something we all have to write. Isn't the point of a library that we don't all need to implement the things we all universally need?
- slime
- Solid Snayke
- Posts: 3163
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Best practices and things you'd like changed about Love2D
Those are all actions which are best handled via events (ie love.keypressed or keyreleased, in love's current API). Having code to check whether a key was pressed since the last time it was checked (i.e. the "wasPressed" approach) is subtly wrong because you will not detect things such as the user pressing and releasing a key twice in a frame. That may seem completely inconsequential at first but frame times are not predictable, and neither are user inputs. You're free to make that choice in your own game if you really want of course since love gives you the tools to do so, but I'd consider it bad design for a library or framework to promote that.Xii wrote: ↑Sat Jun 05, 2021 7:33 pm Jumping in a platformer. Shooting in a shooter. Activating a special ability. Pressing undo. It's a very frequent use case to detect single key presses. And every dev has to write this boilerplate. It's not a big deal, it's simple and easy, but it's something we all have to write. Isn't the point of a library that we don't all need to implement the things we all universally need?
An easy way to think about the best place to handle something is - actions (undo, ability activation, etc) are best suited for key events, whereas things that happen over time (movement, charging an ability, etc) are best suited for per-frame code. Putting actions in per-frame code can be easy to do but leads to the above issues.
There's an argument to be made that events should be easier to use than having a centralized callback which executes everything that wants to handle that event. But that's still a fundamentally different approach than "wasPressed".
The main reason why love doesn't have that decentralized events feature yet is because people haven't come up with a design that works well with arbitrary game states, whereas the current approach lets users decide which events get routed through a game state.
As for wiki clarity, the wiki is freely editable by anyone. If you have an improvement to make, feel free to do it - but also keep in mind its primary purpose is simple documentation rather than tutorialization. Either having a note about sprite sheets in the image example you mentioned or having a second more in-depth example with sprite sheets seem like good approaches to me (rather than having a more complicated sprite sheet example up-front).
I agree that love.load is pretty redundant since love 11 (however it had initialization-related reasons to exist prior to love 11) - but outright removing it and breaking a bunch of code hasn't been a priority in the past either. Maybe it could be deprecated in love 12 or something.
The graphics, image, video, sound, audio, filesystem, font, math, physics, and timer modules don't use SDL at all. Input and windowing are mostly SDL wrappers, but I don't really consider that a bad thing (especially given love's core philosophy of not imposing restrictive high level choices you'd find in bigger engines) because SDL made some good design decisions in that area.
Re: Best practices and things you'd like changed about Love2D
I personally like Löves "do it yourself" approach, because something which may seem universally needed to you, might not be for others. I have never needed to write that boilerplate code which you talk about for example. I hope Löve focuses on staying a framework rather than trying to be an engine.Xii wrote: ↑Sat Jun 05, 2021 7:33 pmJumping in a platformer. Shooting in a shooter. Activating a special ability. Pressing undo. It's a very frequent use case to detect single key presses. And every dev has to write this boilerplate. It's not a big deal, it's simple and easy, but it's something we all have to write. Isn't the point of a library that we don't all need to implement the things we all universally need?
Who is online
Users browsing this forum: No registered users and 4 guests