Strategy Game Style Movement

(Not the colon, the two periods) @.@

@Kempoman - the two periods mean append (concatenate, join), so we are appending “Planet Cute:” to each image name. It just saves you the trouble of having to put Planet:Cute in front of every name. But seeing as you already have the names with this in front, perhaps I shouldn’t have bothered making it separate!

I wrote a Lua ebook that may help your boy, here
https://www.dropbox.com/s/qh1e7ft4rvhlpt2/Lua%20for%20beginners.pdf

lots of codea tutorials here, some of the early ones are quite easy
https://coolcodea.wordpress.com/2013/06/19/index-of-posts/

Also, if he likes the Matrix, he will like this project
https://coolcodea.wordpress.com/2013/06/13/83-a-bit-of-fun-the-matrix-effect/

Thanks. I’ve actually read the ebook and done the first 8 tutorials or so. I will start him on that stuff soon.

Haven’t quite got the new concatenated moveSprite.chars table working yet. What is the reason for adding .chars? Thanks again.

Kempoman - if you are going to implement astar pathfinding I would have a walkable table for movement, and have each object keep track of it’s own coordinates. When moving just loop all active objects and check their position for a match and key off the tileType found.

@Kempoman - the reason for adding a list of all the character names in moveSprite.chars, is that then your draw function becomes

function moveSprite:draw()
    sprite(moveSprite.chars[self.i], self.pos.x, self.pos.y)
end

much simpler!

Yes I get that. So “.chars” doesn’t do anything. Just part of the name of the table?

@Kempoman - chars is just another property, like .x or .y, except that it happens to be a table itself. I put moveSprite in front so that chars is part of the moveSprite class, but you could just call it chars if you like.

Ok, I thought this was too funny not to share: Spent a long time trying to debug my code and it turns out the bug I was looking for was an actual bug! It was the enemy bug that I had separate so I could tint it. Whew.

Hi everybody! Sorry about the joke. I have been busy transitioning everything to tables. So far I am able to make a key disappear when an avatar walks over it and insert “key” into its inventory.

When an avatar walks on a tree, bush, etc., that avatar lifts it. However, I can’t get them to carry it when when they walk away. I really appreciate any help!

Cat girl is prevented from escaping by ellipses drawn behind the background sprite. Is this an efficient way to accomplish this?

Also, I don’t have a retina display. Everything lines up nicely on my screen. Does it look different on a retina display? Thx. Code below.


--# Main

-- Table Hell

    
displayMode(FULLSCREEN)
supportedOrientations(CurrentOrientation)

