Использование библиотеки пользовательского интерфейса при переборе таблицы в coronaSDK
В CoronaSDK я пытаюсь сделать определенный код, который создает множество кнопок и воспроизводит звуки для каждой из этих кнопок, более "эффективным", сначала создав таблицу строк, а затем создавая кнопки и обработчики, перебирая таблицу. Я использую общий файл "ui.lua" для создания кнопок. Однако я получаю (как минимум) две ошибки. Во-первых, fcn newButton говорит, что ожидает табличное значение для "по умолчанию". Вот код:
--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
Когда я изменяю значение по умолчанию на прямую строку, кнопки как минимум создаются и отображаются, как и ожидалось, на экране.
local thisInstrument = ui.newButton{
default = "images/snareDrum_btn.png",
onPress = playThis
}
Конечно, звук не воспроизводится, когда я нажимаю кнопку. Итак, два вопроса: во-первых, почему не работает простая ссылка на default = img? Во-вторых, как заставить слушателя работать для каждой новой кнопки?
1 ответ
Итак, я нашел ответ. Я сделал пару глупых ошибок новичка. Причина, по которой локальная переменная не работала, не имела никакого отношения к моему коду. Это было на самом деле, потому что я неправильно назвал пару файлов изображений (дох!).
Во-вторых, кнопка слушателя не работала, потому что (барабанная дробь...) я забыл загружать аудиофайлы заранее (двойной дох!). В итоге я решил разместить функцию playThis вне цикла, чтобы она не создавалась без необходимости. Вместо этого я установил свойство "sound" для созданных кнопок и использовал аргумент события, чтобы выяснить, какая кнопка была нажата, и воспроизвести соответствующий звук.
Вот окончательный код (я сделал его модульным, чтобы сделать его более пригодным для повторного использования). Надеюсь, это будет урок для других в проверке всей вашей среды, прежде чем ломать голову над вашим кодом.
--init globals
_H = display.contentHeight;
_W = display.contentWidth;
--test to see if I can more efficiently write code to do a repeated action by placing items inside an array and looping through the array
--import the ui file to create buttons
local ui = require("ui")
--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"}
--set constants to be able to set the x value of the buttons
local function doThis (event)
audio.play(event.target.property)
end
--loop through each item in the array to: (a) load the sound, (b) create a btn press event, and (c) create the button (the event must be created before the listener, else it has nothing to listen for)
local function makeBtns(btnList,btnImg,property,groupXPos,groupYPos)
--first, let's place all the buttons inside a button group, so we can move them together
local thisBtnGroup = display.newGroup();
for index,value in ipairs(btnList) do
--first, we use the value to make some reference strings
local img = "images/base_btn.png"
property = audio.loadSound("sounds/"..value..".wav")
--now create the button
local thisBtn = ui.newButton{
default = img,
onPress = doThis,
text = value,
size = 10
}
thisBtnGroup:insert(thisBtn)
thisBtn.x = (index -1) * thisBtn.width
thisBtn.property = property
end
thisBtnGroup.x = groupXPos; thisBtnGroup.y = groupYPos
return thisBtnGroup
end
local myBand = makeBtns(instruments,"images/base_btn.png","sound",_W/3,_H-50)