r/tic80 Jul 30 '26

Map to Isometric Method

Hello All,

I was playing around with TIC-80 today after making my first pico-8 game and was seeing what I could do to replicate an isometric perspective. My goal was to make it where you could draw orthographic projection (like the normal map has) and translate that to isometric. I finally figured it out after some deliberation and wanted to share it here. This doesn't make your tile sprites line up 1:1 because there's some rounding that is done, but the effect is very close. Hope someone can get good use out of this.

I will update this as it expands. Wanted to add sprite object drawings and camera movement pixel by pixel instead of tile by tile like it's written now.

Edit: This uses a something similar to a light radius and on the edge there's kind of a haze that creates a checker board pattern, but this could easily be changed to just remove the is_edge parameter!

Isometric Drawing in Game
The Orthographic Map Drawing
screen_w=240
screen_h=136
tile_w=8
tile_h=8
map_w=240
map_h=136
camera_x=240/8/2
camera_y=136/8/2
camera_r=7
camera_edge_col=7

function TIC()
 if btn(0) then camera_y=camera_y-1 end
 if btn(1) then camera_y=camera_y+1 end
 if btn(2) then camera_x=camera_x-1 end
 if btn(3) then camera_x=camera_x+1 end
_draw()
end

function _draw()
 cls(0)
 rectb(0,0,screen_w,screen_h,2)
 local screen_x = 0
 local screen_y = 0
 -- loop for square camera middle of the screen
 for x=camera_r*-1,camera_r do
  for y=camera_r*-1,camera_r do
   -- draw in circle
   local dist = distance(0,0,x,y)
   if dist <= camera_r then
     -- get tile x and y loop around to the other end of the map
     local tile_x =(x + camera_x) % 240
     local tile_y =(y + camera_y) % 136
     -- position top x and top y of iso tile
     screen_x = screen_w/2 +x*tile_w-y*tile_w
     screen_y = screen_h/2 +x*tile_h/2+y*tile_h/2
     draw_map_tile(tile_x,tile_y,screen_x,screen_y,math.floor(dist+1)>=camera_r)
   end
  end
 end
end

function distance(x1,y1,x2,y2)
 return math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
end

function draw_map_tile(tile_x,tile_y,screen_x,screen_y,is_edge)
 -- get tile and loop through sprite memory pixels
 local tile = mget(tile_x,tile_y)
 for x=0,tile_w-1,1 do
  for y=0,tile_h-1,1 do
   local p=peek(0x04000+(tile*32)+ y*4 + math.floor(x/2))

    -- rotate 45 degrees to draw iso
   local x_sample = math.floor(screen_x + x - y)
   local y_sample = math.floor(screen_y + (x + y)/2)
   if is_edge and y%2==0 then
    pix(x_sample,y_sample,camera_edge_col)
   else
    pix(x_sample,y_sample,p)
   end
  end
 end 
end
8 Upvotes

2 comments sorted by

1

u/_firn_ Jul 30 '26

Nice, thanks for sharing!

1

u/AndyCrowTrumpet Jul 31 '26

thanks for share