function setup()
    
    SA=3 --Selected Avatar right now
    SO=0 --Selected thing to throw
    sw=50 --Starting point
    sh=10
    iw=100 --Width of sprite
    ih=171
    dx=100 --Change in x
    dy=86

    avatars={}
    avatars[1]={img="Planet Cute:Character Horn Girl",x=1*dx-sw,y=4*dy+sh,inventory={}}
    avatars[2]={img="Planet Cute:Character Pink Girl",x=9*dx-sw,y=4*dy+sh,inventory={}}
    avatars[3]={img="Planet Cute:Character Cat Girl",x=2*dx-sw,y=8*dy+sh,inventory={}}
    avatars[4]={img="Planet Cute:Character Princess Girl",x=10*dx-sw,y=3*dy+sh,inventory={}}
    avatars[5]={img="Planet Cute:Character Boy",x=10*dx-sw,y=2*dy+sh,inventory={}}
    
    keys={}
    keys[1]={img="Planet Cute:Key",x=9*dx-sw,y=1*dy+sh}
    keys[2]={img="Planet Cute:Key",x=1*dx-sw,y=1*dy+sh}
    
    bugs={}
    bugs[1]={img="Planet Cute:Enemy Bug",x=2*dx-sw,y=1*dy+sh}
    bugs[2]={img="Planet Cute:Enemy Bug",x=6*dx-sw,y=7*dy+sh}
    
    doors={}
    doors[1]={img="Planet Cute:Door Tall Closed",x=150,y=510}
    
    throwThings={}
    throwThings[1]={img="Planet Cute:Rock",x=8*dx-sw,y=1*dy+sh}
    throwThings[2]={img="Planet Cute:Tree Tall",x=10*dx-sw,y=1*dy+sh}
    throwThings[3]={img="Planet Cute:Tree Tall",x=1*dx-sw,y=2*dy+sh}
    throwThings[4]={img="Planet Cute:Tree Tall",x=2*dx-sw,y=2*dy+sh}
    throwThings[5]={img="Planet Cute:Tree Tall",x=9*dx-sw,y=3*dy+sh}
    throwThings[6]={img="Planet Cute:Tree Tall",x=1*dx-sw,y=5*dy+sh}
    throwThings[7]={img="Planet Cute:Tree Tall",x=3*dx-sw,y=5*dy+sh}
    throwThings[8]={img="Planet Cute:Tree Short",x=8*dx-sw,y=6*dy+sh}
    throwThings[9]={img="Planet Cute:Tree Short",x=5*dx-sw,y=6*dy+sh}
    throwThings[10]={img="Planet Cute:Tree Short",x=8*dx-sw,y=8*dy+sh}
    throwThings[11]={img="Planet Cute:Tree Short",x=5*dx-sw,y=8*dy+sh}
    throwThings[12]={img="Planet Cute:Tree Ugly",x=7*dx-sw,y=3*dy+sh}
    throwThings[13]={img="Planet Cute:Tree Ugly",x=7*dx-sw,y=2*dy+sh}
    throwThings[14]={img="Planet Cute:Tree Ugly",x=8*dx-sw,y=3*dy+sh}
    
    ells={}
    ells[1]={x=1*dx-sw,y=6*dy+sh,w=iw,h=ih}
    ells[2]={x=1*dx-sw,y=7*dy+sh,w=iw,h=ih}
    ells[3]={x=1*dx-sw,y=8*dy+sh,w=iw,h=ih}
    ells[4]={x=1*dx-sw,y=9*dy+sh,w=iw,h=ih}
    ells[5]={x=2*dx-sw,y=9*dy+sh,w=iw,h=ih}
    ells[6]={x=3*dx-sw,y=9*dy+sh,w=iw,h=ih}
    ells[7]={x=3*dx-sw,y=8*dy+sh,w=iw,h=ih}
    ells[8]={x=3*dx-sw,y=7*dy+sh,w=iw,h=ih}
    ells[9]={x=3*dx-sw,y=6*dy+sh,w=iw,h=ih}
    ells[10]={x=2*dx-sw,y=6*dy+sh,w=iw,h=ih}
    
end

function removeSprites()    -- remove sprite when character is over it
    for z=1,#keys do
        if avatars[SA].x>keys[z].x-30 and avatars[SA].x<keys[z].x+30 and avatars[SA].y>keys[z].y-30 and avatars[SA].y<keys[z].y+30 then
            table.remove(keys,z)
            table.insert(avatars[SA].inventory,"key")
            for k=1,#avatars[SA].inventory do
                print(avatars[SA].inventory[k])
            end
            return
        end
    end
    for z=1,#throwThings do -- Lift a throwable thing when selected avatar is on same tile
        if avatars[SA].x>throwThings[z].x-30 and avatars[SA].x<throwThings[z].x+30 and avatars[SA].y>throwThings[z].y-30 and avatars[SA].y<throwThings[z].y+30 then
            throwThings[z].x,throwThings[z].y=avatars[SA].x,avatars[SA].y+50
            table.insert(avatars[SA].inventory,"throwThing")
            for z=1, #avatars[SA].inventory do
               print(avatars[SA].inventory[z])
            end
            SO=z
        end
    end
end

function draw()
    background(6, 223, 252, 255)
    
    for i = 1, table.maxn(ells, i) do
        ellipse(ells[i].x,ells[i].y,ells[i].w,ells[i].h)
    end
    
    sprite("Documents:Level1Map",WIDTH/2,HEIGHT/2) -- Contains Grass, water, dirt, sky.

    for i = 1, table.maxn(avatars, i) do
        sprite(avatars[i].img,avatars[i].x,avatars[i].y)
    end
    
    for i = 1, table.maxn(keys, i) do
        sprite(keys[i].img,keys[i].x,keys[i].y)
    end
    
    for i = 1, table.maxn(bugs, i) do
        sprite(bugs[i].img,bugs[i].x,bugs[i].y)
    end
    
    for i = 1, table.maxn(doors, i) do
        sprite(doors[i].img,doors[i].x,doors[i].y)
    end
    
    for i = 1, table.maxn(throwThings, i) do
        sprite(throwThings[i].img,throwThings[i].x,throwThings[i].y)
    end
end

