2D table tile map help

I’m trying to make a tile map world using 2D table(table in table) but I want more control of where each tile goes.

How do I turn this (scroll down)

function setup()   
    map={} 
    w=5
    h=3 
    for x=1,w do 
        map[x]={} 
        for y=1,h do 
        map[x][y]=0  
        end 
        
        map[1][1]={   asset.builtin.Blocks.Grass_Top,     
            asset.builtin.Blocks.Stone_Coal_Alt,    
            asset.builtin.Blocks.Sand,              
            asset.builtin.Blocks.Stone_Diamond_Alt, 
            asset.builtin.Blocks.Mushroom_Red,      
            asset.builtin.Blocks.Wheat_Stage4,      
            asset.builtin.Blocks.Fence_Stone,       
            asset.builtin.Blocks.Water }
        
    bTab={}
    for x=-20,20 do
        for y=-20,20 do
            table.insert(bTab,{x=x,y=y})
        end       
    end
    dx,dy=WIDTH/2,HEIGHT/2
   end 
end

function draw()
    background(0)
       s=130
    for a,b in pairs(bTab) do
        sprite(map[1][1][1],b.x*s+dx,b.y+dy) 
        sprite(map[1][1][2],b.x*s+dx,b.y+dy+170)
        sprite(map[1][1][3],b.x*s+dx,b.y+dy+340)
    
        end
    end

function touched(t)
    if t.state==MOVING then
        dx=dx+t.deltaX
        dy=dy+t.deltaY
    end 

end

Into something like this. So each number corresponds to a tile. That way I can draw my world and have complete control where each tile goes.

