Сохранение значений в другой документ на Lua с помощью Corona SDK

Я пытаюсь сохранить рекорды в таблице всякий раз, когда вызывается функция gameOver.

Когда я возвращаюсь в приложение и пытаюсь прочитать рекорды (они отображаются как newText, где текст установлен на правильный рекорд уровня.).

Но он не делает то, что должен. Я могу читать рекорды уровней, но когда я пытаюсь изменить значения в таблице, текст рекордов не меняется.

У меня есть main.lua и myData.lua. Таблица рекордов должна быть помещена в myData.lua, чтобы до нее можно было добраться со всех уровней игры. это мой стол

highScores = {  
    1,
    2,
    3,
    4,
    5,
    6,
    7
}

и я пытался сохранить/изменить значение с помощью

highScores[1] = score

Где score — количество очков в игре.

Я понял, что это не тот способ, и то, что я могу найти в Google, кажется слишком сложным для того, что я считаю простой задачей.

Что я делаю неправильно?

Это весь мой level1.lua — фактический уровень, который запущен и пытается сохранить свой счет в таблице highScore level1.lua):

local composer = require( "composer" )
local scene = composer.newScene()
local myData = require( "myData" )
local physics = require("physics")
physics.setDrawMode( "hybrid" )
-- forward references
local w = display.actualContentWidth
local h = display.actualContentHeight
local dropCount = 0
local spawnShit = 0
local allowDrop = 1
local spawnTime = 17
local countdownTimer
local score
local gX = 0
local gY = 0
score = 0
local countDownNumber = 10
local gameOver

local scoreT = display.newText( {text="Score: "..score, font=system.nativeSystemFont, fontSize=14,} )
scoreT.x = w * 0.5
scoreT.y = h * 0.1

local countDownText = display.newText( {text="", font=system.nativeSystemFont, fontSize=14} )
countDownText.x = w * 0.5
countDownText.y = h * 0.2

local drop01 = display.newImage("drop01.png")
drop01.x = -100

local drop02 = display.newImage("drop02.png")
drop02.x = -100

local drop03 = display.newImage("drop03.png")
drop03.x = -100

local drop04 = display.newImage("drop04.png")
drop04.x = -100

local timerSpawn
local timer2

-- Display objects
local background = display.newImage( "bluebg.png" )
background.x = w*0.5
background.y = h*0.5
background.width = w 
background.height = h 

local bckBtn = display.newText({text="<--BACK", font=system.nativeSystemFont, fontSize=14})
bckBtn.x = 50
bckBtn.y = 20


local egon = display.newImage( "Egon.png" )
egon.x = w*0.5
egon.y = h*0.85
egon.width = 100
egon.height = 97

local destroyAll = display.newRect( 0, h, w, 10 )
destroyAll.width = w*2
destroyAll.alpha = 0

local overlayBg = display.newRect( -500, -500, w, h )
overlayBg:setFillColor( 0, 0, 0 )
overlayBg.alpha = 0.4

--functions

function gameOver ()
    if timerSpawn == nil then
    else
        timer.cancel(timerSpawn)
        timerSpawn = nil
        spawnShit = 0
    end
    if countdownTimer == nil then
    else
        timer.cancel(countdownTimer)
        countdownTimer = nil
    end
    highScores[1] = score
    transition.to( overlayBg, {x=w/2, y=h/2, time=500 } )
end

function goBack (event)
    if "began" == event.phase then
        gameOver()
        if timerSpawn == nil then
        else
            timer.cancel(timerSpawn)
        end
        if countdownTimer == nil then
        else
            timer.cancel(countdownTimer)
        end

    elseif event.phase == "ended" then 

        timer2 = timer.performWithDelay(1000, function()
            composer.gotoScene("select", "fade", 500)
        end)

        if overlayBg == nil then
        else
            overlayBg:removeSelf( )
        end

        return true
    end

    return true 
end

function moveEgon (event)
    if "moved" == event.phase then
        egon.x = event.x
    end

end 