function touched(touch)
    local id = touch.id
    local state = touch.state
    local x = touch.x
    local y = touch.y
    if state == BEGAN then
        swipeId = id  -- Preserve the id
        swipeX = x    -- Preserve the position
        swipeY = y    -- Preserve the position
        return
    end
    if state == ENDED and id == swipeId then
        swipeId = nil
        if math.abs(x - swipeX) < 100 then -- Within tolerance?
            if swipeY - y > 100 then       -- Long enough?
                print("Swipe down")
                moveAvatar(SA,0,-dy)
                moveThrowThings(SO,0,-dy)
            end
            if y - swipeY > 100 then       -- Long enough?
                print("Swipe up")
                moveAvatar(SA,0,dy)
                moveThrowThings(SO,0,dy)
            end
        end
        if math.abs(y - swipeY) < 100 then
            if swipeX - x > 100 then
                print("Swipe Left")
                moveAvatar(SA,-dx,0)
                moveThrowThings(SO,-dx,0)
            end
            if x - swipeX > 100 then
                print ("Swipe Right")
                moveAvatar(SA,dx,0)
                moveThrowThings(SO,dx,0)
            end
        end
    end

    if state==ENDED then --Select an Avatar
        for k,v in pairs(avatars) do -- Iterate through avatars table in pairs
            if x>v.x-30 and x<v.x+30 and y>v.y-30 and y<v.y+30 then -- Defines tap select area
                SA=k -- Selected Avatar = id number
            end
        end
    end
end

function screenEdges()
        -- Tells currently selected avatar (SA) to go back to edge of screen when it passes the invisible edges set at w, h, WIDTH, and HEIGHT.
    if avatars[SA].x < sw then avatars[SA].x = 1*dx-sw 
    elseif avatars[SA].x > WIDTH then avatars[SA].x = 10*dx-sw end
    if avatars[SA].y < ih then avatars[SA].y = 1*dy+sh
    elseif avatars[SA].y > HEIGHT then avatars[SA].y = 8*dy+sh end
end

function moveAvatar(SA,dx,dy)
    local newX, newY = avatars[SA].x+dx, avatars[SA].y+dy -- Temporary new positions.
    for k,v in pairs(avatars) do
        if v.x==newX and v.y==newY then -- If true, we have a clash with avatars.
            return -- Don't move, we have a clash.
        end
    end
    for k,v in pairs(ells) do
        if v.x==newX and v.y==newY then
            return
        end
    end
    
    -- if we got this far, there are no clashes, make the move.
    avatars[SA].x,avatars[SA].y=avatars[SA].x+dx,avatars[SA].y+dy
   
    removeSprites() 
    
    screenEdges()
    
    print(avatars[SA].x,avatars[SA].y)
end

function moveThrowThings(SO,dx,dy)
    if avatars[SA].inventory=="throwThing" then
        print("moveit")
        throwThings[SO].x,throwThings[SO].y=throwThings[SO].x+dx,throwThings[SO].y+dy
    end
end






@Kempoman - you can take the bush with the character if you include the bush in the character’s inventory table,and check for that when you draw. You can then adjust the x,y position of the bush (in ThrowThings) so when it is drawn afterwards it is in the right place.

The ellipses aren’t very obvious barriers, perhaps stone blocks or something might be better

(for anyone else who plays with this, you need to press on a character and then swipe, to move them)

removeSprites and moveThrowThings functions are supposed to change the x,y position but I can’t get them to work. (I also put some code in the swipe function) The avatar “picks up the bush” but it doesn’t follow him despite my attempts to change the x,y in throwThings. ActUally I was successful in changing the y to pick it up, but the other part isn’t working.

The ellipses are invisible (behind the background sprite), because the walls are not individual sprites, but part of the background. (I was trying to draw less sprites, at least for now.) but then I ended up having to draw ellipses ehhhh.

Sorry for being such a pest. Any help would be great. Thanks.

Are you saying include the actual sprite in the inventory table or just a word that represents that the avatar ‘has it’ as I have tried to do?

