mirror of
https://github.com/clockworkpi/PicoCalc.git
synced 2026-03-19 10:32:37 +01:00
449 lines
24 KiB
Lua
449 lines
24 KiB
Lua
-- BOXWORLD
|
|
-- original game and sprites by Jeng-Long Jiang, 1992
|
|
-- picocalc lua conversion by maple "mavica" syrup, 2025
|
|
|
|
local sprite_size = 20
|
|
local sprites = draw.loadBMPSprites("lua/boxworld.bmp", sprite_size, sprite_size)
|
|
|
|
local fg,bg = colors.fromRGB(255,255,255),colors.fromRGB(0,0,0)
|
|
local screen = nil
|
|
local quit = false
|
|
|
|
local function switch_screen(to)
|
|
screen = to
|
|
if screen.entry then screen.entry() end
|
|
end
|
|
|
|
local music = {
|
|
tick = 0.10,
|
|
instrument = sound.instrument(sound.presets.square),
|
|
notes = {
|
|
c = 0,
|
|
C = 1,
|
|
d = 2,
|
|
D = 3,
|
|
e = 4,
|
|
f = 5,
|
|
F = 6,
|
|
g = 7,
|
|
G = 8,
|
|
a = 9,
|
|
A = 10,
|
|
b = 11
|
|
},
|
|
tracks = {
|
|
intro = {
|
|
"l2o3el1<el2gl1el2>cl1<el2>el3dl1c<bafl3>c<bl2al1dl2fl1el2gl1fl2b>c",
|
|
"l3o1cga>cel2dl3c<l4bl3fa>cl2<a>c"
|
|
},
|
|
victory = {
|
|
"l2o2el1Gl2al3bl1>dl2ee",
|
|
"l3o1aGel1gl2de"
|
|
}
|
|
},
|
|
playing = nil
|
|
}
|
|
music.instrument.decay = 250
|
|
|
|
function music.perform()
|
|
if not music.playing then return end
|
|
local done_playing = true
|
|
for k,v in pairs(music.playing) do
|
|
local ch = music.channels[k]
|
|
local track = music.playing[k]
|
|
if ch.cursor <= #track then done_playing = false end
|
|
if ch.timer > 0 then ch.timer = ch.timer - 1 end
|
|
if ch.timer == 0 then
|
|
while ch.cursor <= #track do
|
|
local input = string.sub(track, ch.cursor, ch.cursor)
|
|
ch.cursor = ch.cursor + 1
|
|
if input == 'l' then
|
|
input = string.sub(track, ch.cursor, ch.cursor)
|
|
ch.cursor = ch.cursor + 1
|
|
ch.length = tonumber(input)
|
|
elseif input == 'o' then
|
|
input = string.sub(track, ch.cursor, ch.cursor)
|
|
ch.cursor = ch.cursor + 1
|
|
ch.octave = tonumber(input)
|
|
elseif input == '<' then
|
|
ch.octave = ch.octave - 1
|
|
elseif input == '>' then
|
|
ch.octave = ch.octave + 1
|
|
elseif music.notes[input] then
|
|
ch.timer = ch.length
|
|
sound.play(k-1, music.notes[input] + (ch.octave+2) * 12, music.instrument)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if done_playing then music.playing = nil sys.stopTimer() end
|
|
end
|
|
|
|
function music.play(track)
|
|
music.playing = track
|
|
music.channels = {}
|
|
for k,v in pairs(track) do
|
|
music.channels[k] = {}
|
|
music.channels[k].cursor = 1
|
|
music.channels[k].length = 4
|
|
music.channels[k].octave = 3
|
|
music.channels[k].timer = 0
|
|
end
|
|
sys.repeatTimer(music.tick * 1000, music.perform)
|
|
end
|
|
|
|
local game = {
|
|
level = 1,
|
|
levelstrings = {
|
|
"00111\n00131\n00121111\n11142431\n13246111\n111141\n000131\n000111\n",
|
|
"11111\n16221\n124410111\n124210131\n111211131\n011222231\n012221221\n012221111\n011111\n",
|
|
"01111111\n0122222111\n1141112221\n1262422421\n1233124211\n113312221\n011111111\n",
|
|
"01111\n11221\n16421\n114211\n112421\n134221\n133531\n111111\n",
|
|
"011111\n0162111\n0124221\n11121211\n13121221\n13422121\n13222421\n11111111\n",
|
|
"0001111111\n1111222221\n1222311121\n12121222211\n12124241321\n12122522121\n12314242121\n1122221212111\n0121113222261\n0122222112221\n0111111111111\n",
|
|
"0001111111\n0011221261\n0012221221\n0014242421\n0012411221\n1112421211\n133333221\n111111111\n",
|
|
"000111111\n011122221\n1132411211\n1334242261\n1332424211\n111111221\n000001111\n",
|
|
"0111111111\n0122112221\n0122242221\n0142111241\n0121333121\n11213331211\n12422422421\n12222212621\n11111111111\n",
|
|
"00111111\n00122221\n11144421\n16243321\n12433311\n1111221\n0001111\n",
|
|
"011110011111\n112210012221\n124211114221\n122433332421\n112222126211\n01111111111\n",
|
|
"0011111\n1112261\n12243211\n12234321\n11125421\n00122211\n0011111\n",
|
|
"001111\n001331\n0112311\n0122431\n11242211\n12214421\n12262221\n11111111\n",
|
|
"11111111\n12212221\n12433421\n16435211\n12433421\n12212221\n11111111\n",
|
|
"0111111\n11222211\n12424421\n13333331\n12442421\n11126111\n001111\n",
|
|
"00111111\n0012222111\n0012422221\n1112421121\n1333242221\n1333414211\n1111212421\n0001226221\n0001111111\n",
|
|
"111111\n122221\n1244411\n122133111\n112233421\n012622221\n011111111\n",
|
|
"0011111111\n0012221321\n0112243331\n0122421531\n1121141211\n1222422421\n1222122221\n1111111621\n0000001111\n",
|
|
"01111111\n01333321\n1113334111\n1224142421\n1244221421\n1222212221\n1111262111\n00011111\n",
|
|
"1111111\n1334331\n1331331\n1244421\n1224221\n1244421\n1221621\n1111111\n",
|
|
"000111111\n000123331\n111133331\n12211142111\n12424224421\n16242422221\n12221112221\n11111011111\n",
|
|
"11111111\n12222221\n12144221\n12333121\n113334211\n012112421\n014224221\n012212261\n011111111\n",
|
|
"0011111\n1112221111\n1222424221\n1242224261\n1114411111\n00122331\n00133331\n00111111\n",
|
|
"11111100011111\n12222111012231\n12242421013331\n12122421112231\n12244422242631\n11122422412231\n00122414213331\n00112222212231\n00011111111111\n",
|
|
"00000111111\n01111132221\n01221331121\n01224332221\n01221231211\n11121141221\n12422224421\n12141221221\n16221111111\n11111\n",
|
|
"0111111111\n0122211221111\n0124222222221\n0114111211221\n0122112521211\n012433333321\n112111232121\n122222411141\n122212222461\n111114121111\n000012221\n000011111\n",
|
|
"000000111111111\n000000122222221\n000000121212121\n000000122424121\n111111122242221\n133122112424121\n133222112424221\n133122112111111\n133121242421\n133222224221\n122111262111\n1111011111\n",
|
|
"00001111\n11111221\n1224242101111111\n1222422101535351\n1124242111353531\n0142422122535351\n0164242222353511\n0142422122535351\n1124242111353531\n1222422101535351\n1224242101111111\n11111221\n00001111\n",
|
|
"11111111\n13333331\n122421211\n124212421\n114242421\n012262221\n011111111\n",
|
|
"001111111111\n111222322221\n122211411221\n126432323411\n11241141121\n01222232221\n01111111111\n",
|
|
"000111111\n111132261\n122444221\n131131131\n122242221\n122431211\n11112221\n00011111\n",
|
|
"0111111\n0132331\n0132431\n11122411\n12422421\n12141121\n12226221\n11111111\n",
|
|
"0000111111\n001112222111\n00122214222111\n00122242224421\n00124421422221\n00112224222421\n11111121411111\n1336214221\n1313322411\n133334121\n133332221\n111111111\n",
|
|
"111111111111111\n122222212222221\n124214212411421\n121224212222221\n122211414114421\n121212333212221\n124223212342121\n124164333121221\n122223212322421\n121134111432121\n121243333321121\n122222222222221\n111111111111111\n",
|
|
"111111111\n122211221\n121242421\n122531221\n112136311\n1141115111\n1222222221\n1222112121\n1111112221\n0000011111\n",
|
|
"11111111\n12222221\n1244222111\n12242444211111\n112112333222211\n012161333111421\n012124333222221\n112124333421211\n12211111211121\n12222224222421\n11111111111221\n00000000001111\n",
|
|
"00011111\n00012621\n00014441\n11112221\n122231411\n124343231\n122131311\n11111111\n",
|
|
"111111111111\n133321222221\n133221211221\n133222221221\n133221241121\n133321424221\n111111224421\n011224244221\n016244422121\n011242112221\n001222222221\n001111111111\n",
|
|
"111111111\n122222221\n122424241\n112141121\n0123323311\n0113323321\n00121141211\n00142424221\n00122222261\n00111111111\n",
|
|
"111110000001111\n162211111111221\n112422222224221\n012121221111221\n012242221111411\n01421121242421\n11242241222221\n12221222222121\n12221111141111\n1111122212221\n0000133322421\n0000133331221\n0000133331111\n0000111111\n",
|
|
"0000011111\n0111112221\n0123324121\n0121352221\n1125314211\n124224221\n122211261\n111111111\n",
|
|
"1111101111111\n1222111221221\n1242222242621\n1121411311221\n0122333532421\n0124121312121\n0112222422221\n0012211111111\n001111\n",
|
|
"000000000111\n0000111111611\n00001333314211\n00001333312421\n00001333324221\n00001233312221\n111111211111211\n124242224221221\n122224422242421\n111242424221111\n001122242421\n000122111111\n0001111\n",
|
|
"00011111\n0111222111\n1122642421\n12211211211\n12431342221\n12131512221\n12433322111\n111412111\n0012221\n0011111\n",
|
|
"0000001111\n000000122111111\n000000122221221\n000000124422221\n111111141221221\n122132332111411\n122131534222221\n122131351212221\n124433331211111\n12642121121\n12444122221\n12222111111\n111111\n",
|
|
"1111\n122111\n12422111\n1242422111\n124242422111\n124242422221\n1242422122211\n1242211244421\n16211112222211\n11210134444431\n012111333333311\n012223555555531\n011113333333331\n000011111111111\n",
|
|
"1111111\n12612211111\n12442242221\n12213114121\n11413332221\n11233311411\n12211311221\n12242242221\n12212221221\n11111111111\n",
|
|
"00011111\n00012621\n00012421\n00014341\n011134311\n11234343111\n12243434221\n12222322221\n11111111111\n",
|
|
"1111111111111\n1224242435331\n1242424253331\n1224242435331\n1242424253331\n1224242435331\n1242424253331\n1224242435331\n1242424253331\n1224242435331\n1642424253331\n1111111111111\n",
|
|
"00000000000001\n00000000000011\n00000000000111\n000000000012221\n000111111112121\n001242424242221\n01121313131641\n111333333322211\n01121212121411\n001242424242221\n000111111112121\n000000000012221\n00000000000111\n00000000000011\n",
|
|
"1111111\n122342111\n123434221\n154343621\n123434211\n12234221\n11111111\n",
|
|
"00000000011111\n00000000012221\n1111111111252111\n1222222222232221\n1244445555433361\n1222222222232221\n1111111111252111\n00000000012221\n00000000011111\n",
|
|
"000001111\n1111112211111\n1642222422421\n1411124212121\n1221221242221\n1241222212111\n122421412221\n133333333321\n111111112221\n000000011111\n",
|
|
"0111111111\n0122211221111\n0124222222221\n0114111211221\n0122113421211\n012433333321\n112111322121\n122222411141\n122212222461\n111114121111\n000012221\n000011111\n",
|
|
"11111111111\n12222122221\n12464444421\n12222222221\n11111211111\n00013221\n00013221\n00013331\n00013221\n00011111\n",
|
|
"0011111\n0012621\n0012421\n111232111\n122252221\n125555521\n122252221\n111454111\n0012321\n0012521\n0012321\n0011111\n",
|
|
"11111111111111\n13222222222221\n13424242424221\n13111111111221\n13135242334511\n1312424253461\n1313224233441\n1311111111131\n1322222222221\n1314141414141\n1322222222221\n1111111111111\n",
|
|
"111111111111\n13322122222111\n13322124224221\n13322141111221\n13322226211221\n13322121224211\n11111121142421\n00124224242421\n00122221222221\n00111111111111\n",
|
|
"00000001111\n11111111221111\n12221133333221\n12242211333121\n11224221112121\n01212422122221\n01221242212221\n01222124221221\n01222212421211\n0111122124221\n0000112212421\n0000011612221\n0000001111111\n",
|
|
"11110000001111\n13311111111331\n15353333353531\n12424242424241\n14242464242421\n12424242424241\n14242424242421\n13535333335351\n13311111111331\n11110000001111\n",
|
|
"000011111\n000112221111\n000123352421\n111121312221\n122223531611\n12141141121\n12222242421\n11221222111\n011111111\n",
|
|
"111111\n122221\n124221111\n124533521\n125335421\n111122421\n000126221\n000111111\n",
|
|
"00011111\n111132211\n124343221\n164121421\n124323221\n111141421\n001323221\n001111111\n",
|
|
"111111111111\n122223332421\n124445552461\n122223332421\n111111111111\n",
|
|
"1111111111\n1122222221\n1222141421\n1244223431\n1261113331\n1111111111\n",
|
|
"01111\n012211111\n114211221\n122464221\n122211421\n1113112111\n0133342421\n0113322221\n0011111111\n",
|
|
"1111101111\n1333101221111\n1333111224221\n133331124224111\n113333112224221\n111333211242421\n121122221224221\n1221121211121111\n1242121422422221\n1224262422224221\n1222124244242111\n12211111122111\n121100001111\n111\n",
|
|
"1111111\n1323231\n1244421\n1346431\n1244421\n1323231\n1111111\n",
|
|
"0000001111\n1111111221\n1222224221\n1222411641\n1141333121\n0124333221\n01213231211\n01222121421\n01422422221\n01221111111\n01111\n",
|
|
"000111111111\n000122212221\n000122222221\n111115111211\n12223332221\n121215111411\n124222242221\n111116212221\n000011111111\n",
|
|
"11111\n13331011111\n13331112221\n133332224411111\n1333322122122211\n1331411112141221\n1124221222224421\n1224126242441221\n1242424212224211\n122212242112221\n111111222111111\n0000011111\n",
|
|
"111111111111111\n111312222221111\n113312422421221\n133312112421221\n133333221442221\n113333422221421\n111121111111221\n122242222222211\n122421224124211\n124111242124421\n122261221122221\n111111111111111\n",
|
|
"000000011111111\n000000012212221\n011111112443331\n012222222213331\n012111111413331\n112122222213331\n122121424211111\n12124242421\n12622421221\n11111424421\n00001222221\n00001111111\n",
|
|
"000000011111\n001111112221\n111222232421\n124221431411\n122122631221\n112111132221\n012422151111\n01211213221\n01222223121\n01114222221\n00012211111\n0001111\n",
|
|
"00001111\n111112211111\n122224222421\n122414112221\n111213532111\n0012333261\n0011214111\n00012221\n00011111\n",
|
|
"00011111111\n11112222321\n12242424321\n12231111311\n1243424261\n1223221111\n1111111\n",
|
|
"0011111\n0012221\n11143411111\n12223242221\n12114112621\n12223211111\n1112321\n0012221\n0011111\n",
|
|
"011111\n01262111111\n01213352221\n01233312221\n11411242421\n12221411111\n122242221\n111112121\n000012221\n000011111\n",
|
|
"00000111111\n000111222211\n000122211221\n011141122121\n112222233121\n122414153121\n12446213512111\n12244213312221\n11222213342221\n01114113212111\n000122111221\n000112222211\n00001111111\n",
|
|
"000001111111\n000001221221\n000001224421\n111111241221\n1333111212211\n1322122421221\n1322224242421\n1322122421221\n1333111212211\n111111242221\n000001621221\n000001111111\n",
|
|
"0000000000111111\n0000000000122221\n1111100011121121\n1332111112422121\n1332222242224121\n1332211211222121\n1332112421424121\n1332122222422121\n1332122421114221\n1332124242242111\n111211212422221\n001222216112421\n001111111112211\n00000000001111\n",
|
|
"00000001\n0000011111\n000111262111\n000122424221\n000125353521\n0011234243211\n01112535352111\n111122424221111\n000111111221\n00001100011\n",
|
|
"011111111111111\n0126252525212211\n0141225252212221\n0121252525222221\n0121225252211211\n012125252521121\n012122525221121\n012125252521121\n012122525221121\n0121252325211211\n1121111111111221\n1222222222222221\n1222111111111221\n1111100000001111\n",
|
|
"01111111111111\n01222212211221\n014442124422411\n012422122333321\n012242214311321\n012212412333311\n114242214311321\n124224264333321\n122211122111111\n1111101111\n",
|
|
"00000111111111\n00000122222221\n00000122414121\n01111112212421\n01222124224221\n11242222211121\n12221411112221\n12222421112111\n1111133261211\n0001333424421\n0001333122221\n0001333111111\n00011111\n",
|
|
"1111000001111\n122111111133111\n124242422133331\n124222442155531\n124242422133531\n122424242153531\n1124242423535311\n1224242423535361\n1224242421535311\n124242422133531\n124222442155531\n124242422133331\n122111111133111\n1111000001111\n",
|
|
"00000011111\n11111112221\n12221132221\n122413322111\n1122333144211111\n0124313422222221\n0124111411212421\n0122212222244121\n0114412114142221\n0133324624222111\n01333141222111\n013332211111\n01111111\n",
|
|
"0111100111111\n0122111122221\n1152225255221\n1242522225121\n1232221112221\n1111112221611\n1252325225521\n1222122212221\n1152225214121\n0122111112221\n0111100011111\n",
|
|
"0111111111\n0122212221\n0124444421\n1124242421\n1242262221\n12421111211\n12213333321\n11223333321\n01111111111\n",
|
|
"0001111111\n0001222221\n00012424211\n000111113311111\n111111335322421\n122464333314421\n122242141112221\n111112222222111\n0000111221111\n0000001221\n0000001111\n",
|
|
"11111\n1222111111\n1242332421\n1142334461\n0122332421\n0111111111\n",
|
|
"0011111\n001222111111\n111413222221\n124233312421\n162431542221\n111122221111\n000111111\n",
|
|
"000011111\n111112221\n122242621\n122421311111\n114211311221111\n012233333241221\n012411311221421\n012221311222221\n011124211111211\n000121422222421\n000122221112221\n000111111011111\n",
|
|
"1111111\n1225221\n1263421\n1243221\n1535551\n1225221\n1245421\n1223221\n1111111\n",
|
|
"00111111111\n00122221221\n11121422421111\n1224221133122111\n1212242133424221\n1244224133221221\n1122122333142221\n0142621333124221\n0122221333422211\n012114211122211\n01222422222111\n012211111111\n01111\n",
|
|
"0001111111111\n1111333333221\n1222333331221\n1221333333211\n112111141141\n16422424222111\n12442222112221\n12122441122121\n12224221244221\n12242242221421\n11112221242421\n00012221222221\n00011111111111\n",
|
|
"000000111111111\n000000122222221\n000000142444221\n000000122212421\n000000122246421\n000011142421211\n00001222414121\n11111212212221\n13332212412111\n133333222121\n133333124121\n111111112221\n000000011111\n",
|
|
"0111110111111\n0122211122221\n1124242142141\n12242624224211\n12122112133331\n12211242131131\n11224222233331\n01244214133331\n01222122214211\n0111112422221\n0000011112211\n000000001111\n",
|
|
"1111\n1221\n1221111111111\n1222211222221\n1331222244121\n133221122242111\n133122114124221\n133222126424221\n133122124242221\n123222124242111\n1221221222111\n12212222111\n111111111\n",
|
|
"00000000011111\n000000001222221\n0000000122411221\n0000001221222421\n1001001212212121\n0101001242422421\n0011111112141221\n001224242222221\n00163342553111\n000133333311111\n0000111111111111\n"
|
|
},
|
|
anim_timer = 0,
|
|
player_flip = 0,
|
|
player_sprites = {
|
|
U = {7, 8},
|
|
D = {5, 6},
|
|
L = {11, 12},
|
|
R = {9, 10},
|
|
W = {13, 13}
|
|
}
|
|
}
|
|
game.push_sound = sound.instrument(sound.drums.tom)
|
|
game.push_sound.volume = 0.5
|
|
game.push_sound.decay = 150
|
|
game.push_sound.sustain = 0
|
|
|
|
local title = {}
|
|
|
|
function title.input()
|
|
local state, _, code = keys.poll()
|
|
|
|
if state == keys.states.pressed then
|
|
if code == keys.left then
|
|
game.level = ((game.level - 2) % #game.levelstrings) + 1
|
|
screen.redraw = true
|
|
elseif code == keys.right then
|
|
game.level = ((game.level) % #game.levelstrings) + 1
|
|
screen.redraw = true
|
|
elseif code == keys.enter then
|
|
switch_screen(game)
|
|
elseif code == keys.esc then
|
|
quit = true
|
|
end
|
|
end
|
|
end
|
|
|
|
function title.entry()
|
|
draw.enableBuffer(false)
|
|
music.play(music.tracks.intro)
|
|
draw.clear()
|
|
screen.redraw = true
|
|
end
|
|
|
|
function title.draw()
|
|
-- boxworld logo
|
|
for j = 0, 1 do
|
|
for i = 0, 6 do
|
|
sprites:blit(160 - 70 + i * sprite_size, 80 + j * sprite_size, 14 + i + j * 7)
|
|
end
|
|
end
|
|
|
|
draw.text(160, 140, "Original by Jeng-Long Jiang, 1992",fg,bg,draw.align_center)
|
|
draw.text(160, 160, "Reprogram by maple \"mavica\" syrup, 2025",fg,bg,draw.align_center)
|
|
draw.text(160, 180, "Select level",fg,bg,draw.align_center)
|
|
draw.text(160, 190, " < " .. game.level .. " > ",fg,bg,draw.align_center)
|
|
end
|
|
|
|
function game.entry()
|
|
-- load level
|
|
game.leveltable = {}
|
|
local row = {}
|
|
local longest = 0
|
|
local str = game.levelstrings[game.level]
|
|
for i = 1, #str do
|
|
if str:sub(i,i) == '\n' then
|
|
table.insert(game.leveltable, row)
|
|
if #row > longest then longest = #row end
|
|
row = {}
|
|
elseif str:sub(i,i) == '6' then -- player
|
|
game.player_pos = {#row + 1, #game.leveltable + 1}
|
|
game.player_direction = "D"
|
|
table.insert(row, '2') -- empty floor under player
|
|
else
|
|
table.insert(row, str:sub(i,i))
|
|
end
|
|
end
|
|
game.draw_offset = {140 - longest/2*sprite_size, 140 - #game.leveltable/2*sprite_size}
|
|
game.moves = {}
|
|
collectgarbage()
|
|
|
|
draw.enableBuffer(1)
|
|
draw.clear()
|
|
screen.redraw = true
|
|
end
|
|
|
|
function game.draw()
|
|
for j = 1, #game.leveltable do
|
|
local row = game.leveltable[j]
|
|
for i = 1, #row do
|
|
local pos = {game.draw_offset[1] + i * sprite_size, game.draw_offset[2] + j * sprite_size}
|
|
if row[i] == "1" then -- wall
|
|
sprites:blit(pos[1], pos[2], 0)
|
|
elseif row[i] == "2" then -- floor
|
|
sprites:blit(pos[1], pos[2], 1)
|
|
elseif row[i] == "3" then -- floor with goal
|
|
sprites:blit(pos[1], pos[2], 1)
|
|
sprites:blit(pos[1], pos[2], 4)
|
|
elseif row[i] == "4" then -- box
|
|
sprites:blit(pos[1], pos[2], 2)
|
|
elseif row[i] == "5" then -- box on goal
|
|
sprites:blit(pos[1], pos[2], 3)
|
|
end
|
|
end
|
|
end
|
|
|
|
local pos = {
|
|
game.draw_offset[1] + game.player_pos[1] * sprite_size,
|
|
game.draw_offset[2] + game.player_pos[2] * sprite_size
|
|
}
|
|
sprites:blit(pos[1], pos[2], game.player_sprites[game.player_direction][game.player_flip+1])
|
|
|
|
if game.player_direction == "W" then
|
|
draw.text(160, 160, "You win !!!",fg,bg,draw.align_center)
|
|
draw.text(160, 170, "Press ENTER for next level",fg,bg,draw.align_center)
|
|
end
|
|
|
|
draw.text(0, 300, "Box World! #" .. game.level .. " - Moves: " .. #game.moves .. " ")
|
|
draw.text(0, 310, "(U)ndo, (R)estart, (ESC) Quit")
|
|
|
|
draw.blitBuffer()
|
|
end
|
|
|
|
function game.check_win()
|
|
for j = 1, #game.leveltable do
|
|
local row = game.leveltable[j]
|
|
for i = 1, #row do
|
|
if row[i] == "4" then -- box not on goal
|
|
return false -- quit as soon as found any
|
|
end
|
|
end
|
|
end
|
|
-- didn't quit? must mean we won
|
|
game.player_direction = "W"
|
|
music.play(music.tracks.victory)
|
|
end
|
|
|
|
function game.process_push(code)
|
|
if game.player_direction == "W" then return end -- don't move if we've already won
|
|
local ahead, ahead2
|
|
if code == keys.up then
|
|
game.player_direction = "U"
|
|
ahead = {game.player_pos[1], game.player_pos[2]-1}
|
|
ahead2 = {game.player_pos[1], game.player_pos[2]-2}
|
|
elseif code == keys.down then
|
|
game.player_direction = "D"
|
|
ahead = {game.player_pos[1], game.player_pos[2]+1}
|
|
ahead2 = {game.player_pos[1], game.player_pos[2]+2}
|
|
elseif code == keys.left then
|
|
game.player_direction = "L"
|
|
ahead = {game.player_pos[1]-1, game.player_pos[2]}
|
|
ahead2 = {game.player_pos[1]-2, game.player_pos[2]}
|
|
elseif code == keys.right then
|
|
game.player_direction = "R"
|
|
ahead = {game.player_pos[1]+1, game.player_pos[2]}
|
|
ahead2 = {game.player_pos[1]+2, game.player_pos[2]}
|
|
end
|
|
|
|
local whats_ahead = game.leveltable[ahead[2]]
|
|
if whats_ahead ~= nil then whats_ahead = whats_ahead[ahead[1]] end
|
|
local whats_ahead2 = game.leveltable[ahead2[2]]
|
|
if whats_ahead2 ~= nil then whats_ahead2 = whats_ahead2[ahead2[1]] end
|
|
|
|
if whats_ahead == '2' or whats_ahead == '3' then -- ahead is floor or empty goal
|
|
game.player_pos = ahead
|
|
table.insert(game.moves, string.lower(game.player_direction))
|
|
elseif whats_ahead == '4' or whats_ahead == '5' then -- ahead is box, whether or not on a goal
|
|
if whats_ahead2 == '2' or whats_ahead2 == '3' then -- box pushed onto floor or goal
|
|
sound.playPitch(2,1,game.push_sound)
|
|
local box_leaves = whats_ahead == '4' and '2' or '3'
|
|
local box_becomes = whats_ahead2 == '2' and '4' or '5'
|
|
game.player_pos = ahead
|
|
game.leveltable[ahead[2]][ahead[1]] = box_leaves
|
|
game.leveltable[ahead2[2]][ahead2[1]] = box_becomes
|
|
table.insert(game.moves, game.player_direction)
|
|
game.check_win()
|
|
end
|
|
end
|
|
screen.redraw = true
|
|
end
|
|
|
|
function game.process_undo()
|
|
if #game.moves < 1 then return false end
|
|
|
|
local return_to, pushed
|
|
local move = table.remove(game.moves)
|
|
game.player_direction = string.upper(move)
|
|
|
|
if string.upper(move) == 'D' then
|
|
return_to = {game.player_pos[1], game.player_pos[2]-1}
|
|
pushed = {game.player_pos[1], game.player_pos[2]+1}
|
|
elseif string.upper(move) == 'U' then
|
|
return_to = {game.player_pos[1], game.player_pos[2]+1}
|
|
pushed = {game.player_pos[1], game.player_pos[2]-1}
|
|
elseif string.upper(move) == 'R' then
|
|
return_to = {game.player_pos[1]-1, game.player_pos[2]}
|
|
pushed = {game.player_pos[1]+1, game.player_pos[2]}
|
|
elseif string.upper(move) == 'L' then
|
|
return_to = {game.player_pos[1]+1, game.player_pos[2]}
|
|
pushed = {game.player_pos[1]-1, game.player_pos[2]}
|
|
end
|
|
|
|
if move == string.upper(move) then -- if move was recorded upper means we moved a box
|
|
local what_box_became = game.leveltable[pushed[2]][pushed[1]]
|
|
local box_leaves = what_box_became == '4' and '2' or '3'
|
|
local box_becomes = game.leveltable[game.player_pos[2]][game.player_pos[1]] == '2' and '4' or '5'
|
|
game.leveltable[pushed[2]][pushed[1]] = box_leaves
|
|
game.leveltable[game.player_pos[2]][game.player_pos[1]] = box_becomes
|
|
end
|
|
game.player_pos = return_to
|
|
|
|
screen.redraw = true
|
|
end
|
|
|
|
function game.input()
|
|
local state, _, code = keys.poll()
|
|
|
|
if state == keys.states.pressed then
|
|
if code == keys.up or code == keys.down or code == keys.left or code == keys.right then
|
|
game.process_push(code)
|
|
elseif code == 'u' then
|
|
game.process_undo()
|
|
elseif code == 'r' then
|
|
game.entry()
|
|
elseif code == keys.esc then
|
|
switch_screen(title)
|
|
elseif game.player_direction == "W" and code == keys.enter then
|
|
-- go to next level when won and pressed enter
|
|
game.level = ((game.level) % #game.levelstrings) + 1
|
|
game.entry()
|
|
end
|
|
end
|
|
collectgarbage()
|
|
end
|
|
|
|
function game.update(now)
|
|
if game.player_direction ~= 'W' and now > game.anim_timer then
|
|
game.player_flip = (game.player_flip + 1) % 2
|
|
game.anim_timer = now + 1
|
|
screen.redraw = true
|
|
end
|
|
end
|
|
|
|
switch_screen(title)
|
|
while true do
|
|
now = os.clock()
|
|
if screen.input then screen.input() end
|
|
if quit then break end
|
|
if screen.update then screen.update(now) end
|
|
if screen.redraw and screen.draw then screen.draw() screen.redraw = false end
|
|
end
|