local anim_to_right = hash("to_right")
local anim_idle_right = hash("idle_right")
local anim_to_left = hash("to_left")
local anim_idle_left = hash("idle_left")
function init(self)
msg.post(".", "acquire_input_focus")
self.speed = 20
self.right = true;
self.left = false;
self.lastAnimation = anim_idle_right
end
local function toRight(self)
self.right = true;
self.left = false;
local p = go.get_position()
p.x = p.x + self.speed
go.set_position(p)
end
local function toLeft(self)
self.right = false;
self.left = true;
local p = go.get_position()
p.x = p.x - self.speed
go.set_position(p)
end
local function managerAnimation(self,newAnimation)
if self.lastAnimation ~= newAnimation then
msg.post(".", "play_animation", {id = newAnimation})
self.lastAnimation = newAnimation
end
end
function update(self, dt) end
function on_message(self, message_id, message, sender) end
function on_input(self, action_id, action)
if action_id == hash("key_right") and action.repeated then
toRight(self)
managerAnimation(self,anim_to_right)
elseif action_id == hash("key_left") and action.repeated then
toLeft(self)
managerAnimation(self,anim_to_left)
end
if action_id == hash("key_right") and action.released then
managerAnimation(self,anim_idle_right)
elseif action_id == hash("key_left") and action.released then
managerAnimation(self,anim_idle_left)
end
end
I think you are going about the movement logic in a little bit of an “odd” way, you see since I am not sure but I do not think that the action.repeated is called every single frame, and therefore the best way to do movement would be something along the lines of this:
function init(self)
self.right = false
self.left = false
end
function update(self, dt)
local pos = go.get_position()
if self.left then
pos.x = pos.x - (speed * dt)
elseif self.right then
pos.x = pos.x + (speed * dt)
end
end
function on_input(self, action_id, action)
self.right = false
self.left = false
if action_id == hash("key_right") then
self.right = true
elseif action_id == hash("key_left") then
self.left = true
end
end
So what is happening here is that you update the movement every frame, you have 2 variables, one for left and one for right. I might have made a small mistake or 2, but the idea is use booleans that you update in the input, and that you check every frame in the update method.
Also use dt, which converts the speed variable from pixels per frame to pixels per second, this compensates for lag, or slower computers and faster computers that don’t run exactly 60 fps.
Correct. By default action.repeated isn’t called every frame. You can set Repeat Interval in game.project so that you get an action.repeated call every frame, but I think it’s better to set a flags when actions are pressed and clear the flags when released and update animations and movement based on these flags, just like @dawo2002 suggested.
Hahaha this is a good definition for my code style!
Nice hint! really useful to solve this situation thank you!
Thanks man! it is a good alternative option but i prefer update the code to use the @dawo2002 solution and avoid change any default configuration. Probably when i learn more about defold i will start to change this configuration.
A really important information!!! Thanks a lot!
Problem Solved!
Guys now it is everything working! With yours hints I made the refactoring the code and fix this logic error in my game.
See the Result:
Excellent! Good to hear that we were able to help you! As a bonus: The solution where you keep track of the different input states using booleans can be encapsulated into a Lua module so that it is easy for you to reuse. I’ve done it in this Lua module that you’re free to use if you like, or you can do it yourself as well. It is used like this:
local input = require "ludobits.m.input"
function init(self)
input.acquire()
end
function final(self)
input.release()
end
function update(self, dt)
if input.is_pressed(hash("left")) then
go.set_position(go.get_position() - vmath.vector3(50, 0, 0) * dt)
elseif input.is_pressed(hash("right")) then
go.set_position(go.get_position() + vmath.vector3(50, 0, 0) * dt)
end
end
function on_input(self, action_id, action)
input.on_input(action_id, action)
end
hmmm! nice utility file. Thank you! So, if we are checking the pressed action inside the update function we don’t need a action.repeated because update function it is executed every frame/cicle. is this correct?