#### Howdy, Stranger!

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

# Strategy Game Style Movement

edited July 2013 Posts: 37

Does anyone now how to select one avatar and move it with swipe controls... Then select a different avatar and move it with the same swipe controls? I'm guessing i need to put the swipe controls in a class. But I have no idea how to differentiate between which avatar to control at a given time. Please help. Code below. Thx. @.@

Tagged:

• Posts: 37
``````--# Main
-- Move

displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
sx=50.5
sy=85.5
w=101
h=171
dx=101
dy=85.5
end

function draw()
background(0, 0, 0, 255)

sprite("Documents:TileSetTest",WIDTH/2,HEIGHT/2)

sprite("Planet Cute:Character Horn Girl",151.5,256.5,w,h)

sprite("Planet Cute:Character Pink Girl",sx,sy,w,h)
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")
sy = sy - dy
end
if y - swipeY > 100 then       -- Long enough?
print("Swipe up")
sy = sy + dy
end
end
if math.abs(y - swipeY) < 100 then
if swipeX - x > 100 then
print("Swipe Left")
sx = sx - dx
end
if x - swipeX > 100 then
print ("Swipe Right")
sx = sx + dx
end
end
end
end
``````
• edited July 2013 Posts: 37

Maybe a tapCount would be part of the answer? But how to implement a double tap without messing up the swipe code?

• Posts: 372

Put the two avatars in a table having there x and y values and then select an avatar when someone touches it and then control the x and y of the avatar. I think I might not be clear so here's the code.

``````--# Main
-- Move

displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
avatars={vec2(101,170), --Horn Girl
vec2(50.5,85.5)--Pink Girl
}
SA=1 --Selected Avatar right now Horn Girl since 1
w=101
h=171
dx=101
dy=85.5
end

function draw()
background(0, 0, 0, 255)

sprite("Documents:TileSetTest",WIDTH/2,HEIGHT/2)

sprite("Planet Cute:Character Horn Girl",avatars[1].x,avatars[1].y,w,h)

sprite("Planet Cute:Character Pink Girl",avatars[2].x,avatars[2].y,w,h)
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")
avatars[SA].y = avatars[SA].y - dy
end
if y - swipeY > 100 then       -- Long enough?
print("Swipe up")
avatars[SA].y = avatars[SA].y + dy
end
end
if math.abs(y - swipeY) < 100 then
if swipeX - x > 100 then
print("Swipe Left")
avatars[SA].x = avatars[SA].x - dx
end
if x - swipeX > 100 then
print ("Swipe Right")
avatars[SA].x = avatars[SA].x + dx
end
end
end

if state==ENDED then --Select an Avatar
for k,v in pairs(avatars) do
if x>v.x-30 and x<v.x+30 and y>v.y-30 and y<v.y+30 then
SA=k
end
end
end
end

``````
• Posts: 37

@Saurabh, thank you soooo much!!!! Nothing short of elegant!!! What I would have tried would have been so messy and probably wouldn't have worked anyway. I'm going to post an updated version for other newbies to play with.

• Posts: 37
``````--# Main

--# Main
-- Move

displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
SA=1 --Selected Avatar right now (Horn Girl since 1)
sw=50.5
sh=85.5
w=101
h=171
dx=101
dy=85.5

avatars={vec2(sw, sh+h), -- Horn Girl
vec2(sw, sh), -- Pink Girl
vec2(sw+w*2, sh), -- Cat Girl
vec2(sw+w*3, sh+h*4), -- Princess Girl
vec2(sw+w*9, sh+h*3) -- Boy
}
end

function draw()
background(0, 0, 0, 255)

sprite("Documents:TileSetTest",WIDTH/2,HEIGHT/2)

sprite("Planet Cute:Character Horn Girl",avatars[1].x,avatars[1].y,w,h)

sprite("Planet Cute:Character Pink Girl",avatars[2].x,avatars[2].y,w,h)

sprite("Planet Cute:Character Cat Girl",avatars[3].x,avatars[3].y,w,h)