@Kempoman, first thing, you are going to want to moveThrowThings before moveAvatar, so the object is not moved the instant it is picked up. See code below:

    if state == ENDED and id == swipeId then
        swipeId = nil
        if math.abs(x - swipeX) < 100 then -- Within tolerance?
            if swipeY - y > 100 then       -- Long enough?
                print("Swipe down")
                moveThrowThings(SO,0,-dy)
                moveAvatar(SA,0,-dy)
            end
            if y - swipeY > 100 then       -- Long enough?
                print("Swipe up")
                moveThrowThings(SO,0,dy)
                moveAvatar(SA,0,dy)
            end
        end
        if math.abs(y - swipeY) < 100 then
            if swipeX - x > 100 then
                print("Swipe Left")
                moveThrowThings(SO,-dx,0)
                moveAvatar(SA,-dx,0)
            end
            if x - swipeX > 100 then
                print ("Swipe Right")
                moveThrowThings(SO,dx,0)
                moveAvatar(SA,dx,0)
            end
        end
    end

Second, instead of storing the word “key” or “throwThing”, store the index of the item. See code below:

function removeSprites()    -- remove sprite when character is over it
    for z=1,#keys do
        if avatars[SA].x>keys[z].x-30 and avatars[SA].x<keys[z].x+30 and avatars[SA].y>keys[z].y-30 and avatars[SA].y<keys[z].y+30 then
            table.remove(keys,z)
            table.insert(avatars[SA].inventory, z)
            for k=1,#avatars[SA].inventory do
                print(avatars[SA].inventory[k])
            end
            return
        end
    end
    for z=1,#throwThings do -- Lift a throwable thing when selected avatar is on same tile
        if avatars[SA].x>throwThings[z].x-30 and avatars[SA].x<throwThings[z].x+30 and avatars[SA].y>throwThings[z].y-30 and avatars[SA].y<throwThings[z].y+30 then
            throwThings[z].x,throwThings[z].y=avatars[SA].x,avatars[SA].y+50
            table.insert(avatars[SA].inventory, z)
            for z=1, #avatars[SA].inventory do
               print(avatars[SA].inventory[z])
            end
            SO=z
        end
    end
end

Finally, now that we use the index, we need to change the test. See code below:

function moveThrowThings(SO,dx,dy)
    if avatars[SA].inventory[1] == SO then
        print("moveit")
        throwThings[SO].x,throwThings[SO].y=throwThings[SO].x+dx,throwThings[SO].y+dy
    end
end

Currently, the code above only works if you pick up a bush first. I recommend leaving inventory just for keys and make a new variable for bushes. The new variable doesn’t have to be a table, just a simple integer since I assume you can only pick up one bush at a time.

Edit: you could also keep the inventory table for both and instead of using table.insert use inventory[1] to store bush index and inventory[2] to store number of keys collected.

@Kempoman, I decided to just write the rest of the code for you. This is what I have:


--# Main

-- Table Hell


displayMode(FULLSCREEN)
supportedOrientations(CurrentOrientation)

