Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

Table problem when using to store sprite data - inconsistent error message

edited July 2012 in General Posts: 9

I'm learning Codea and Lua by making a simple game. Basically the code draws four sprites on the screen, when you touch the sprites it removes the sprite you touch. I am using a table to store information on the sprites (x,y coordinates). My problem is that I getting an error, but it is not consistent. I would say the error occurs 50-75% of the time.

Here's the code:

-- Multiple Sprites Test
-- testing to draw and remove sprites using meshes or tables
-- first testing using a table -- having issues with intermittent error

-- Use this function to perform your initial setup
function setup()
    rects = {}
    w,h = spriteSize("SpaceCute:Health Heart")
    
    for i = 1, 4 do
        rects[i] = {}
        rects[i].x = math.random(0, (WIDTH - 100))
        rects[i].y = math.random(0, (HEIGHT - 100))
        print(i,rects[i].x, rects[i].y)
    end
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    drawSprite()
end

function drawSprite()
    for i = 1, #rects do
        sprite("SpaceCute:Health Heart", rects[i].x,rects[i].y)
    end
end
        
function touched(touch)
    local TouchX = CurrentTouch.x
    local TouchY = CurrentTouch.y
    if touch.state == ENDED then
        for i = 1, #rects do
            if TouchX >= (rects[i].x - (w/2))and 
                TouchX <= (rects[i].x + (w/2)) and 
                TouchY >= (rects[i].y - (h/2)) and 
                TouchY <= (rects[i].y + (h/2)) then
                print(i)
                table.remove(rects,i)
            end
        end
    end
end

The error message I get is "error: attempt to index field '?' (a nil value)". It always points to this line "if TouchX >= (rects[i].x - (w/2))and" as the place in the code where the errors shows up. Codea pauses playback, but when I continue, the code removes the touched sprite and continues as expected. The error may or may not reoccur.

I just can't figure out what is wrong. I have read just about everything I was able to find on how to use Lua tables and everything in my code looks like it should be ok, especially since the program runs error free a good chunk of the time.

Any help is greatly appreciated!

Tagged:

Comments

  • SimeonSimeon Admin Mod
    edited July 2012 Posts: 5,054

    Your problem sits in your loop in touched:

            for i = 1, #rects do
                if TouchX >= (rects[i].x - (w/2))and 
                    TouchX <= (rects[i].x + (w/2)) and 
                    TouchY >= (rects[i].y - (h/2)) and 
                    TouchY <= (rects[i].y + (h/2)) then
                    print(i)
    
                    ---------------------------
                    -- This line is causing the issue
                    table.remove(rects,i) 
                    ---------------------------
    
                end
            end
    

    Because you are removing while iterating, you are later accessing rects[i] which no longer exists for those values of i.

    What you need to do is store your rects to-be-removed in a separate table when you process the touches. Then iterate the table of rects to-be-removed and remove them from the rects table.

  • SimeonSimeon Admin Mod
    edited July 2012 Posts: 5,054

    Here's a version that does the above:

    EDIT: I haven't tested this, I may have introduced more bugs :)

    function touched(touch)
        local TouchX = CurrentTouch.x
        local TouchY = CurrentTouch.y
        if touch.state == ENDED then
    
            local toRemove = {}
    
            for i = 1, #rects do
                if TouchX >= (rects[i].x - (w/2))and 
                    TouchX <= (rects[i].x + (w/2)) and 
                    TouchY >= (rects[i].y - (h/2)) and 
                    TouchY <= (rects[i].y + (h/2)) then
                    print(i)
                    table.insert(toRemove, i)
                end
            end
    
            for i = 1, #toRemove do
                    table.remove(rects,toRemove[i])
            end
        end
    end
    
  • Posts: 9

    Your code worked like a charm. There's always something to learn!

    Thank you! :)

Sign In or Register to comment.