------------------------------------------------vvv---------------------------------------------------
------------------------------------------------vvv---------------------------------------------------
------------------------------------------------vvv---------------------------------------------------
function spawnObjects (event)

    dropCount = math.random(1,4)

    --if stopTimer == 1 then
      --  timerSpawn = nil
        --spawnShit = nil
    --end
    if spawnShit == 1 then
        print( 'spawnShit' )
        if dropCount == 1 then
            -- Drop01 function and settings
            drop01 = display.newImage( "drop01.png" )
            drop01.x = math.random(10, 470)
            drop01.y = -40
            drop01.width = 50
            drop01.height = 50
            drop01.myName = "01"
            physics.addBody( drop01, "dynamic", {density=0.9, friction=0.1, bounce=0.8 } )

        elseif dropCount == 2 then 
            --Do shit for drop02
            drop02 = display.newImage( "drop02.png" )
            drop02.x = math.random(10, 470)
            drop02.y = -40
            drop02.width = 50
            drop02.height = 50
            drop02.myName = "02"
            physics.addBody( drop02, "dynamic", {density=0.9, friction=0.1, bounce=0.8 } )

        elseif dropCount == 3 then
            drop03 = display.newImage( "drop03.png" )
            drop03.x = math.random(10, 470)
            drop03.y = -40
            drop03.width = 50
            drop03.height = 50
            drop03.myName = "03"
            physics.addBody( drop03, "dynamic", {density=0.9, friction=0.1, bounce=0.8 } )

        elseif dropCount == 4 then
            drop04 = display.newImage( "drop04.png" )
            drop04.x = math.random(10, 470)
            drop04.y = -40
            drop04.width = 50
            drop04.height = 50
            drop04.myName = "04"
            physics.addBody( drop04, "dynamic", {density=0.9, friction=0.1, bounce=0.8 } )
        end
    end

    return true
end

---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------

function onCollision (event)

    if "began" == event.phase then
    --v--do shit when touching surface

        if event.other.myName == "01" then
            -- Do shit for drop01 -- 
            -- Change score, powersups etc
            event.other:removeSelf( )
            score = score+1
            countDownNumber = countDownNumber + 10
            scoreT.text = "Score: "..score
        end

        if event.other.myName == "02" then
            -- Do shit for drop02 -- 
            -- Change score, powersups etc
            event.other:removeSelf( )
            score = score+1
            scoreT.text = "Score: "..score
        end

        if event.other.myName == "03" then 
            -- Do shit for drop03 -- 
            -- Change score, powersups etc
            event.other:removeSelf( )
            score = score-1
            scoreT.text = "Score: "..score
        end

        if event.other.myName == "04" then
            -- Do shit for drop04 -- 
            -- Change score, powersups etc
            event.other:removeSelf( )
            score = score-1
            scoreT.text = "Score: "..score
        end

    elseif "ended" == event.phase then 
    -- Do shit when leaving surfaces
    end     

    return true

end

------------------------------------------------vvv---------------------------------------------------
------------------------------------------------vvv---------------------------------------------------
------------------------------------------------vvv---------------------------------------------------
function showCountDown (event)
    -- Condition to show and hide countdown
    if countDownNumber <= 1 or score == -1 then
        spawnShit = 0
        countDownNumber = 0
        timer.cancel(timerSpawn)
        timer.cancel(countdownTimer)
        countdownTimer = nil
        highScores[1] = score
        print( 'NO MORE SPAAAAAAAAAAAAAAAWWNS' )
    end

    if countDownNumber >= 1 then
        countDownNumber = countDownNumber -1 
        countDownText.text = countDownNumber
        spawnShit = 1
    end

    return true
end

---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------


function destroy (event)

    if "began" == event.phase then
        event.other:removeSelf( )
        else if "ended" == event.phase then 
        end
        return true
    end
end


--function scene:create( event )
function scene:create( event )
    local sceneGroup = self.view

    -- Initialize the scene here.
    -- Example: add display objects to "sceneGroup", add touch listeners, etc

    --Listeners

    background:addEventListener( "touch", moveEgon )
    bckBtn:addEventListener( "touch", goBack )
    egon:addEventListener( "collision", onCollision )
    destroyAll:addEventListener( "collision", destroy )

    --SceneGroup insert
    sceneGroup:insert( background )
    sceneGroup:insert(egon)
    sceneGroup:insert(bckBtn)
    sceneGroup:insert(drop01)
    sceneGroup:insert(drop02)
    sceneGroup:insert(drop03)
    sceneGroup:insert(drop04)
    sceneGroup:insert(scoreT)
    sceneGroup:insert(countDownText)
    sceneGroup:insert(overlayBg)
    sceneGroup:insert(destroyAll)

end