function setup()

    SA=3 --Selected Avatar right now
    sw=50 --Starting point
    sh=10
    iw=100 --Width of sprite
    ih=171
    dx=100 --Change in x
    dy=86

    avatars={}
    avatars[1]={img="Planet Cute:Character Horn Girl",x=1*dx-sw,y=4*dy+sh,inventory={}}
    avatars[2]={img="Planet Cute:Character Pink Girl",x=9*dx-sw,y=4*dy+sh,inventory={}}
    avatars[3]={img="Planet Cute:Character Cat Girl",x=2*dx-sw,y=8*dy+sh,inventory={}}
    avatars[4]={img="Planet Cute:Character Princess Girl",x=10*dx-sw,y=3*dy+sh,inventory={}}
    avatars[5]={img="Planet Cute:Character Boy",x=10*dx-sw,y=2*dy+sh,inventory={}}

    keys={}
    keys[1]={img="Planet Cute:Key",x=9*dx-sw,y=1*dy+sh}
    keys[2]={img="Planet Cute:Key",x=1*dx-sw,y=1*dy+sh}

    bugs={}
    bugs[1]={img="Planet Cute:Enemy Bug",x=2*dx-sw,y=1*dy+sh}
    bugs[2]={img="Planet Cute:Enemy Bug",x=6*dx-sw,y=7*dy+sh}

    doors={}
    doors[1]={img="Planet Cute:Door Tall Closed",x=150,y=510}

    throwThings={}
    throwThings[1]={img="Planet Cute:Rock",x=8*dx-sw,y=1*dy+sh}
    throwThings[2]={img="Planet Cute:Tree Tall",x=10*dx-sw,y=1*dy+sh}
    throwThings[3]={img="Planet Cute:Tree Tall",x=1*dx-sw,y=2*dy+sh}
    throwThings[4]={img="Planet Cute:Tree Tall",x=2*dx-sw,y=2*dy+sh}
    throwThings[5]={img="Planet Cute:Tree Tall",x=9*dx-sw,y=3*dy+sh}
    throwThings[6]={img="Planet Cute:Tree Tall",x=1*dx-sw,y=5*dy+sh}
    throwThings[7]={img="Planet Cute:Tree Tall",x=3*dx-sw,y=5*dy+sh}
    throwThings[8]={img="Planet Cute:Tree Short",x=8*dx-sw,y=6*dy+sh}
    throwThings[9]={img="Planet Cute:Tree Short",x=5*dx-sw,y=6*dy+sh}
    throwThings[10]={img="Planet Cute:Tree Short",x=8*dx-sw,y=8*dy+sh}
    throwThings[11]={img="Planet Cute:Tree Short",x=5*dx-sw,y=8*dy+sh}
    throwThings[12]={img="Planet Cute:Tree Ugly",x=7*dx-sw,y=3*dy+sh}
    throwThings[13]={img="Planet Cute:Tree Ugly",x=7*dx-sw,y=2*dy+sh}
    throwThings[14]={img="Planet Cute:Tree Ugly",x=8*dx-sw,y=3*dy+sh}

    ells={}
    ells[1]={x=1*dx-sw,y=6*dy+sh,w=iw,h=ih}
    ells[2]={x=1*dx-sw,y=7*dy+sh,w=iw,h=ih}
    ells[3]={x=1*dx-sw,y=8*dy+sh,w=iw,h=ih}
    ells[4]={x=1*dx-sw,y=9*dy+sh,w=iw,h=ih}
    ells[5]={x=2*dx-sw,y=9*dy+sh,w=iw,h=ih}
    ells[6]={x=3*dx-sw,y=9*dy+sh,w=iw,h=ih}
    ells[7]={x=3*dx-sw,y=8*dy+sh,w=iw,h=ih}
    ells[8]={x=3*dx-sw,y=7*dy+sh,w=iw,h=ih}
    ells[9]={x=3*dx-sw,y=6*dy+sh,w=iw,h=ih}
    ells[10]={x=2*dx-sw,y=6*dy+sh,w=iw,h=ih}

end

function removeSprites()    -- remove sprite when character is over it
    for z=1,#keys do
        if avatars[SA].x>keys[z].x-30 and avatars[SA].x<keys[z].x+30 and avatars[SA].y>keys[z].y-30 and avatars[SA].y<keys[z].y+30 then
            table.remove(keys,z)
            if avatars[SA].inventory[1] == nil then
                avatars[SA].inventory[1] = 1
            else
                avatars[SA].inventory[1] = avatars[SA].inventory[1] + 1
            end
            return
        end
    end
    for z=1,#throwThings do -- Lift a throwable thing when selected avatar is on same tile
        if avatars[SA].x>throwThings[z].x-30 and avatars[SA].x<throwThings[z].x+30 and avatars[SA].y>throwThings[z].y-30 and avatars[SA].y<throwThings[z].y+30 then
            if avatars[SA].inventory[2] ~= nil then
                throwThings[avatars[SA].inventory[2]].y = throwThings[avatars[SA].inventory[2]].y - 50
            end
            throwThings[z].y = throwThings[z].y + 50
            avatars[SA].inventory[2] = z
        end
    end
end

function draw()
    background(6, 223, 252, 255)

    for i = 1, table.maxn(ells, i) do
        ellipse(ells[i].x,ells[i].y,ells[i].w,ells[i].h)
    end

    --sprite("Documents:Level1Map",WIDTH/2,HEIGHT/2) -- Contains Grass, water, dirt, sky.

    for i = 1, table.maxn(avatars, i) do
        sprite(avatars[i].img,avatars[i].x,avatars[i].y)
    end

    for i = 1, table.maxn(keys, i) do
        sprite(keys[i].img,keys[i].x,keys[i].y)
    end

    for i = 1, table.maxn(bugs, i) do
        sprite(bugs[i].img,bugs[i].x,bugs[i].y)
    end

    for i = 1, table.maxn(doors, i) do
        sprite(doors[i].img,doors[i].x,doors[i].y)
    end

    for i = 1, table.maxn(throwThings, i) do
        sprite(throwThings[i].img,throwThings[i].x,throwThings[i].y)
    end
end