TileTable = {
  { 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4 },
  { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,4 },
  { 4,1,3,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,4 },
  { 4,1,1,1,1,1,1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,4 },
  { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
  { 4,1,1,4,1,1,1,1,1,2,2,1,1,4,1,1,1,4,1,4,2,2,1,1,4 },
  { 4,1,1,4,1,1,1,1,4,3,3,4,1,2,1,1,1,2,1,4,1,1,1,1,4 },
  { 4,1,1,4,1,1,1,1,4,3,3,4,1,1,4,1,4,1,1,4,2,2,1,1,4 },
  { 4,1,1,4,1,1,1,1,4,3,3,4,1,1,2,1,2,1,1,4,1,1,1,1,4 },           
  { 4,1,1,4,1,1,1,1,2,3,3,2,1,1,1,4,1,1,1,4,1,1,1,1,4 },
  { 4,1,1,2,2,2,2,1,1,2,2,1,1,1,1,2,1,3,1,2,2,2,1,1,4 },
  { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
  { 4,1,1,1,1,1,1,1,1,2,1,1,1,1,2,2,4,1,1,1,1,1,1,1,4 },
  { 4,1,1,1,1,1,1,1,4,3,4,1,1,1,1,1,2,1,1,1,1,1,1,1,4 },
  { 4,1,1,3,1,1,1,1,2,3,2,1,1,1,1,2,1,1,1,1,1,1,1,1,4 },
  { 4,1,1,1,1,1,1,1,1,2,1,1,2,1,2,1,1,1,1,1,1,1,3,1,4 },
  { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
  { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }
}

@Jarc - just a little info - do you want to scroll the whole screen or have a smaller fixed window with a portion of the map scrolled within it?

displayMode(FULLSCREEN)

function setup()   
    dx,dy=0,0
    TileTable = {
    { 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4 },
    { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,4 },
    { 4,1,3,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,4 },
    { 4,1,1,1,1,1,1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,4 },
    { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
    { 4,1,1,4,1,1,1,1,1,2,2,1,1,4,1,1,1,4,1,4,2,2,1,1,4 },
    { 4,1,1,4,1,1,1,1,4,3,3,4,1,2,1,1,1,2,1,4,1,1,1,1,4 },
    { 4,1,1,4,1,1,1,1,4,3,3,4,1,1,4,1,4,1,1,4,2,2,1,1,4 },
    { 4,1,1,4,1,1,1,1,4,3,3,4,1,1,2,1,2,1,1,4,1,1,1,1,4 },           
    { 4,1,1,4,1,1,1,1,2,3,3,2,1,1,1,4,1,1,1,4,1,1,1,1,4 },
    { 4,1,1,2,2,2,2,1,1,2,2,2,1,1,1,2,1,3,1,2,2,2,1,1,4 },
    { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
    { 4,1,1,1,1,1,1,1,1,2,1,1,1,1,2,2,4,1,1,1,1,1,1,1,4 },
    { 4,1,1,1,1,1,1,1,4,3,4,1,1,1,1,1,2,1,1,1,1,1,1,1,4 },
    { 4,1,1,3,1,1,1,1,2,3,2,1,1,1,1,2,1,1,1,1,1,1,1,1,4 },
    { 4,1,8,1,1,1,1,1,1,2,1,1,2,1,2,1,1,1,1,1,1,1,3,1,4 },
    { 4,8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
    { 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }}  

    map={   asset.builtin.Blocks.Grass_Top,     
            asset.builtin.Blocks.Stone_Coal_Alt,    
            asset.builtin.Blocks.Sand,              
            asset.builtin.Blocks.Stone_Diamond_Alt, 
            asset.builtin.Blocks.Mushroom_Red,      
            asset.builtin.Blocks.Wheat_Stage4,      
            asset.builtin.Blocks.Fence_Stone,       
            asset.builtin.Blocks.Water }
end

function draw()
    background(0)
    for x=1,#TileTable do
        for y=1,#TileTable[1] do
            a=TileTable[x][y]
            sprite(map[a],y*128+dx,HEIGHT-x*128+dy)
        end
    end
end

function touched(t)
    dx=dx+t.deltaX
    dy=dy+t.deltaY
end

@dave1707 Thanks Dave. @Bri_G I would like to see the smaller fixed window with a portion of the map scrolled within because I’m having trouble visualizing what that looks like and I like options.

@Jarc - took @dave1707’s code above and made a windowed scroller. Tap outside the red rectangle to move in any of the 8 directions. If you want a smoother scroll you need to build an image map bigger than the viewing rectangle then print sprite the map before adding the foreground (with an appropriately placed hole. Then add a routine to sprite the map displaced by 1 pixel in a loop.

Post again if problems.


displayMode(FULLSCREEN)

function setup()
    scW,scH,cW,cH = WIDTH,HEIGHT,WIDTH//2,HEIGHT//2
    dx,dy=0,0
    data()
    lbx,lby = 13,10
    winX,winY = cW-3*64-32,cH-3*64-32
end

function draw()
    --
    spriteMode(CENTER)
    sprite(back,cW,cH,scW,scH)
    rectMode(CENTER)
    fill(46, 39, 30)
    noStroke()
    rect(cW,cH,7*64+48,7*64+48)
    for y=-3,3 do
        for x=-3,3 do
            a=TileTable[lby+y][lbx+x]
            sprite(map[a],winX+x*64+224,winY+y*64+224,64,64)
        end
    end
    noFill()
    strokeWidth(4)
    stroke(255, 25, 0)
    rect(cW,cH,64,64)
end

function touched(t)
    --
    if t.state == ENDED then
        if CurrentTouch.x < cW-32 then lbx = lbx-1 end
        if CurrentTouch.x > cW+32 then lbx = lbx+1 end
        if CurrentTouch.y < cH-32 then lby = lby-1 end
        if CurrentTouch.y > cH+32 then lby = lby+1 end
        if lbx < 4 then lbx = 4 end
        if lbx > 22 then lbx = 22 end
        if lby < 4 then lby = 4 end
        if lby > 16 then lby = 16 end
    end
    print(lbx,lby)
end

function data()
    --
    TileTable = {
    { 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4 },
    { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,4 },
    { 4,1,3,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,4 },
    { 4,1,1,1,1,1,1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,4 },
    { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
    { 4,1,1,4,1,1,1,1,1,2,2,1,1,4,1,1,1,4,1,4,2,2,1,1,4 },
    { 4,1,1,4,1,1,1,1,4,3,3,4,1,2,1,1,1,2,1,4,1,1,1,1,4 },
    { 4,1,1,4,1,1,1,1,4,3,3,4,1,1,4,1,4,1,1,4,2,2,1,1,4 },
    { 4,1,1,4,1,1,1,1,4,3,3,4,1,1,2,1,2,1,1,4,1,1,1,1,4 },           
    { 4,1,1,4,1,1,1,1,2,3,3,2,1,1,1,4,1,1,1,4,1,1,1,1,4 },
    { 4,1,1,2,2,2,2,1,1,2,2,2,1,1,1,2,1,3,1,2,2,2,1,1,4 },
    { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
    { 4,1,1,1,1,1,1,1,1,2,1,1,1,1,2,2,4,1,1,1,1,1,1,1,4 },
    { 4,1,1,1,1,1,1,1,4,3,4,1,1,1,1,1,2,1,1,1,1,1,1,1,4 },
    { 4,1,1,3,1,1,1,1,2,3,2,1,1,1,1,2,1,1,1,1,1,1,1,1,4 },
    { 4,1,8,1,1,1,1,1,1,2,1,1,2,1,2,1,1,1,1,1,1,1,3,1,4 },
    { 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4 },
    { 4,8,1,1,1,1,4,1,1,1,1,1,1,4,3,1,1,1,1,1,1,2,1,1,4 },
    { 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4 }}  

    map={   asset.builtin.Blocks.Grass_Top,     
            asset.builtin.Blocks.Stone_Coal_Alt,    
            asset.builtin.Blocks.Sand,              
            asset.builtin.Blocks.Stone_Diamond_Alt, 
            asset.builtin.Blocks.Mushroom_Red,      
            asset.builtin.Blocks.Wheat_Stage4,      
            asset.builtin.Blocks.Fence_Stone,       
            asset.builtin.Blocks.Water,  
        }
    back = asset.builtin.Cargo_Bot.Game_Area
end


P.s. Added an extra line of data in to make it odd number to center screen etc better.

On that topic, I’ve made a tilemap editor that saves the map as a json-file.


url = "https://cutt.ly/QyXUpzN"
http.request(url, function (code)
    saveProjectTab("Main", code)
    print("go back to the editor to see the code")
end)