-- "scene:show()"
function scene:show( event )
    local sceneGroup = self.view
    local phase = event.phase

    if ( phase == "will" ) then
        -- Called when the scene is still off screen (but is about to come on screen).

    elseif ( phase == "did" ) then
        -- Called when the scene is now on screen.
        -- Insert code here to make the scene come alive.
        -- Example: start timers, begin animation, play audio, etc.
        physics.start( )
        gX = 0
        gY = 10
        physics.setGravity( gX, gY )
        timercount = 10
        spawnShit = 1
        score = 0
        scoreT.text = "Score: "..score

        -- ADD physic bodies ----
        physics.addBody( egon, "static", {density=0.1, friction=0.1, bounce=0.8 } )
        physics.addBody( destroyAll, "static", {density=0.1, friction=0.1, bounce=0.1 } )
        countDownNumber = 10
        if countdownTimer == nil then
            countdownTimer = timer.performWithDelay( 1000, showCountDown, 0 )
        else
        end

        ----------- Timers ------------
        if timerSpawn == nil then
            timerSpawn = timer.performWithDelay(500, spawnObjects, 0 )
        else 
        end

    end
end


-- "scene:hide()"
function scene:hide( event )

    local sceneGroup = self.view
    local phase = event.phase

    if ( phase == "will" ) then
        -- Called when the scene is on screen (but is about to go off screen).
        -- Insert code here to "pause" the scene.
        -- Example: stop timers, stop animation, stop audio, 
        --timer.pause( timerSpawn )
        physics.stop()
        spawnShit = nil
        score = nil
        timerSpawn = nil
        countdownTimer = nil
        overlayBg = nil

        --timer.cancel(timerSpawn)

        physics.removeBody( egon )

    elseif ( phase == "did" ) then
        -- Called immediately after scene goes off screen.
    end
end


-- "scene:destroy()"
function scene:destroy( event )
    local sceneGroup = self.view

    -- Called prior to the removal of scene's view ("sceneGroup").
    -- Insert code here to clean up the scene.
    -- Example: remove display objects, save state, etc.
    bckBtn:removeEventListener("touch", goBack )
    egon:removeEventListener("touch", moveEgon )
end



-- -------------------------------------------------------------------------------

-- Listener setup
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )

-- -------------------------------------------------------------------------------

return scene

