Использование библиотеки пользовательского интерфейса при переборе таблицы в 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)
Другие вопросы по тегам