sprite("Planet Cute:Character Princess Girl",avatars[4].x,avatars[4].y,w,h)

sprite("Planet Cute:Character Boy",avatars[5].x,avatars[5].y,w,h)
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")
avatars[SA].y = avatars[SA].y - dy
end
if y - swipeY > 100 then       -- Long enough?
print("Swipe up")
avatars[SA].y = avatars[SA].y + dy
end
end
if math.abs(y - swipeY) < 100 then
if swipeX - x > 100 then
print("Swipe Left")
avatars[SA].x = avatars[SA].x - dx
end
if x - swipeX > 100 then
print ("Swipe Right")
avatars[SA].x = avatars[SA].x + dx
end
end
end

if state==ENDED then --Select an Avatar
for k,v in pairs(avatars) do
if x>v.x-30 and x<v.x+30 and y>v.y-30 and y<v.y+30 then
SA=k
end
end
end
end

``````
• Posts: 37

Ok, I figured out how to keep all my avatars from going off the edges of the screen. And even figured out how to put the code into a function. Woot! Yeah, I know, not very impressive, but I'm thrilled anyway. However, I have yet more agonizingly noob questions for anybody with the time or inclination.

1. My program worked the same when I put the screen edges code in the draw function as when I put it into its own function screenEdges(). So are functions mostly for organization? Or do they help chunks of code interfering with other chunks?

2. Could I use the table and loop that Saurabh generously provided to prevent my selected avatar "SA" from occupying the same x,y coordinates as the other avatars? (So far my grid is defined by limiting the movement of avatars to only the center of each tile (dx=101, dy=85.5).) So my idea is to use x,y coordinates instead of rectangles or physics objects to keep everybody on separate tiles...

3. @Saurabh What do k and v mean in the for loop? Also, it seems like the associated table keeps updating the x and y values since I can select an avatar even after it moves from its starting point. Is that right? I've done the lua tuts for tables and loops by ignatz, but they don't seem natural to me yet...

Thanks everyone!! Code below

• Posts: 37
``````--# Main

--# Main
-- Move

displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
SA=1 --Selected Avatar right now (Horn Girl since 1)
sw=50.5
sh=85.5
w=101
h=171
dx=101
dy=85.5

avatars={vec2(sw, sh+h), -- Horn Girl
vec2(sw, sh), -- Pink Girl
vec2(sw+w*2, sh), -- Cat Girl
vec2(sw+w*3, sh+h*4), -- Princess Girl
vec2(sw+w*9, sh+h*3) -- Boy
}
end

function draw()
background(0, 0, 0, 255)

sprite("Documents:TileSetTest",WIDTH/2,HEIGHT/2)

sprite("Planet Cute:Character Horn Girl",avatars[1].x,avatars[1].y,w,h)

sprite("Planet Cute:Character Pink Girl",avatars[2].x,avatars[2].y,w,h)

sprite("Planet Cute:Character Cat Girl",avatars[3].x,avatars[3].y,w,h)

sprite("Planet Cute:Character Princess Girl",avatars[4].x,avatars[4].y,w,h)

sprite("Planet Cute:Character Boy",avatars[5].x,avatars[5].y,w,h)

screenEdges()
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")
avatars[SA].y = avatars[SA].y - dy
end
if y - swipeY > 100 then       -- Long enough?
print("Swipe up")
avatars[SA].y = avatars[SA].y + dy
end
end
if math.abs(y - swipeY) < 100 then
if swipeX - x > 100 then
print("Swipe Left")
avatars[SA].x = avatars[SA].x - dx
end
if x - swipeX > 100 then
print ("Swipe Right")
avatars[SA].x = avatars[SA].x + dx
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 -- What does k,v stand for?
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 < w then avatars[SA].x = sw end
if avatars[SA].x > WIDTH then avatars[SA].x = sw * 19 end
if avatars[SA].y < h then avatars[SA].y = sh end
if avatars[SA].y > HEIGHT then avatars[SA].y = sh * 9 end
end