person MNDevelopments    schedule 10.04.2014    source источник
comment
Я понимаю, что highScore находится в области действия функции gameOver, так как вы не получаете никаких ошибок индексации нулевого значения. Но уверены ли вы, что это таблица, которую вы хотите изменить, находится в области действия? Возможно, вы меняете другую highScore локальную таблицу? Возможно, вы захотите дать больше деталей, возможно, весь код?   -  person W.B.    schedule 10.04.2014
comment
Я могу попытаться опубликовать код, о котором идет речь, конечно. Я не получаю никаких ошибок, просто кажется, что таблица highScore сбрасывается до исходных значений.   -  person MNDevelopments    schedule 10.04.2014
comment
@В.Б. Я добавил ссылку для скачивания в свой файл level1.lua. Он содержит весь код, который я использую для этой цели.   -  person MNDevelopments    schedule 10.04.2014
comment
Что ж, давайте начнем сначала. Откуда вы знаете, что ваша оценка не назначена таблице? Как вы это проверяете? И что вы действительно хотите сделать - присвоить счет первому элементу таблицы (что вы и делаете сейчас) или поместить его в конец таблицы highScore?   -  person W.B.    schedule 10.04.2014
comment
Я использую экран выбора уровня с 7 уровнями с текстовым отображением, установленным на highScore[1], highScore[2] и так далее. Поэтому, когда я нахожусь на экране выбора уровня, я вижу уровень 1, уровень 2 и так далее. Когда я завершаю уровень 1, предполагается, что текст изменится с 1 на тот, который равен highScore[1]. И да, я пытаюсь присвоить его первому элементу, являющемуся highScore уровня 1, уровень для которого затем вызовет highScore[2]. Я новичок в Lua, поэтому я не уверен, что есть более простой способ сделать это, но мне нравится просто делать пробы и ошибки.   -  person MNDevelopments    schedule 10.04.2014
comment
@В.Б. Кстати, я также пытался объявить каждый уровень с highScore1 = 1 highScore2 = 2 и так далее.   -  person MNDevelopments    schedule 10.04.2014
comment
Вы так и не ответили на мой вопрос. Где и как вы проверяете, изменился ли счет? Я не видел других ваших файлов уровней, так что это полное предположение, но возможно ли, что каждый из файлов уровней содержит оператор require(myData)? Если это так, это будет означать, что каждый уровень загружает таблицу highScore = {"1", "2", ...} в глобальное пространство имен. Кроме того, какой фреймворк вы используете?   -  person W.B.    schedule 10.04.2014
comment
О, мой плохой. Я не проверяю изменение оценки, я могу только проверить, изменился ли отображающий ее текст. И да, вы правы, оба файла требуют (myData), не так ли? Можно ли вызывать значения из другого документа без? И я использую Corona SDK.   -  person MNDevelopments    schedule 10.04.2014
comment
Я изменил заголовок и теги на CoronaSDK, что плохо, что я не упомянул.   -  person MNDevelopments    schedule 10.04.2014
comment
Это именно проблема. Вы перезаписываете глобальный highScores каждый раз, когда загружается уровень. Вероятно, вам следует потребовать myData в main.lua, когда вы инициализируете свое приложение.   -  person W.B.    schedule 10.04.2014
comment
Пожалуйста, разместите код в своем вопросе: у меня нет доступа к этому сайту из-за ограничений безопасности в моей системе. Для форматирования: поместите код в notepad++ или другой текстовый редактор, замените все табы четырьмя пробелами, выберите все, сделайте отступ 4 пробела, скопируйте и вставьте в сообщение.   -  person Oliver    schedule 10.04.2014
comment
@В.Б. Если мне требуется только (myData) в main.lua, я получаю нулевое значение ошибки, когда открываю levelselect.   -  person MNDevelopments    schedule 10.04.2014
comment
@Schollii Я не могу разместить здесь свой код по какой-то причине (я думаю, это потому, что я использую много пробелов), код не форматируется должным образом. Так что почти нечитабельно. Я хотел бы опубликовать его на другом сайте загрузки или где-то еще, если у вас есть тот, который вы предпочитаете :)   -  person MNDevelopments    schedule 10.04.2014
comment
@MNDevelopments никогда не слышал о таком переформатировании. Вы заменили вкладки на 4 пробела?   -  person Oliver    schedule 10.04.2014
comment
Только что попробовал еще раз. Половина моего кода отображается за пределами кодовых полей. Это мои комментарии, запуск функций и некоторые мои форвардные ссылки тоже почему-то не работают.   -  person MNDevelopments    schedule 10.04.2014
comment
@MNDevelopments Просто убедитесь, что перед каждой строкой есть как минимум 4 пробела. Если код выглядит нормально в вашем редакторе и вы не используете вкладки, то он должен просто работать. Не стесняйтесь публиковать все испорченное, и я это исправлю.   -  person Oliver    schedule 11.04.2014
comment
@ScholliiI сделаю специальное редактирование для Schollii с любым испорченным синтаксисом, который он мне даст. Код большей части читабелен, просто много хлама без форматирования. Редактирую пост сейчас.   -  person MNDevelopments    schedule 11.04.2014
comment
Хорошо, добавив четыре пробела в каждую строку вручную, я получил ее для форматирования! Пиу.   -  person MNDevelopments    schedule 11.04.2014
comment
@MNDevelopments Я не знаю, почему это не работает. Должно. Альтернативным решением было бы создать таблицу и прикрепить ее к раскадровке. Таким образом, вы можете получить к нему доступ отовсюду. storyboard.highScores = {"1", "2", ...}. Тогда в ваших уровнях вы сможете получить к нему доступ таким же образом - через storyboard.highScores. Или лучше storyboard.globalState = {}, а потом storyboard.globalState.highScores = {"1", "2", ...}.   -  person W.B.    schedule 11.04.2014
comment
@В.Б. Хорошо, могу я по-прежнему использовать раскадровку, когда я использую композитор для обработки сцен? Но обязательно рассмотрю этот вариант. Также могу ли я быть проблемой симулятора? Я думаю, я мог бы портировать его на свой телефон завтра и посмотреть, исправит ли это.   -  person MNDevelopments    schedule 11.04.2014


Ответы (1)


Отлично. Баллы сохраняются. Проблема заключалась в том, как я отображал текст оценки, потому что он не перезагружался, а просто повторно использовал старое значение.

ИСПРАВЛЕНИЕ: я добавил

score01.text = highScore[1]

каждый раз, когда отображается сцена, и она автоматически обновляет счет, когда отображается экран выбора.

person MNDevelopments    schedule 13.04.2014