Hi, I’m new Lua/Defold game developer coming from C#/Unity.
I’m testing music player for my game and ran into a problem I cant seem to figure out.
When track is done playing the [complete_function] is called and next track starts playing fine.
But when I manually press next track button it goes through the tracks instantly and really fast.
Help would be much appreciated!
Below is parts of the code
-- Music playback status table
local music = {
playing = true,
repeating = false,
shuffle = false,
index = nil,
}
-- Track component table
local track = {}
for i = 1, 8 do
track[i] = "#track_" .. i
end
-- Next track
local function forward()
if music.index < #track then
sound.stop(track[music.index])
music.index = music.index + 1
sound.play(track[music.index], nil, forward)
music.playing = true
else
sound.stop(track[music.index])
music.index = 1
sound.play(track[music.index], nil, forward)
music.playing = true
end
end
I’m using Gooey and the input comes from music.gui_script
local function update_button(button)
if button.pressed_now then
gui.set_color(button.node, COLOR_PRESSED)
elseif button.released_now then
gui.set_color(button.node, COLOR_DEFAULT)
elseif not button.pressed and button.out_now then
gui.set_color(button.node, COLOR_DEFAULT)
end
end
local function on_pressed(button)
if button.node_id == hash("button_music_forward") then
msg.post("main:/music", "music_forward")
end
end
function on_input(self, action_id, action)
gooey.button("button_music_forward", action_id, action, on_pressed, update_button)
end
Thanks. The reason I asked is because I was thinking that you were calling forward() constantly in on_input(), but assuming you have Gooey set up correctly (I’m not familiar with it) then the fact that it is on_press should invalidate that theory.
Having run a quick check, I think it is because calling sound.stop() triggers the complete_function. This isn’t clear in the sound.play(), sound_stop() or sound_done API refs.
In my opinion, the most problematic part of the documentation is this line:
This message is sent back to the sender of a play_sound message, if the sound could be played to completion.
I think the documentation might benefit from an update clarifying this.
I moved this music player fixing for later to do other stuff but now I’m back to finish this.
I’m trying to do very basic in-game music player with the usual buttons like, Play/Pause, previous track, next track, shuffle and repeat.
Using sound.play() with complete_function to play next track after current one finishes.
Pressing next track (>>) button calls sound.stop() and that triggers the complete_function so this is working great.
But with previous track (<<) button it should stop current track without triggering complete_function and then start playing previous track that does trigger complete_function like normal.
I feel like this should be simple thing to figure out but I’m struggling with this still
Here are relevant parts of the music player code currently.
Local variables and tables
-- Music player status
local is_playing = false
local is_repeating = false
local is_shuffle = false
local index = nil
local previous_requested = nil
-- Track table
local track = {}
for i = 1, 8 do
track[i] = "#track_"..i
end
Init
-- Start playing from track 1
index = 1
sound.play(track[index], nil, track_selection)
is_playing = true
Track selection func
local function track_selection()
if is_repeating then
sound.play(track[index], nil, track_selection)
is_playing = true
elseif is_shuffle then
index = math.random(1, 8) --TODO: proper shuffle
sound.play(track[index], nil, track_selection)
is_playing = true
else
if previous_requested then
-- Previous track (<<)
previous_requested = nil --reset flag
index = index - 1
if index < 1 then index = #track end
else
-- Next track (>>)
index = index + 1
if index > #track then index = 1 end
end
sound.play(track[index], nil, track_selection)
is_playing = true
end
end
On message
...
if message_id == hash("next_track") then
if is_playing then
sound.stop(track[index])
else
track_selection()
end
elseif message_id == hash("previous_track") then
if is_playing then
sound.stop(track[index])
else
previous_requested = true
track_selection()
end
elseif message_id == hash("toggle_music") then
if is_playing then
sound.pause(track[index], true)
is_playing = false
else
sound.pause(track[index], false)
is_playing = true
end
elseif message_id == hash("toggle_shuffle") then
is_shuffle = not is_shuffle -- toggle bool
elseif message_id == hash("toggle_repeat") then
is_repeating = not is_repeating -- toggle bool
end
...