function touched(touch)
    local id = touch.id
    local state = touch.state
    local x = touch.x
    local y = touch.y
    if state == BEGAN then
        swipeId = id  -- Preserve the id
        swipeX = x    -- Preserve the position
        swipeY = y    -- Preserve the position
        return
    end
    if state == ENDED and id == swipeId then
        swipeId = nil
        if math.abs(x - swipeX) < 100 then -- Within tolerance?
            if swipeY - y > 100 then       -- Long enough?
                print("Swipe down")
                if avatars[SA].inventory[2] ~= nil then
                    moveThrowThings(avatars[SA].inventory[2],0,-dy)
                end
                moveAvatar(SA,0,-dy)
            end
            if y - swipeY > 100 then       -- Long enough?
                print("Swipe up")
                if avatars[SA].inventory[2] ~= nil then
                    moveThrowThings(avatars[SA].inventory[2],0,dy)
                end
                moveAvatar(SA,0,dy)
            end
        end
        if math.abs(y - swipeY) < 100 then
            if swipeX - x > 100 then
                print("Swipe Left")
                if avatars[SA].inventory[2] ~= nil then
                    moveThrowThings(avatars[SA].inventory[2],-dx,0)
                end
                moveAvatar(SA,-dx,0)
            end
            if x - swipeX > 100 then
                print ("Swipe Right")
                if avatars[SA].inventory[2] ~= nil then
                    moveThrowThings(avatars[SA].inventory[2],dx,0)
                end
                moveAvatar(SA,dx,0)
            end
        end
    end

    if state==ENDED then --Select an Avatar
        for k,v in pairs(avatars) do -- Iterate through avatars table in pairs
            if x>v.x-30 and x<v.x+30 and y>v.y-30 and y<v.y+30 then -- Defines tap select area
                SA=k -- Selected Avatar = id number
            end
        end
    end
end

function screenEdges()
        -- Tells currently selected avatar (SA) to go back to edge of screen when it passes the invisible edges set at w, h, WIDTH, and HEIGHT.
    if avatars[SA].x < sw then avatars[SA].x = 1*dx-sw 
    elseif avatars[SA].x > WIDTH then avatars[SA].x = 10*dx-sw end
    if avatars[SA].y < ih then avatars[SA].y = 1*dy+sh
    elseif avatars[SA].y > HEIGHT then avatars[SA].y = 8*dy+sh end
end

function moveAvatar(SA,dx,dy)
    local newX, newY = avatars[SA].x+dx, avatars[SA].y+dy -- Temporary new positions.
    for k,v in pairs(avatars) do
        if v.x==newX and v.y==newY then -- If true, we have a clash with avatars.
            return -- Don't move, we have a clash.
        end
    end
    for k,v in pairs(ells) do
        if v.x==newX and v.y==newY then
            return
        end
    end

    -- if we got this far, there are no clashes, make the move.
    avatars[SA].x,avatars[SA].y=avatars[SA].x+dx,avatars[SA].y+dy

    removeSprites() 

    screenEdges()

    print(avatars[SA].x,avatars[SA].y)
end

function moveThrowThings(SO,dx,dy)
    if avatars[SA].inventory[2] == SO then
        print("moveit")
        throwThings[SO].x,throwThings[SO].y=throwThings[SO].x+dx,throwThings[SO].y+dy
    end
end

I had to comment out your Level1Map since I don’t have that image.

Edit: Just a word of advice, when utilizing tables to store your objects, you always want to store the index of the object in tables such as an inventory. This makes for a quick and efficient reference. Because of this, you no longer need the SO global variable as the selected object’s index is referenced like this: avatars[SA].inventory[2]

Sorry about that! I forgot that no one else can see the sprite background.

Thanks a lot @shlashin8r! I’m beginning to understand it more. I noticed that when the selected avatar gets close to another avatar, it ‘throws’ the object and then can’t get it back again. Maybe because of the SO variable? I’ll try and figure it out. Thanks again!

@Kempoman, I rewrote your for loops to iterate through the tables more efficiently. Also moved the moveThrowThings call into the move function. See code below:

--# Main

-- Table Hell


displayMode(FULLSCREEN)
supportedOrientations(CurrentOrientation)

