简体   繁体   中英

attempt to concatenate field ' ?' (a nil value) corona SDK

hey i'm newbie both in corona and lua, i'm making a little memory game for a school project but i keep getting the error with the concatenation for a nill value, it shows the elements from the concatenation in the screen but it dosn't work

heres my code:

display.setStatusBar(display.HiddenStatusBar)
centerX=display.contentCenterX
centerY=display.contentCenterY
screenX=display.screenOriginX
screenY=display.screenOriginY
screenWidth=display.contentWidth-screenX * 1
screenHeight=display.contentHeight - screenY *1
screenLeft=screenX
screenRight=screenX + screenWidth
screenTop=screenY
screenBottom=screenY+screenHeight
display.contentWidht=screenWidth
display.contentHeight=screenHeight

display.cl=display.CenterLeftReferencePoint
local tileImg="images/lolo.png"
local hiddenObjects={
"cubo", "abeja", "mariposa", "flor",
"cubo", "abeja", "mariposa", "flor"}



local tileWidth=100
local tileHeigth=100
local tileAcross=6
local tileDown=4
local tileSpacing=2
local topSpacing=screenTop+tileHeigth+tileSpacing
local leftSpacing = screenLeft+tileWidth+tileSpacing

local numMatches=0
local numObjsShowing=0
local flipped={}
local pauseDelay=800
local score=0
local scoreTxt=nil

local allTiles={}
local allThings={}


local resetGame


local function shuffle(t) 
    local n= #t
    while n > 2 do
    local k = math.random(n)
    t[n], t[k] = t[k], t[n]
    n = n-1
    end
    return t
end
 local function killObj( obj)
    display.remove( obj )
    obj = nil
 -- body
 end 

 local function startOver() 
    local msg
    local function start(event)
        killObj(event.target)
        resetGame()
        -- body
    end 
    msg=display.newText("Tap Here To Start", 0, 0, "Helvetica", 24)
    msg.x=centerX
    msg.y=centerY+250
    msg:addEventListener("tap", start)
end
local function addToScore( addNum )
    local num = addNum or 100
    score = score +num
    scoreTxt:setReferencePoint(display.cl)
    scoreTxt.x = screenWidth+250
    -- body
end

local function checkForMatch()
    if #flipped== 2 then
        local idx1,idx2=flipped[1],flipped[2]
        local function resetNumObjsShowing()
            numObjsShowing=0

        end
        if allThings[idx1].name==allThings[idx2].name then
            audio.play(sndMatch)
            allThings[idx1]:toFront()
            allThings[idx2]:toFront()
            transition.to(allThings[idx1],{time=400, x=screenRight,                       y=screenTop, alpha=0})
            transition.to(allThings[idx2],{time=400, x=screenRight, y=screenTop, alpha=0})
            addToScore(100)
            resetNumObjsShowing()
            numMatches=numMatches+1
            if numMatches==(tileAcross * tileDown / 2) then
                audio.play(sndWinner)
                startOver()
            end
        else
            audio.play(sndNoMatch)
            transition.to(allTiles[idx1],{delay=pauseDelay, time=200,alpha=1, onComplete=resetNumObjsShowing})
            transition.to(allTiles[idx2],{delay=pauseDelay, time=200,alpha=1,})
            if score> 20 then
                addToScore(-20)
            end
    end

    flipped[1]=nil
    flipped[2]=nil
end
end

local function  tileTapped(event)
    if numObjsShowing< 2 then
        local tile=event.target
        if flipped[numObjsShowing]~=tile.idx then
            numObjsShowing=numObjsShowing+1
            flipped[numObjsShowing]=tile.idx
            transition.to(tile,{time=500,alpha=0,onComplete=checkForMatch})
        end
    end
end

local function makeTiles(things)
    local idx=1
    for x = 1, tileAcross do
        for y = 1, tileDown do
            local thing = display.newImage("images/" ..things[idx].. ".png")
            thing.x=(x+1.5)*(tileWidth + tileSpacing)+ leftSpacing
            thing.y=(y+0.9)*(tileHeigth + tileSpacing)+ topSpacing
            thing.name=things[idx]
            allThings[#allThings+1]=thing

            local tile = display.newImage(tileImg)
            tile.x =(x+1) * (tileWidth + tileSpacing)+ leftSpacing
            tile.y =(y+1) * (tileHeigth + tileSpacing)+ topSpacing
            tile.idx=idx
            tile:addEventListener("tap", tileTapped)
            allTiles[#allTiles+1]=tile

            idx=idx+1
        end
    end
end

function resetGame()
    numMatches= 0
    numObjsShowing = 0
    score = 0
    scoreTxt.text ="score: 000"
    flipped[1]=nil
    flipped[2]=nil

    if allThings ~={} then
        for x=#allThings, 1, -1 do
            killObj(allThings[x])
        end

        allThings={}
    -- body
end
if allTiles ~={} then
    for x=#allTiles,1,-1 do
        killObj(allTiles[x])
end
allTiles={}
end
makeTiles(shuffle(hiddenObjects))
end 

local function setupDisplay()
local bg=display.newImage("images/paisaje1.jpg")
bg.x=centerX
bg.y=centerY
bg.width=screenWidth
bg.height=screenHeight

scoreTxt = display.newText("Score: 000", 0, 0, "Helvetica", 18)
scoreTxt.x=screenWidth-120
scoreTxt.y=screenTop+15
end
setupDisplay()
startOver()

any suggestion is welcome

The only concatenation in the code occurs in this line:

local thing = display.newImage("images/" ..things[idx].. ".png")

So, it appears that things[idx] is nil.

The index value idx in the makeTiles() function is being incremented at the end of the inner loop, so after a couple of iterations of the outer loop, idx is referencing nil values in things , since #things is 8 .

One possible fix is to use the modulus operator to keep idx between 1 and 8 :

idx=(idx % 8) + 1

This will cycle through the shuffled table repeatedly. You could also call shuffle again on things when idx is reset to 1 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM