I’m developing a game just for fun, but i came across a bug of the movement of the player that im just can’t understand. My knowledge of programming is pretty basic (i studied C in colege) and based in codes of forums that i found here.
Basically the bug is that the game does not accept two inputs at the same time.
Like, if im pressing the action D the player go to the right, and if i press the action A (with D still pressed) the player go to the left, but if i let go A the player just stops like any action is pressed.
function init(self)
msg.post('.', 'acquire_input_focus')
self.velocity_direction = vmath.vector3()
self.velocity_module = 60
self.direction = vmath.vector3()
end
function update(self, dt)
self.current_position = go.get_position()
self.new_position = self.current_position + self.velocity_direction * self.velocity_module * dt
go.set_position(self.new_position)
end
function on_input(self, action_id, action)
if action_id == hash('left') and action.pressed then
self.velocity_direction.x = -1
self.direction.x = -1
msg.post('player', "play_animation", {id = hash('player_run_left')})
elseif action_id == hash('right') and action.pressed then
self.velocity_direction.x = 1
self.direction.x = 1
msg.post('player', "play_animation", {id = hash('player_run_right')})
end
if action.released and self.direction.x == -1 then
self.velocity_direction.x = 0
msg.post('player', "play_animation", {id = hash('player_idle_left')})
elseif action.released and self.direction.x == 1 then
msg.post('player', "play_animation", {id = hash('player_idle_right')})
self.velocity_direction.x = 0
end
end
The issue here is that you’re only setting the velocity direction when the action is first pressed. So what happens is you press A and D, set the velocity to whichever is pressed second, then when you release one of them it sets your velocity to 0 because of the action.released code you have, and it won’t be set to a direction again until you re-press the button.
Instead of checking for action.pressed, just zero your velocity on a release action of a movement key like you’re doing, and set the directional velocity for any non-release action.
function init(self)
msg.post('.', 'acquire_input_focus')
self.velocity_module = 60
self.direction = vmath.vector3()
self.velocity = 1
self.left_down = false
self.right_down = false
end
function update(self, dt)
self.current_position = go.get_position()
self.new_position = self.current_position + self.direction * self.velocity * self.velocity_module * dt
go.set_position(self.new_position)
end
function on_input(self, action_id, action)
if action.pressed then
if action_id == hash('left') then
self.left_down = true
self.direction.x = -1
elseif action_id == hash('right') then
self.right_down = true
self.direction.x = 1
end
end
if action.released then
if action_id == hash('left') then
self.left_down = false
if self.right_down then
self.direction.x = 1
msg.post('player', "play_animation", { id = hash('player_run_right') })
end
elseif action_id == hash('right') then
self.right_down = false
if self.left_down then
self.direction.x = -1
msg.post('player', "play_animation", { id = hash('player_run_left') })
end
end
end
if not self.left_down and not self.right_down then
if self.direction == -1 then
msg.post('player', "play_animation", { id = hash('player_idle_left') })
elseif self.direction == 1 then
msg.post('player', "play_animation", { id = hash('player_idle_right') })
end
self.direction.x = 0
elseif self.left_down and self.direction.x ~= -1 and not self.right_down then
self.direction.x = -1
msg.post('player', "play_animation", { id = hash('player_run_left') })
elseif self.right_down and self.direction.x ~= 1 and not self.left_down then
self.direction.x = 1
msg.post('player', "play_animation", { id = hash('player_run_right') })
end
end
Alternatively, you could try just removing the action.pressed check and decoupling your animation playback from your input. The great thing about programming is there’s always more than one way of doing things:
-- also good practice to prehash anything you're gonna reuse often, such as input ids
local h_player_run_left = hash("player_run_left")
local h_player_run_right = hash("player_run_right")
local h_player_idle_left = hash("player_idle_left")
local h_player_idle_right = hash("player_idle_right")
function play_animation(self, anim)
if anim ~= self.current_animation then
msg.post('player', "play_animation", {id = anim})
self.current_animation = anim
end
end
function update(self, dt)
if self.velocity_direction.x < 0 then
play_animation(self, h_player_run_left)
elseif self.velocity_direction.x > 0 then
play_animation(self, h_player_run_right)
elseif self.direction.x < 0 then
play_animation(self, h_player_idle_left)
else
play_animation(self, h_player_idle_right)
end
end
local h_left = hash("left")
local h_right = hash("right")
function on_input(self, action_id, action)
if action_id == h_left then
if action.released then
self.velocity_direction.x = 0
else
self.velocity_direction.x = -1
self.direction.x = -1
end
elseif action_id == h_right then
if action.released then
self.velocity_direction.x = 0
else
self.velocity_direction.x = 1
self.direction.x = 1
end
end
end