function setup()

    SA=3 --Selected Avatar right now
    sw=50 --Starting point
    sh=10
    iw=100 --Width of sprite
    ih=171
    dx=100 --Change in x
    dy=86

    avatars={}
    avatars[1]={img="Planet Cute:Character Horn Girl",x=1*dx-sw,y=4*dy+sh,inventory={}}
    avatars[2]={img="Planet Cute:Character Pink Girl",x=9*dx-sw,y=4*dy+sh,inventory={}}
    avatars[3]={img="Planet Cute:Character Cat Girl",x=2*dx-sw,y=8*dy+sh,inventory={}}
    avatars[4]={img="Planet Cute:Character Princess Girl",x=10*dx-sw,y=3*dy+sh,inventory={}}
    avatars[5]={img="Planet Cute:Character Boy",x=10*dx-sw,y=2*dy+sh,inventory={}}

    keys={}
    keys[1]={img="Planet Cute:Key",x=9*dx-sw,y=1*dy+sh}
    keys[2]={img="Planet Cute:Key",x=1*dx-sw,y=1*dy+sh}

    bugs={}
    bugs[1]={img="Planet Cute:Enemy Bug",x=2*dx-sw,y=1*dy+sh}
    bugs[2]={img="Planet Cute:Enemy Bug",x=6*dx-sw,y=7*dy+sh}

    doors={}
    doors[1]={img="Planet Cute:Door Tall Closed",x=150,y=510}

    throwThings={}
    throwThings[1]={img="Planet Cute:Rock",x=8*dx-sw,y=1*dy+sh}
    throwThings[2]={img="Planet Cute:Tree Tall",x=10*dx-sw,y=1*dy+sh}
    throwThings[3]={img="Planet Cute:Tree Tall",x=1*dx-sw,y=2*dy+sh}
    throwThings[4]={img="Planet Cute:Tree Tall",x=2*dx-sw,y=2*dy+sh}
    throwThings[5]={img="Planet Cute:Tree Tall",x=9*dx-sw,y=3*dy+sh}
    throwThings[6]={img="Planet Cute:Tree Tall",x=1*dx-sw,y=5*dy+sh}
    throwThings[7]={img="Planet Cute:Tree Tall",x=3*dx-sw,y=5*dy+sh}
    throwThings[8]={img="Planet Cute:Tree Short",x=8*dx-sw,y=6*dy+sh}
    throwThings[9]={img="Planet Cute:Tree Short",x=5*dx-sw,y=6*dy+sh}
    throwThings[10]={img="Planet Cute:Tree Short",x=8*dx-sw,y=8*dy+sh}
    throwThings[11]={img="Planet Cute:Tree Short",x=5*dx-sw,y=8*dy+sh}
    throwThings[12]={img="Planet Cute:Tree Ugly",x=7*dx-sw,y=3*dy+sh}
    throwThings[13]={img="Planet Cute:Tree Ugly",x=7*dx-sw,y=2*dy+sh}
    throwThings[14]={img="Planet Cute:Tree Ugly",x=8*dx-sw,y=3*dy+sh}

    ells={}
    ells[1]={x=1*dx-sw,y=6*dy+sh,w=iw,h=ih}
    ells[2]={x=1*dx-sw,y=7*dy+sh,w=iw,h=ih}
    ells[3]={x=1*dx-sw,y=8*dy+sh,w=iw,h=ih}
    ells[4]={x=1*dx-sw,y=9*dy+sh,w=iw,h=ih}
    ells[5]={x=2*dx-sw,y=9*dy+sh,w=iw,h=ih}
    ells[6]={x=3*dx-sw,y=9*dy+sh,w=iw,h=ih}
    ells[7]={x=3*dx-sw,y=8*dy+sh,w=iw,h=ih}
    ells[8]={x=3*dx-sw,y=7*dy+sh,w=iw,h=ih}
    ells[9]={x=3*dx-sw,y=6*dy+sh,w=iw,h=ih}
    ells[10]={x=2*dx-sw,y=6*dy+sh,w=iw,h=ih}

end

function removeSprites()    -- remove sprite when character is over it
    for z,v in pairs(keys) do
        if avatars[SA].x>v.x-30 and avatars[SA].x<v.x+30 and avatars[SA].y>v.y-30 and avatars[SA].y<v.y+30 then
            table.remove(keys,z)
            if avatars[SA].inventory[1] == nil then
                avatars[SA].inventory[1] = 1
            else
                avatars[SA].inventory[1] = avatars[SA].inventory[1] + 1
            end
            return
        end
    end
    for z,v in pairs(throwThings) do -- Lift a throwable thing when selected avatar is on same tile
        if avatars[SA].x>v.x-30 and avatars[SA].x<v.x+30 and avatars[SA].y>v.y-30 and avatars[SA].y<v.y+30 then
            if avatars[SA].inventory[2] ~= nil then
                throwThings[avatars[SA].inventory[2]].y = throwThings[avatars[SA].inventory[2]].y - 50
            end
            v.y = v.y + 50
            avatars[SA].inventory[2] = z
        end
    end