``````
• Mod
Posts: 5,396

@Kempoman - functions should give the same result as inline (everything in one function) code, but they are there for several reasons.

• Avoid duplication - to prevent having to write the same code repeatedly
• Debugging - to break the code into logical chunks that can be checked separately, making it much easier to find errors
• Organisation - to make code readable
and more
• Mod
Posts: 5,396

@Kempoman - the k,v in the for loop are

k = an id number for each item in the table. Often, you won't need to bother with this, but if you want to delete an item, you will need it.

v = the item that is stored in the table. You have put vec2 variables in there, so v will be a vec2 (with properties v.x and v.y) and the for loop will cycle through all your avatars.

• Mod
edited July 2013 Posts: 5,396

@Kempoman - to avoid collisions, you could use several approaches, but the logical place to do it is when you're moving an avatar, in the touch function. You can go in four different directions, so you need to check each of them, and if an avatar is already there, cancel the movement.

So one way you could do it is to write a function MoveAvatar that takes three parameters, the current avatar index number; the change in x position; and the change in y position (only one of the x and y will change, of course). It would set a new vec2 for the avatar.

So if your movement is down, you currently say

``````avatars[SA].y=avatars[SA].y-dy
``````

``````MoveAvatar(SA,0,-dy)
``````

if you swiped right, you would say

``````MoveAvatar(SA,dx,0)
``````

and now you should see how useful functions are in making your code simpler.

What would MoveAvatar do?

A simple approach is just to cycle through the avatars and check the x,y positions don't conflict, eg

``````function MoveAvatar(id,dx,dy)
local newX, newY = avatars[id].x+dx,avatars[id].y+dy --temporary new positions
for k,v in pairs(avatars)
if v.x==newX and v.y==newY then --if true, we have a clash
return end  --don't move, we have a clash
end
end
--if we got this far, there are no clashes, make the move
avatars[id].x,avatars[id].y=avatars[id].x+dx,avatars[id].y+dy
end
``````
• Posts: 37

Ignatz, you are amazing!!!! I.. think... I... Understand!! This is so cool. To me all of you seem like wizards.

• Mod
Posts: 5,396

That's what I thought a few months ago, so you'll soon be a wizard if you just keep learning

• Mod
Posts: 5,396

At the moment, your avatar locations are x,y screen coordinates.

I think you'll do better by creating a virtual grid (ie 2D table) on the screen, starting at [1][1] at bottom left, and going to [r][c] at top left, where r=rows and c=columns.

This enables you to hold a map of the screen in memory, and instead of moving your avatars to pixel locations, you move them to squares on your map, eg [3][4]. Then when you're drawing, you can easily convert those map locations into pixels.

This map based approach is really useful if you want to put objects on your map, because you could use a table to store the objects in each cell of the map.

So I suggest separating the mapping and screen drawing functions, because it will be much easier to manage and to extend your code.

• Posts: 80

As a former UI designer always keep you data separate from your drawing routines. You can make the migration to 3d or just a different display scheme easily.

I use grid[x][y] for the map and store a dataObject in that location, and I have a table with dataObjects for any non-map things (like the player, enemies, doors...). You can then check grid[x][y].tileType and key off the value. This will let you have flexibility if you want to have a tileType that allows passage for a certain type of tileType. For example, 1=player, 2=enemy, 3=stopEnemy,4=food

Here is what I use:

``````mapData = class()

function mapData:init(id,pos,tileType,isShown,blocksLOS,stateObstacle)
--  print("mapData")
-- you can accept and set parameters here
self.id = id -- the id number of the rectangle created in the grid[][]
self.pos = pos  -- the position to be multiplied  *also the begin vec2 of the astar search
self.tileType = tileType  -- the id number now it is mesily made by hand
-- later it will be the map format from tiled editor.
self.isShown = isShown   -- to display the correct texture map coordinate
self.isDrawn = 1 -- flag to draw tile on screen
self.isPointOfInterest = vec2(0,0) -- the vec2 location the the endpoint of the astar search
self.giveDamage = 0
self.takeDamage = 0
self.blocksLOS = blockLOS
self.isEnemy = 0
self.health = 0
self.isOnFire = 0
self.name = "default"
self.state = tileType
--    self.timer = newTimerClass to be created later
end
``````

