Hello reader.
I am currently trying to make a zelda like game with animations for movement but have come to some problems, the animations play but at an abnormal frame rate and dont seem to stop when standing still. Here is my code
function init(self)
msg.post(".", "acquire_input_focus")
self.vel = vmath.vector3()
end
function update(self, dt)
local pos = go.get_position()
pos = pos + self.vel * dt
go.set_position(pos)
self.vel.x = 0
self.vel.y = 0
end
function on_input(self, action_id, action)
if action_id == hash("up") then
self.vel.y = 15
elseif action_id == hash("down") then
self.vel.y = -15
msg.post("#robo", "play_animation", {id = hash("down M")})
elseif action_id == hash("left") then
self.vel.x = -15
msg.post("#robo", "play_animation", {id = hash("left M")})
elseif action_id == hash("right") then
self.vel.x = 15
msg.post("#robo", "play_animation", {id = hash("right M")})
end
end
Any suggestions to how to fix this problem would be highly appreciated
It looks like you are using sprite animations. You can control much of its behaviour on the animations properties in the atlas. The speed is controlled by the FPS (frames per second) and the looping is controlled by the Playback.
You act on all input, meaning that if you press ”up”, for instance, you get 60 inputs/s and the animation restarts each frame.
What you want to do is to only play a new animation when the input changes. Alternatively, only play when user presses the button, avoiding all repeats when the button is held down:
if action_id == hash("up") and action.pressed then
...
Thank you for the reply, however I still seem to be facing the same problem.
So I did a little reading and found an idea of how the animations might work but not quite sure how to apply them to the code
1st idea:
Have the sprite respond to the direction of movement
If self velocity.x < 0 then
msg.post("#robot", “play_animation”, {id = hash(“walk left”)})
( Or is it called play_animation(self, “walk left”)
If self velocity.x > 0 then
msg.post("#robot", “play_animation”, {id = hash(“walk right”)})
( Or is it called play_animation(self, “walk right”)
2nd idea:
have animations play based on booleans
if action_id == hash(“left”) then set ( move left = true )
if ( move left = true ) then
msg.post("#robot", “play_animation”, {id = hash(“walk right”)})
( Or is it called play_animation(self, “walk right”)
if action_id == hash(“left”) then set ( move right = true )
if ( move right = true ) then
msg.post("#robot", “play_animation”, {id = hash(“walk right”)})
( Or is it called play_animation(self, “walk right”)
I may be mixing up lua with other languages but is it possible to apply these codes to defold scripts and if so where would they be placed
This is almost perfect,
But now the animations frames are still out of control.
Although I set the animations to play at 10 fps when creating them they still play at an insanely high speed.
This will also cause a few issues when moving in diagonals.
I once used another app named stencyl to make a few games and there was a section for animations to be added where one could place conditions on motion like so:
update_animations() and play_animation() are custom functions written by the user (you). They won’t exist or ever be called unless you do it.
When you create a new script, Defold automatically adds all the “lifecycle functions” to it:
init — called when the script instance is created
final — called when the script instance is destroyed
update — called every frame
on_message — called every time the script gets a message
on_input — called every time the script gets input (if it has acquired input focus)
on_reload — called when the script is hot reloaded
These functions will be called by the engine at certain points during the life of the script instance and your game. They won’t actually do anything until you add code to them. All the code in your game will branch out from these functions.
Then there are the engine API functions. Basically all of these will be prefaced by the name of the library that they are in, like: go.get_position() (from the Game Object library), msg.post() (from the Message library), or vmath.length() (from the Vector Math library). You have to call these yourself, but what they do is pre-defined and isn’t meant to be changed.
Then there are user-defined functions (like update_animations or play_animation). You can create as many of these as you want. Basically anytime you have a sequence of things that you want to do multiple times in the same script, you should put those things in a function (otherwise you will have to write the same code multiple times). You should always define them as local or you may get very weird bugs.
The colored blocks that Stencyl uses are basically identical to text code. If you took away the colored shapes so you just had the text, that would be very close to the code you need to write for Defold.
Stencyl’s “When Creating” is the same as Defold’s init(), and for all simple cases, Stencyl’s “When Drawing” and “When Updating” are combined in Defold’s update().
Could you please try checking the Variable Dt option in game.project and see if this helps? It sounds as if you’re graphics driver isn’t respecting the vsync and runs full speed.