I’ve run into an error where the on_input function is reading that I released either of the right/left keys when I’m still holding one. This makes it so that the player decelerates before they even started moving.
function on_input(self, action_id, action)
if action_id == hash("left") and action.repeated then
move = 0
accelerate(self, -maxSpeed)
print("left")
elseif action_id == hash("right") and action.repeated then
move = 0
accelerate(self, maxSpeed)
print("right")
elseif action_id == hash("left") or hash("right") and action.released then
move = 0
accelerate(self, 0)
print("decelerating")
end
end
What’s up? If I’m holding the left/right key, then the input should read that I’m still holding it, not that I released it…
No no, are you sure that will work? (You are correct in saying that and has higher precedence than or). The and operator definition states that and will give its first argument if it is false, otherwise the second (Programming in Lua : 3.3).
1st argument: action_id == (hash("left") or hash("right"))
and
2nd argument: action.released
So, let’s examine the first argument and what that evaluates to:
action_id == (hash("left") or hash("right"))
We need to look at that or first. The or in Lua is defined to return its first argument if it is true, otherwise the second.
1st argument: hash("left")
or
2nd argument: hash("right")
Both of these are true. Lua will return hash("left") which leaves us with:
action_id == hash("left") and action.released
Which isn’t what was intended. This would be the correct conditional:
elseif (action_id == (hash("left") or action_id == hash("right")) and action.released then
The on_input() function is called twice, once when action_id == hash(“left”) and one where it’s hash(“right”). You could accumulate the input and simply move the reaction code to update():
function update(self, dt)
accelerate(self, maxSpeed * self.move)
self.move = 0
end
function on_input(self, action_id, action)
if action_id == hash("left") then
self.move = -1
elseif action_id == hash("right") then
self.move = 1
end
end
This is a bit unpredictable if the player presses left and right simultaneously since on_input will be called once for each input, but in what order? That’s easily fixed though. Say that you want left to take precedence:
function on_input(self, action_id, action)
if action_id == hash("left") then
self.move = -1
elseif action_id == hash("right") and self.move == 0 then
self.move = 1
end
end
What I meant was that hash(“left”) and hash(“right”) are values that are considered true in Lua (nil and false are considered false). I’m fully aware that you’ll get multiple calls to on_input() once per input “event”.
True! I got caught up in the details of the language. Storing key states (pressed/released) in a table and updating in update() is better in this case.