Hope this helps

• Posts: 37

Thank you Ignatz and Thwapp. I've been making a lot of progress with your help. I will post my results when I have reached some of my goals. Hopefully soon.

• edited July 2013 Posts: 37

I took your advice Ignatz and started switching from pixels to tables and I like it so far.

Ok, so I've learned a little about tables thanks to you wizards. Unfortunately, I couldn't figure out how to make the avatars and bugs move within the table, which would solve a lot of overlapping problems.

So here's my idea for the game if you are interested. Bug boy wants to save his friend cat girl from the evil bugs in level 1. His power is super strength so he can pick up objects like trees, bushes, and later on boulders. Here's the twist: when thrown, each of these objects pushes a bug in a different compass direction and there are a limited number of each object. The bugs are too strong to defeat directly, so bug boy has a plan to push the two opposite bugs together (this makes them fight each other and explode).

To prototype this level, I was hoping someone could help me figure out how to:

1. Move avatars within a table.
2. Pick up and carry objects.
3. Throw objects so that they push a bug in a given direction one tile.
4. Make objects and bugs disappear.
5. Open a door only when carrying a key.

Btw, in future levels, bug boy will be joined by cat girl who will have different powers --which will be needed to solve greater challenges. She might have the ability to grow a limited number of extra trees. Later, when other friends are rescued, they will join the team with their own unique powers, like turning water into ice, etc...

I'm pretty sure i could have put all my sprites in a table with a table right? For 1,maxnum something do I = Id end I'm not sure. However, I thought it would be hard to remember which number was which sprite...

Hope you guys don't mind helping me out again. I really appreciate it . Code below.

• edited July 2013 Posts: 37
``````--# Main

-- Final

displayMode(FULLSCREEN)
supportedOrientations(CurrentOrientation)

moveSprites = {}
layer1 = 1
layer2 = 2
layer3 = 3

function setup()
SA=1 --Selected Avatar right now (Horn Girl since 1)
sw=50 --Starting point
sh=121
w=101 --Width of sprite
h=171
dx=101 --Change in x
dy=85.5

avatars={vec2(sw, sh+h), -- Horn Girl
vec2(sw+w*8, sh), -- Pink Girl
vec2(sw+w*2, sh), -- Cat Girl
vec2(sw+w*3, sh+h*3), -- Princess Girl
vec2(sw+w*9, sh+h) -- Boy
}

makeSprites()

end

function makeSprites()
for i = 1, 8 do --rows
for j = 1, 11 do  --columns
if layers[layer1][i][j] > 0 then
table.insert(moveSprites,moveSprite((j*100-50),HEIGHT-(i*86-50),layers[layer1][i][j]))
end
end
end

for i = 1,8 do
for j = 1,11 do
if layers[layer2][i][j] > 0 then
table.insert(moveSprites,moveSprite((j*100-50),HEIGHT-(i*86-36),layers[layer2][i][j]))
end
end
end

for i = 1,8 do
for j = 1,11 do
if layers[layer3][i][j] > 0 then
table.insert(moveSprites,moveSprite((j*100-50),HEIGHT-(i*86-36),layers[layer3][i][j]))
end
end
end
end

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

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

for i = 1, table.maxn(moveSprites, i) do -- Get largest possible numerical index.
moveSprites[i]:draw()
end

-- sprite("Planet Cute:Character Horn Girl",avatars[1].x,avatars[1].y,w,h)

-- sprite("Planet Cute:Character Pink Girl",avatars[2].x,avatars[2].y,w,h)

-- sprite("Planet Cute:Character Cat Girl",avatars[3].x,avatars[3].y,w,h)

-- sprite("Planet Cute:Character Princess Girl",avatars[4].x,avatars[4].y,w,h)

