-- routines for drawing and sizing to available space
function car.draw()
if dark_theme then
g.setBackgroundColor(0.4,0.4, 0.4)
end
ui_state.button_handlers = {}
draw_level_state()
draw_buttons()
draw_level_number()
draw_win_state()
draw_crate_to_move()
draw_hud()
end
function draw_level_state()
for r,row in ipairs(level_state) do
for c,cell in ipairs(row) do
draw_sprite(cell, left+(c-1)*side, top+(r-1)*side)
--? if crate_id[r][c] then
--? color(1,1,1)
--? g.print(crate_id[r][c], left+(c-1)*side, top+(r-1)*side)
--? end
end end end
function draw_sprite(cell, x,y)
if cell >= CELL_VACANT then
color(unpack(SC_AIR))
rect('fill', x,y, side,side)
return
end
local sprite = sprites[cell+1]
for r,row in ipairs(sprite) do
for c,clr in ipairs(row) do
color(unpack(clr))
rect('fill', x+(c-1)*pxside, y+(r-1)*pxside, pxside, pxside)
end end end
function draw_level_number()
local lx, ly = left-level_width, top+10
if Safe_height > Safe_width then
lx, ly = (Safe_width - level_width)/2, top-side-Line_height-10
end
color(unpack(level_color))
g.print(curr_level, lx,ly)
end
function draw_win_state()
if not any_state_in_level(CELL_CRATE) then
color(0,1,0)
g.print('success!', left-2*side, top+side)
end
end
function any_state_in_level(needle)
for r,row in ipairs(level_state) do
for c,cell in ipairs(row) do
if cell == needle then
return true
end end end end
function draw_buttons()
local bg
if dark_theme then
bg = {r=0.4,g=0.2,b=0.4}
else
bg = {r=0.6,g=0.4,b=0.6}
end
button(ui_state, 'left', {x=0, y=bside, w=bside, h=Safe_height-bside*2,
bg=bg, onpress1 = function() move_left(true) end})
button(ui_state, 'right', {x=Safe_width-bside, y=bside, w=bside, h=Safe_height-bside*2,
bg=bg, onpress1 = function() move_right(true) end})
button(ui_state, 'up', {x=bside, y=0, w=Safe_width-bside*2, h=bside,
bg=bg, onpress1 = function() move_up(true) end})
button(ui_state, 'down', {x=bside, y=Safe_height-bside, w=Safe_width-bside*2, h=bside,
bg=bg, onpress1 = function() move_down(true) end})
-- level navigation
local ns, ps = tostring('>>'), tostring('<<')
local nw, pw = App.width(ns)+10, App.width(ps)+10
local h = Line_height+10
local nx,px, y
if Safe_width > Safe_height then
px, nx = left-side-pw-10, left+lw*side+side+10
y = top + lh*side/2
else
px, nx = left+side+10, left+lw*side-side-nw-10
y = top-side-h
end
if curr_level > 1 then
button(ui_state, 'previous level', {x=px, y=y, w=pw, h=h,
bg=bg, onpress1=previous_level,
icon=function(p)
color(unpack(level_color))
g.print(ps, p.x+5, p.y+5)
end,
})
end
if curr_level < #levels then
button(ui_state, 'next level', {x=nx, y=y, w=nw, h=h,
bg=bg, onpress1=next_level,
icon=function(p)
color(unpack(level_color))
g.print(ns, p.x+5, p.y+5)
end,
})
end
if #undo_history > 0 then
local w = App.width('undo')+10
local ux, uy = left+lw*side+10, top+10
if Safe_width < Safe_height then
ux, uy = left+lw*side-w-10, top+lh*side+10
end
button(ui_state, 'undo', {x=ux, y=uy, w=w, h=Line_height+10,
bg=bg, onpress1=undo_move,
icon=function(p)
color(0,0,0)
g.print('undo', p.x+5, p.y+5)
end,
})
end
end
-- leave 6 tiles worth of margin on all sides for the nav buttons
function car.resize()
local w,h = Safe_width, Safe_height
local w1, w2 = landscape_button_offsets()
local h1, h2 = portrait_button_offsets()
if Safe_width > Safe_height then
side = min((w-w1-w2)/(1+lw+1+6), h/(lh+6)) -- leave 1 side between board and buttons
else
side = min(w/(lw+6), (h-h1-h2)/(1+lh+1+6)) -- leave 1 side between board and buttons
end
pxside = side/num_tile_px
left = (w-side*lw)/2
top = (h-side*lh)/2
if Safe_width > Safe_height then
bside = min((w-w1-w2-side*(1+lw+1))/2, (h-side*lh)/2)
else
bside = min((h-h1-h2-side*(1+lh+1))/2, (w-side*lw)/2)
end
end
-- space needed for buttons to the left and right
function landscape_button_offsets()
local ns, ps = tostring('>>'), tostring('<<')
local nw, pw = App.width(ns)+10, App.width(ps)+10
return 10+pw+10, 10+nw+10
-- we assume the level name and undo button will be within this width
end
-- space needed for buttons to the top and bottom
function portrait_button_offsets()
return 10+Line_height+10, 10+Line_height+10
end