end

function draw()
    background(6, 223, 252, 255)

    for _,v in ipairs(ells) do
        ellipse(v.x,v.y,v.w,v.h)
    end

    --sprite("Documents:Level1Map",WIDTH/2,HEIGHT/2) -- Contains Grass, water, dirt, sky.

    for _,v in ipairs(avatars) do
        sprite(v.img,v.x,v.y)
    end

    for _,v in ipairs(keys) do
        sprite(v.img,v.x,v.y)
    end

    for _,v in ipairs(bugs) do
        sprite(v.img,v.x,v.y)
    end

    for _,v in ipairs(doors) do
        sprite(v.img,v.x,v.y)
    end

    for _,v in ipairs(throwThings) do
        sprite(v.img,v.x,v.y)
    end
end

function touched(touch)
    local id = touch.id
    local state = touch.state
    local x = touch.x
    local y = touch.y
    if state == BEGAN then
        swipeId = id  -- Preserve the id
        swipeX = x    -- Preserve the position
        swipeY = y    -- Preserve the position
        return
    end
    if state == ENDED and id == swipeId then
        swipeId = nil
        if math.abs(x - swipeX) < 100 then -- Within tolerance?
            if swipeY - y > 100 then       -- Long enough?
                print("Swipe down")
                moveAvatar(SA,0,-dy)
            end
            if y - swipeY > 100 then       -- Long enough?
                print("Swipe up")
                moveAvatar(SA,0,dy)
            end
        end
        if math.abs(y - swipeY) < 100 then
            if swipeX - x > 100 then
                print("Swipe Left")
                moveAvatar(SA,-dx,0)
            end
            if x - swipeX > 100 then
                print ("Swipe Right")
                moveAvatar(SA,dx,0)
            end
        end
    end

    if state==ENDED then --Select an Avatar
        for k,v in pairs(avatars) do -- Iterate through avatars table in pairs
            if x>v.x-30 and x<v.x+30 and y>v.y-30 and y<v.y+30 then -- Defines tap select area
                SA=k -- Selected Avatar = id number
            end
        end
    end
end

function screenEdges()
        -- Tells currently selected avatar (SA) to go back to edge of screen when it passes the invisible edges set at w, h, WIDTH, and HEIGHT.
    if avatars[SA].x < sw then avatars[SA].x = 1*dx-sw 
    elseif avatars[SA].x > WIDTH then avatars[SA].x = 10*dx-sw end
    if avatars[SA].y < ih then avatars[SA].y = 1*dy+sh
    elseif avatars[SA].y > HEIGHT then avatars[SA].y = 8*dy+sh end
end

function moveAvatar(SA,dx,dy)
    local newX, newY = avatars[SA].x+dx, avatars[SA].y+dy -- Temporary new positions.
    for k,v in pairs(avatars) do
        if v.x==newX and v.y==newY then -- If true, we have a clash with avatars.
            return -- Don't move, we have a clash.
        end
    end
    for k,v in pairs(ells) do
        if v.x==newX and v.y==newY then
            return
        end
    end
    
    if avatars[SA].inventory[2] ~= nil then
        moveThrowThings(avatars[SA].inventory[2],dx,dy)
    end

    -- if we got this far, there are no clashes, make the move.
    avatars[SA].x,avatars[SA].y=avatars[SA].x+dx,avatars[SA].y+dy

    removeSprites() 

    screenEdges()

    print(avatars[SA].x,avatars[SA].y)
end

function moveThrowThings(SO,dx,dy)
    if avatars[SA].inventory[2] == SO then
        print("moveit")
        throwThings[SO].x,throwThings[SO].y=throwThings[SO].x+dx,throwThings[SO].y+dy
    end
end

@Kempoman - wins helper of the day award =D>

Codea programmers are the kindest, most giving group of people I have ever met!!! ^:)^ ^:)^
I will try my hardest to understand everything you gave me! Someday, I might be able to help out a little too, thanks to you all.