sprite("Planet Cute:Character Boy",avatars[5].x,avatars[5].y,w,h)

screenEdges()
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 -- What does k,v stand for?
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 < w then avatars[SA].x = sw
elseif avatars[SA].x > WIDTH then avatars[SA].x = sw * 19 end
if avatars[SA].y < h then avatars[SA].y = sh
elseif avatars[SA].y > HEIGHT then avatars[SA].y = sh * 6 end
end

function moveAvatar(id,dx,dy)
local newX, newY = avatars[id].x+dx, avatars[id].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.
return -- Don't move, we have a clash.
end
end
-- if we got this far, there are no clashes, make the move.
avatars[id].x,avatars[id].y=avatars[id].x+dx,avatars[id].y+dy
end

--# MoveSprite
moveSprite = class()

function moveSprite:init(x,y,i)
-- you can accept and set parameters here
self.pos = vec2(x,y)
self.size = vec2(101,171)
self.i = i
end

function moveSprite:draw()
-- Codea does not automatically call this method
if self.i == 1 then
sprite("Planet Cute:Door Tall Open", self.pos.x, self.pos.y)
elseif self.i == 2 then
sprite("Planet Cute:Character Boy", self.pos.x, self.pos.y)
elseif self.i == 3 then
sprite("Planet Cute:Character Cat Girl", self.pos.x, self.pos.y)
elseif self.i == 4 then
sprite("Planet Cute:Character Horn Girl", self.pos.x, self.pos.y)
elseif self.i == 5 then
sprite("Planet Cute:Character Pink Girl", self.pos.x, self.pos.y)
elseif self.i == 6 then
sprite("Planet Cute:Character Princess Girl", self.pos.x, self.pos.y)
elseif self.i == 7 then
sprite("Planet Cute:Enemy Bug", self.pos.x, self.pos.y)
elseif self.i == 8 then
sprite("Planet Cute:Gem Blue", self.pos.x, self.pos.y)
elseif self.i == 9 then
sprite("Planet Cute:Gem Green", self.pos.x, self.pos.y)
elseif self.i == 10 then
sprite("Planet Cute:Gem Orange", self.pos.x, self.pos.y)
elseif self.i == 11 then
sprite("Planet Cute:Brown Block", self.pos.x, self.pos.y)
elseif self.i == 12 then
sprite("Planet Cute:Chest Open", self.pos.x, self.pos.y)
elseif self.i == 13 then
sprite("Planet Cute:Chest Lid", self.pos.x, self.pos.y)
elseif self.i == 14 then
sprite("Planet Cute:Chest Closed", self.pos.x, self.pos.y)
elseif self.i == 15 then
sprite("Planet Cute:Heart", self.pos.x, self.pos.y)
elseif self.i == 16 then
sprite("Planet Cute:Key", self.pos.x, self.pos.y)
elseif self.i == 17 then
sprite("Planet Cute:Plain Block", self.pos.x, self.pos.y)
elseif self.i == 18 then
sprite("Planet Cute:Rock", self.pos.x, self.pos.y)
elseif self.i == 19 then
sprite("Planet Cute:Star", self.pos.x, self.pos.y)
elseif self.i == 20 then
sprite("Planet Cute:Stone Block Tall", self.pos.x, self.pos.y)
elseif self.i == 21 then
sprite("Planet Cute:Tree Short", self.pos.x, self.pos.y)
elseif self.i == 22 then
sprite("Planet Cute:Tree Tall", self.pos.x, self.pos.y)
elseif self.i == 23 then
sprite("Planet Cute:Tree Ugly", self.pos.x, self.pos.y)
elseif self.i == 24 then
sprite("Planet Cute:Wall Block Tall", self.pos.x, self.pos.y)
elseif self.i == 25 then
sprite("Planet Cute:Window Tall", self.pos.x, self.pos.y)
elseif self.i == 26 then
sprite("Planet Cute:Door Tall Closed", self.pos.x, self.pos.y)
elseif self.i == 27 then
sprite("Planet Cute:Selector", self.pos.x, self.pos.y)
elseif self.i == 28 then
pushStyle()
tint(0, 97, 250, 255)
sprite("Planet Cute:Enemy Bug", self.pos.x, self.pos.y)
popStyle()
end
end

