In CoronaSDK, I’m trying to make a certain code that creates a lot of buttons and plays sounds for each of those buttons more “efficient” by first creating a table of strings and then creating the buttons and handlers by iterating over the table. I’m using the common “ui.lua” file to create buttons. However, I get (at least) two errors. The first is that the newButton fcn says it’s expecting a table value for “default.” Here’s the code:
--create the array. Note that these names will be used for all the objects that refer to these things, so you must have a consistent naming convention
local instruments = {"snare","piano1", "piano2","guitar1","guitar2","softPiano"}
--set constants to be able to set the x value of the buttons
local h = display.contentWidth/6-25;
local multiplier = 1
--loop through each item in the array to: (a) load the sound, (b) create a btn press event, and (c) create the button
for k,v in pairs(instruments) do
--first, we use the value to make some reference strings
img = "images/"..v.."_btn.png"
sound = "media/"..v..".wav"
--now create the event listener
local playThis = function (event)
audio.play(sound)
end
--now create the button
local thisInstrument = ui.newButton{
default = img,
onPress = playThis
}
thisInstrument.x = h*multiplier
thisInstrument.y = display.contentHeight * .8
multiplier = multiplier + 1
end
When I change the value of default to a straight up string, the buttons are at least created and displayed as expected across the screen.
local thisInstrument = ui.newButton{
default = "images/snareDrum_btn.png",
onPress = playThis
}
Of course, the sound still doesn’t play when I click a button. So, two questions: First, why won’t a simple reference to default = img work? Second, how do I get the listener to work for each new button?
Ok, so I found the answer. I made a couple of stupid rookie mistakes. The reason the local variable wasn’t working had nothing to do with my code. It was actually because I had misnamed a couple of the image files (doh!).
Second, the button listener wasn’t working because (drumroll…) I had forgotten to load the audio files ahead of time (double doh!). I ended up deciding to place the playThis function outside the loop so that it wasn’t being recreated unnecessarily. Instead, I set a “sound” property on the created buttons and used the event argument to figure out which button was pushed and play the corresponding sound.
Here’s the final code (I’ve modularized it to make it more re-usable). Hopefully, this’ll be a lesson for others in checking your entire environment before banging your head about your code.