Hello, I’m following the crash course Defold tutorial and have previously watched the whole Defold tutorial series from Gamefromscratch. On there they make a script for moving the character but, when I press right it starts going right indefinitely until I press left when it starts going just left (even when the key is released). Tried some stuff on my own like “and action.released ~= true” etc but with no luck (probbably because I’m so new to Defold and Lua altogether. Can anyone help me? I want the character to stop and the idle anim to play when no keys are being pressed (at least not the right or left for now). The script can be found here
hi!
Put this code into your on_input
pprint(action)
and you can see the action table in your console. Search in the console for a field called “released” and when released = true, then it means a key was released.
if action.released ~= true then
here, you are checking that action.released is NOT true. you need to write it like this
if action.released == true then
just to make that clear,
if action.released ~= true then
means:
If action.released is unequal to true then
and you want to use ==, which means “equal to”
Hi, thanks for the response. Where would I be checking for that? In the update or input (with a repeat untill released == true?)
the action table is only available in the on_input() function. The code on your tutorial would probably be better if it was something like this:
function on_input(self, action_id, action)
if action_id == hash(“MOVE_RIGHT”) and action.pressed then
self.speed.x = self.runSpeed
sprite.set_hflip("#sprite", false)
end
if action_id == hash(“MOVE_LEFT”) and action.pressed then
self.speed.x = self.runSpeed * -1
sprite.set_hflip("#sprite", true)
end
if action.released then --if any key is released…
self.speed.x = 0 …set the speed to zero (and also maybe set the idle anim?
end
end
If I understood correctly, while holding the button
In on_input
if action.repeated then
--moving
end
The site also has great manuals.
action.repeated is something else which I can’t explain right now. But it’s not important at the moment, you just need action.pressed and action.released.
Remember, if you put pprint(action) at the top of your on_input section, you can see the Action Table in the console. That will show you what information is being used in the function.
Yes! That’s it! I can’t believe I didn’t think of that (I suppose for some reason I wasn’t thinking as released starting on_input too. Now just need to sort the animations. Thanks a lot. Can I choose the right answer, close the question or something like that on this forum?
you can edit the title to put (SOLVED) at the end.
Here’s also an example of eight way movement: https://defold.com/examples/input/move
And another example tracking key states and animations: https://github.com/britzl/publicexamples/tree/master/examples/play_animation
Oh and this as well: https://github.com/britzl/publicexamples/tree/master/examples/top_down_movement
Hey hey!
First post, so let me know if I’m breaking some rule. But in case anyone finds this in the future as I did from a google search, I’ve got a little bit of a small bugfix.
Doing the standard 8-way movement code worked in general, but I was running into this issue:
- Press and hold “right” (player moves right)
- Press “left” (player moves left)
- Let go of “left” while still holding “right” (player stands still)
The player should be moving right in this scenario. So I went around this like so:
in update(self, dt)
:
local pos = go.get_position()
pos = pos + velocity * dt
go.set_position(pos)
And in my on_input(self, action_id, action)
:
if action_id == hash("left") then
if action.pressed then
velocity.x = velocity.x - self.speed
elseif action.released then
velocity.x = velocity.x + self.speed
end
elseif action_id == hash("right") then
if action.pressed then
velocity.x = velocity.x + self.speed
elseif action.released then
velocity.x = velocity.x - self.speed
end
elseif action_id == hash("up") then
if action.pressed then
velocity.y = velocity.y + self.speed
elseif action.released then
velocity.y = velocity.y - self.speed
end
elseif action_id == hash("down") then
if action.pressed then
velocity.y = velocity.y - self.speed
elseif action.released then
velocity.y = velocity.y + self.speed
end
end
It’s very unwieldy, but it gets the job done and doesn’t require processing repeated inputs. This is the first real, full-fledged game I’m working on, so if anyone happens to have a better way, do let me know!
You could do generic input tracking in on_input() and the check which keys are held down in update():
function init(self)
self.actions = {}
end
function update(self, dt)
local pos = go.get_position()
if self.actions[hash("right")] then
pos.x = pos.x + self.speed * dt
elseif self.actions[hash("left")] then
pos.x = pos.x - self.speed * dt
elseif self.actions[hash("up")] then
pos.y = pos.y + self.speed * dt
elseif self.actions[hash("down")] then
pos.y = pos.y - self.speed * dt
end
go.set_position(pos)
end
function on_input(self, action_id, action)
if action_id then
if action.pressed then
self.actions[action_id] = true
elseif action.released then
self.actions[action_id] = false
end
end
end
I’m not sure if it is necessarily better, but at least it is a different solution that can be good to know about.