function moveSprite:touched(touch)
-- Codea does not automatically call this method
end

--# Layers
layers = {

-- Open door layer
{
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
},

-- Contains walls, doors, trees, shrubs, keys,... bugs,... and avatars? How do I get them to move?
{
{24,24,24,21,21,0,0,21,0,0,0},
{24,3,24,0,0,28,0,0,0,0,0},
{24,0,24,0,21,0,0,21,0,0,0},
{24,26,24,0,0,0,0,0,0,0,0},
{21,0,21,0,0,0,23,23,0,2,0},
{0,0,0,0,0,0,23,0,0,22,21},
{22,22,0,0,0,0,0,0,0,0,22},
{16,7,0,0,0,0,23,0,0,0,0},
},

{
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
},

{
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
},

{
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
},

}

``````
• Mod
edited July 2013 Posts: 5,396

@Kempoman - we all learn by doing, you're going the right way and will soon be teaching us stuff >-

Your questions. Here are my suggestions

1 Move avatars within a table
2 Pick up and carry objects

Store more stuff in the avators table, like so

``````avatars={}
avatar[1]={img="Planet Cute:Character Horn Girl",x=1,y=1,inventory={}}
avatar[2]={img="Planet Cute:Character Pink Girl",x=1,y=1,inventory={}}
--etc
``````

Now we have stored the image name, x and y position, and a table listing the objects they are carrying, which you can add to, or delete from, as you wish, eg

``````table.insert(avatar[1].inventory,"small key")
``````

4 Make objects and bugs disappear.

Objects and bugs can be stored in tables, and removed when you want to get rid of them

5 Open a door only when carrying a key.

Check if the character has a key in their inventory

.
Also - you have a long list of character names and repetitive code in moveSprite:Draw()

Better is something like this

in the init function:

``````moveSprite.chars={"Door Tall Open", "Character Boy",
"Character Cat Girl", etc....}
``````

and in the draw function, just one line replaces all the code (except maybe number 28, where you draw extra stuff)

``````sprite("Planet Cute:"..moveSprite.chars[self.i], self.pos.x, self.pos.y)
``````
• Posts: 37

Thanks for understanding where I'm at @Ignatz! I should be able to go quite a ways before i get stuck again thanks to you! One tiny silly question: Are the two dots in
sprite("Planet Cute: "..moveSprite etc
significant?

Btw, my son really likes math. He is six and starting algebra. I got into catos hike and then codea because I wanted him to apply his math skills so he wouldn't forget math or get bored with it. So he is even more motivated to get to the point where I can start teaching him codea so he can make his own games. Which means i need to hurry up and learn it!

If you are ever in Las Vegas and need anything, let me know!

• Posts: 37

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

• Mod
edited July 2013 Posts: 5,396

@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!

https://www.dropbox.com/s/qh1e7ft4rvhlpt2/Lua for beginners.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/

• Posts: 37

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.

• Posts: 80

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.

• Mod
Posts: 5,396

@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!

• Posts: 37

Yes I get that. So ".chars" doesn't do anything. Just part of the name of the table?

• Mod
Posts: 5,396

@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.

• Posts: 37

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.

• edited July 2013 Posts: 37

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.

• edited July 2013 Posts: 37
``````--# 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

``````
• Mod
Posts: 5,396

@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)

• edited July 2013 Posts: 37

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.

• Posts: 37

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?

• edited July 2013 Posts: 391

@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.

• edited July 2013 Posts: 391

@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]

• Posts: 37

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

• Posts: 37

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!

• Posts: 391

@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
``````
• Mod
Posts: 5,396

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

• Posts: 37

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.

• Posts: 147

@Kempoman you are absolutly right! People here are just so nice and there help is the best!