0JJJ{{{38lqU8P)qVMupm.,< !CTfͫwVE#2TvͫgE#͛xVUfwxf!2Df4#"/"޼xf޼xVUUfxgVUYUU ef2Dfge~w g и!23|wFdffRTfff5"23D42TUCDDDDDDDDDTTUUUTUUUTUUUTUUUTUUUTUUUUUUUDDDDDDDDD̪ JJf f eeUU``fPfPUPUPDDDD̤̤ݤݤDDDDDDDDJJJJJJJDDDNDDNNDDDDODDOODDDDTTUUUTTTTTEDUTDETTEDUTTTTUUUUDDDKDDKKDDDDIDDIIDDDDLDDLLD̪ JJ""!!2 2 ""JJJJJJJJDDDNNDDDDOODDDDTTUUUTUTETEDUTUTUTUUUTUTUUUUUDDDKKDDDDIIDDDDLLDf f oo``ff ݤݤ̤̤DDDD̪DDDDJJJJJJJDDDDDDDTTUUUTEDUTTTDDTTE@UTTTTTUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD:#4$!DDDD#4$3333#""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDTTUUUTUUUTUUUTUUUTUUUTUUUUUUUDDDDDDDDDDDKK D@D@DDDDEEUUD@D@DPDPUPUPDDDDDDDDDDDDDDDDDDDNDDDDDNDDNNDDDDODDOODDDDTTUUUTTTTTEDUTDETTEDUTTTTUUUUDDDKDDKKDDDDIDDIIDDDDLDDLLDDDLL D@D@DDDDDDDDD@D@D@D@D@D@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDNNDDDDOODDDDTTUUUTUTETEDUTUTUTUUUTUTUUUUUDDDKKDDDDIIDDDDLLDDDOOD@D@DDDDNND@D@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDTTUUUTEDUTTTDDTTE@UTTTTTUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDidoDDDTDiXUUdXUPUTUPTPTPeDDDDʻ Ļ DDDtDwwxwwwptwtwpttpDDDD̔  JJf f eeUU``fPfPUPUPDDDDMDD@NDDDDDidHDD@ODoDDDTDiXUTdHDPD@TEDTTTPeDDDDĴLDD@KDDDDtDwwttGDptD@tGDttpDDDD̔LDD@LD JJ""!!2 2 ""DDDDNMDDDDDiOdHDoDDDTDiXUTEdHDPUTUPTPTPeDDDDʴKLDĻ DDDtDwwxtGGDptwtwpttpDDDD̔LLD f f oo``ff DDDTTUUUHDddDDdF@fTUUUB!CB@4$DDD  VUUUP xwwwp DDDD#4$DD"D#4$#C"C $##C ### "@@ @  @`p@`p@ J D @Df`fpwD `ww@D`fwwwDD`fww fffpDDffww@DffpwDDD fw@D`fpw@D `ffpw D@ DDD@DD DDD @DD D @DD D@ DD DDD DD@DD D@ D@ @DD D @D D@ DDD @ @DD DD @D DD DD DDD@  @ ݬ f`f D@f`f DDDf@DDf` DDDff@DDffDf`f @DDff` D@` DD` DDDff DDf@DDf`` D@f` D@f` @DDfffDf``@Dfff D@`ff DDD` @f` @DDff DDf`` @Df DD`fDDf DDD DADDD DADDAD DADDAD DADDD ``VUVUP @ VUUUP xwwwp . #33333333$$3#3%%3!!!!$$$$$$$$$$$3%%%33!!!!!!!$$$#%%333!!!!!!!"$$$$$$$$%%%3333!!!!!!!$$$$%%3333!!!!!!!333333333$$$$$$$$$$%%%33333$$$$$$$$$$$$$$!!!!!!!$3$$3$%%33333333"!!!!!!!##""""$$$$$$$$$$%%%3333333!!!!!!!333333""""""33333$$$$3%%33333333!!!!!!!"""$$$$$$$$$$$%%%33333333!!!!!!!""""""3$$3%%33333333333!!!""""*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++, !''''''''333333333333333############333333333333333333333'!!!$$$$$$$3####3&&&&&&&&&333!!''''''''3##########&&&&&&&&&&!$!'!$$$$$$$3###########33&&&&&&&&&&(((((('''''''''''!!!''''''''3##3#######&&&&&&&##3##333333(((($$'!$$$$$$$3############!"#&&&&&&&&%%!$$$'!''''''''3############&&&&&&&&&&&&'!$$$$$$$3######&&&&&&&&&&&'''!!!''''''''########&&&&&&&&&&&&&333333#333333$'!$$$$$$$######%&$3&"'#!''''''''!######333333333333'*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,*+++++++++++++++,JKKKKJKKKLlmmJKKLJKKLJKKKKKKKKKKKKKKKKKK<jj]^_kkjjj^]kj_]kjjjj[[[[\kjjjo_kjo^kjjjjkkjjKKj[[\j]_kjjjjkkjjj^]kj^okjjjjkkjjj_okj_]kjjZ[[[[z{{Z[[[Z[[[Z[[MZ[[MjjJKKLJKKLJLJLJKKjjjj_^kjkjkjjjjKLj[[\j;=kj[[jjjkjkjkjjjZ[[Mz{z{Z[[jjJKKLmlJKKJKLZ[[[[[[[[[[[[[[[[[[=jo]kjkjj]kj]_kjkj[[j[[\j_ok|<:NjjkZ[[MZMZ[[z{  !$"%3647EHFIWZX[i l j m { ~| pP sP4 p!"$%'()*+,-..////////////////   "(,////////////////////////// @pApBpBpCpC`D`DPDPE@E@F0G G HHIIJJJKLLMMNNOO@pO`APOPB@O@C@O0D0O EOGOHOIOJOKOLOMOOOOOb 00@00 РР p0݀>;84200000000000123494567;8: ;-=M>?^|000000????????????????????????pА@CEGIKLMNOOOOOOOOOOOOOOOOOO ``````````````````````````````T0``````````````````````````````T0p0А @pB@GLLLLLLMOOOOOOOOOOOOOOOOOOOO @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DPRWY]_________________________VVVVVVVVVVVWWWWWWXXXXXXXXXXXXXjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj%  00@@PP``ppp`pP`@P0@ 0b  00@@PP``ppp`pP`@P0@ 0@@@@eeee @ @eeeee)@)e@e@)e)@e)@)e@e@)e)@e) )e e )e) e) )e e )e) eD.PeWPPe PefPePeWPPe  Pe PePeWPPe  Pe Pe`0GG''GG''GG''GG'G ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 'e4e4e4e4e4ee4e;fe;fee;fe;fe;fee;fPg Pg PghPgPg Pg Pg Pg ' ''' ' ''' ' ''' ' '' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '0@0@Pg 0@0f@PgPgPg0@0@Pg 0@0@PgPgPg ' ''' ' ''' ' ''' ' ''''' ' ''' ' ''' ' ''' ''e9fe9fe9fe9fe9fee9feLfeLfeeLfeLfeLfeeLfe9fe9fe9fe9fe9fee9fe4e4ee4e4e 4ee4e9fe9fe9fe9fe9fee9fe4e4ee4e4e 4e$0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4ϊ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 04 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0$ϊ0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 FF&FFFgggggggggggggggggggg & & & &FFF0LllLllTLllLllLllLllLllLllLllLllLllLllLllLllLllLlleeeeeeeeeeeeeeeeG4GGG4G4G4GGG4G4G4GGG4G4G4GGG4G4KllDllGllKllIllGllFllNfllDllFllGllKllIllGllFllNfllK L LD L LG L LK L LI L LG L LF L LNf L LD L LF L LG L LK L LI L LG L LF L LNf L L 'Lf 'G 'Lf 'Lf 'Lf 'G 'Lf 'Lf 'Lf 'G 'Lf 'Lf 'Lf 'G 'Lf 'LfK䆀D䆀G䆀K䆀I䆀G䆀F䆀NfD䆀F䆀G䆀K䆀I䆀G䆀F䆀Nf4444KDGKIGFNfDFGKIGFNfLfLfLfLfKDGKIGFNfDFGKIGFNf00Mm m mZmPem m mZmPemPe Mm m m mPe m m[mPe mPeMm m m mPem m m mPemPe Mm m m mPe m m mPe mPeLLLLLLLLLLLLLLLL L L L L L L L LLLLLLLLLLLLLLLLLLLLLLLLL L L L L L L L LLLLLLLLLmPeM mPe mPemPemPemmmPemmmPemmmPemmLLLLLLLL , , , , , , , ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/,mPePePem mPePePePePemPePePem mPePePePePeK:=DFK:=DFe F Fe F FeFFeFFe F Fe F FeFFeFe F Fe F FeFFeFFe F Fe F FeFFeFmPePePem mPePePePePemPePePem mPePePePe Pe Pe PePePePePe Pe Pe PePePePePe Pee&&e&&e&&e&&e & &e & &e&&e&e&&e&&e&&e&&e & &e & &e&&e&e&&e&&e  e  eeeeeeeemPePePeϜm mPePePePePepmPe`PePPeOm mPe0Pe PePePeK:=DFpK`P:@0= DFe F䞁 Fe Fԝ FeFƜFeFFe F Fe F FeFFeFte Fd Fe FT FeFFFeF6Fe F-Fe FFeFFeF` 02001Qaqaqa q a  BMM޷޷`(`((H ' %'p,< !A %E %E ! %E?  @D@D@DDDD@D@D@@DD@DDD@DD@@DDDDD@DDD@D@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDNDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDNDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD D@D@@DDD@D@DD@DD@DDDD@DDDD@DD@DDD@DDDD@DDDDDD@D@DDDD Ь Ь DDD@D@D@DD@DDDDDD@D@D@DDDDDD@DDD@DDD f`fffff `ff`fff @DD@DD@DD@DDDD@DDDD@D@@D@DD@@DD@DD@Dpwpwwwwwwwwpwww  @ DDD@DDDDDDDDD@DDDD@DD@DDD@DDD DD@D@D@@D@D@DDDDDD@D@DDD@DDD@D@D `f`f`ff  @@DDDDD@DND@D@DD@DDD@D@DD@DDD@D@DDDDDDD@D@DD@wwwwwwwwpw@@ ` `  @@DDDD@DD@DDpDDpD@DDD@@DDDD@D@DDD@DDD@@  `` @@DDDD@DD@DDpDDpDDD@DD@D@D@DpP-- title: Crill-80 -- author: Ravetracer -- desc: This is a fan remake of the awesome game "Crillion" on the C64 by Oliver Kirwa -- script: lua -- saveid: de.ravetracer.crill80 -- Still TODO: -- - deeper game testing plyr = { x=0,y=0,w=4,h=4,dY=1,dX=0, xIncF=0,xIncD=.2,curCol=1,push=false, dead=false,deadSndPlayed=false,deadFrames=5,deadCur=1, score=0,lives=4,bonusScore=0, update = function(self) self.x = self.x + self.dX self.y = self.y + self.dY if self.dX < 0 then self.dX = self.dX + .2 if self.dX > 0 then self.dX = 0 self.push = false end else self.dX = self.dX - .2 if self.dX < 0 then self.dX = 0 self.push = false end end end, setPos = function(self, x, y) self.x = x self.y = y end, incScore = function(self, num) self.score = self.score + num end, incBonus = function(self, num) self.bonusScore = self.bonusScore + num end } colors = { {name = "colodore", data="0000084a4a4a7b7b7bb2b2b2fffff6813338c46c715538008e5029edf171a9ff9f56ac4d75cec8706deb2e2c9b8e3c97"}, {name = "pepto", data="0000084444446c6c6c959595ffffff68372b9a67594339006f4f25b8c76f9ad284588d430ba4b26c5eb53528796f3d86"} } opts = { tileSet=1,palIdx=1,plyMusic=true,plySfx=true,gameTrack=1 } stars = {sObjs={},minX=0,maxX=0,minY=0,maxY=0,maxSpeed=0,num=0} function stars:init(minX, maxX, minY, maxY, maxSpeed, numStars) self.minX=minX self.maxX=maxX self.minY=minY self.maxY=maxY self.maxSpeed=maxSpeed self.num=numStars for i = 1, self.num, 1 do self.sObjs[i] = {math.random(self.minX, self.maxX), math.random(self.minY, self.maxY), math.random(1, self.maxSpeed)} end end function stars:draw() for k, p in pairs(self.sObjs) do pix(p[1], p[2], 14) p[1] = p[1] - p[3]/2 if p[1] < 5 then p[1] = self.maxX p[2] = math.random(self.minY, self.maxY) p[3] = math.random(1, self.maxSpeed) end end end bg = {} hiScores = {} curState = "title" states = {} State = {initialized=false,timer=0} function State:new (o) o = o or {} setmetatable(o, self) self.__index = self return o end function State:setUp(name) self.name = name end function State:incTm() self.timer = self.timer + 1 end function State:init() self.initialized = true end function State:run() end function State:getName() return self.name end function loadLevel(num) -- entries: -- 1. map start x -- 2. map start y -- 3. plyr start x (in map cell) -- 4. plyr start y (in map cell) -- 5. plyr y direction (-1 or 1) -- 6. plyr color (1-6) local lvlCfg = { {17, 0, 14, 11, -1, 1}, -- 1 {34, 0, 1, 2, 1, 1}, {51, 0, 2, 3, -1, 1}, {68, 0, 11, 11, 1, 1}, {85, 0, 2, 2, 1, 3}, -- 5 {102, 0, 2, 10, 1, 5}, {119, 0, 12, 11, -1, 3}, {136, 0, 8, 6, 1, 2}, {153, 0, 14, 2, -1, 4}, {170, 0, 1, 5, -1, 1}, -- 10 {187, 0, 8, 10, 1, 3}, {204, 0, 1, 3, 1, 3}, {221, 0, 14, 9, 1, 2}, {17, 13, 13, 8, 1, 4}, {34, 13, 9, 6, 1, 4}, -- 15 {51, 13, 14, 11, 1, 4}, {68, 13, 7, 5, 1, 3}, {85, 13, 15, 5, 1, 4}, {102, 13, 2, 1, -1, 6}, {119, 13, 10, 8, 1, 6}, -- 20 {136, 13, 1, 11, 1, 5}, {153, 13, 8, 6, 1, 2}, {170, 13, 14, 11, 1}, {187, 13, 5, 4, 1, 4}, {204, 13, 10, 2, 1, 5}, -- 25 {0, 13, 2, 2, 1, 1} -- test } for y = 0, 13, 1 do memcpy(0x8000+y*240,(0x8000+lvlCfg[num][1])+y*240+(240*lvlCfg[num][2]), 17) end plyr:setPos(lvlCfg[num][3]*8+1,lvlCfg[num][4]*8) plyr.dY = lvlCfg[num][5] plyr.curCol = lvlCfg[num][6] -- counting blocks local blocks = 0 for x = 0, 16, 1 do for y = 0, 12, 1 do tId = mget(x, y) if hasValue({1,2,3,4,5,6}, tId) then blocks = blocks + 1 end end end game.Lvl.blocks = blocks game.Lvl.bonus = 999 game.Lvl.num = num end title = State:new() title:setUp("title") function title:init() loadOptions() loadHiScores() self.showOpts = false stars:init(0, 239, 0, 135, 3, 100) setTiles(opts.tileSet) setPalette(opts.palIdx) if opts.plyMusic then music(0) end self.initialized = true self.showScores = false self.optsCy=50 self.optEntry=1 end function title:infoScreen() map(0, 34, 30, 7, 0, 10, 0) cntr("RAVETRACER PRESENTS", 0) cntr("A REMAKE OF THE AWESOME GAME", 65) cntr("- CRILLION -", 75) cntr("BY OLIVER KIRWA IN 1987/1988", 85) cntr("DESIGN, SOUND, GRAPHICS AND", 95) cntr("PROGRAM BY RAVETRACER IN 2021", 105) end function title:hiScores() cntr("TOP EIGHT OF -CRILL-80-", 0) for x = 1, 8, 1 do font(x, 50, 10+x*10) font(hiScores[x].score, 70, 10+x*10) font(hiScores[x].name, 140, 10+x*10) end end function title:run() cls(0) stars:draw() if self.timer > 600 then self.showScores = not self.showScores self.timer = 0 end if self.showScores then self:hiScores() else self:infoScreen() end cntr("PRESS ~/s FOR OPTIONS", 115) cntr("PRESS }/a TO START", 125) if btnp(7) and self.showOpts == false then self.showOpts = true self.optsCy = 50 self.optEntry = 1 end if self.showOpts then optionScreen() else if btnp(6) then curState = "game" end end self:incTm() end table.insert(states, title) game = State:new() game:setUp("game") function game:init() if opts.plyMusic then music(opts.gameTrack) end self.Lvl = { blocks = 0, bonus = 0, num = 0, decBonus = function(self, num) self.bonus = self.bonus - num if self.bonus < 0 then self.bonus = 0 end end, decBlocks = function(self, num) self.blocks = self.blocks - num end } plyr.lives = 4 plyr.score = 0 plyr.dead = false -- for level clearing effect self.clrLevel = false self.clrAnim = {69, 68, 67, 66, 65, 66, 67, 68, 69, 0} self.curClrAnim = 1 self.addBonus = false self.bonusPitch = 20 self.level = 1 self.randomLevel = false self.movingBlocks = {} self.explosions = {} loadLevel(game.level) stars:init(0, 135, 0, 104, 3, 100) self.initialized = true gameover.initialized = false end function game:run() cls(0) stars:draw(0, 135, 0, 100, 3, 100) map(0, 0, 17, 13, 0, 0, 0) -- draw player if plyr.dead == false and self.clrLevel == false and self.addBonus == false then spr(256 + plyr.curCol, plyr.x, plyr.y, 0) checkColorChange() chkColl() end self:handleDestroyedBlocks() self:handleMovingBlocks() playerMovement() showScore() calcBonus() self.Lvl:decBonus(.15) clearLevel() end function game:handleDestroyedBlocks() for k, v in pairs(self.explosions) do spr(v.sId+math.floor(v.curFrame), v.x, v.y, 0) v.curFrame = v.curFrame + v.frmSpeed if v.curFrame > v.aLength then table.remove(self.explosions, k) end end if self.Lvl.blocks < 1 and self.clrLevel == false then self.addBonus = true end end function game:handleMovingBlocks() for k, v in pairs(self.movingBlocks) do spr(v.sId, v.x, v.y, 0) local tId = fget(tileId(v.x+v.dX, v.y+v.dY), 0) if v.dY > 0 then tId = fget(tileId(v.x, v.y+8), 0) end if v.dX > 0 then tId = fget(tileId(v.x+8, v.y), 0) end if tId then mset((v.x)//8, (v.y)//8, v.orig) table.remove(self.movingBlocks, k) break end v.y = v.y + v.dY * v.spd v.x = v.x + v.dX * v.spd v.mv = v.mv + v.spd if v.mv > 8 then mset((v.x+1)//8, (v.y+1)//8, v.orig) table.remove(self.movingBlocks, k) end end end table.insert(states, game) gameover = State:new() gameover:setUp("gameover") function gameover:init() if opts.plyMusic then music(5) end self.initialized = true end function gameover:run() cls(0) map(0, 41, 16, 10, 50, 20, 0) cntr("PRESS ~/s TO CONTINUE", 110) if btnp(7) then game.initialized = false title.initialized = false if plyr.score > hiScores[8].score then curState = "scoreentry" else curState = "title" end end end table.insert(states, gameover) scoreEntry = State:new() scoreEntry:setUp("scoreentry") function scoreEntry:init() self.initialized = true self.plyrName = "" self.timer = 0 end function scoreEntry:run() sel = sel or 1 cls(0) cntr("CONGRATULATIONS", 10) cntr("YOU REACHED A HI SCORE", 20) cntr("FOR THE TOP EIGHT", 30) cntr("OF CRILL-80", 40) cntr("PICK YOUR NAME", 60) cntr("use left/right and }/a", 120) for x = 1, 26, 1 do font(string.char(64+x), x*8, 90) end font("[", 216, 90) font("]", 224, 90) spr(210, math.floor(sel)*8, 100) if btn(3) then sel = sel + .15 if sel > 29 then sel = 1 end end if btn(2) then sel = sel - .15 if sel < 1 then sel = 28 end end if btnp(6) then if sel < 27 then if string.len(self.plyrName) < 9 then self.plyrName = self.plyrName .. string.char(96+math.floor(sel)) end end if math.floor(sel) == 27 then self.plyrName = string.sub(self.plyrName, 1, string.len(self.plyrName) - 1) end if math.floor(sel) == 28 then saveScore(plyr.score, self.plyrName) curState = "title" self.initialized = false end end vals = cntr(self.plyrName, 80) spr(211+self.timer%60//30, vals[1]+vals[2], 80) self:incTm() end table.insert(states, scoreEntry) function playerMovement() if btnp(4) then opts.plyMusic = not opts.plyMusic if opts.plyMusic then music(opts.gameTrack) else music() end saveOptions() end if btnp(7) then opts.plySfx = not opts.plySfx saveOptions() end if plyr.dead == false and game.clrLevel == false then if btn(2) and plyr.push == false then plyr.dX = - 1 end if btn(3) and plyr.push == false then plyr.dX = 1 end if btnp(5) then doPlayerDie() if plyr.deadSoundPlayed == false then if opts.plySfx then sfx(8, "C-5", -1, 3) end plyr.deadSoundPlayed = true end end plyr:update() else playerDied() end end function playerDied() if game.clrLevel == true then return end spr(288 + plyr.deadCur, plyr.x, plyr.y, 0) plyr.deadCur = plyr.deadCur + .2 if plyr.deadCur > plyr.deadFrames then plyr.deadCur = 6 plyr.deadCur = 1 plyr.lives = plyr.lives - 1 if plyr.lives < 1 then curState = "gameover" end game.clrLevel = true end end function chkColl() -- check walls dFlags = {1, 5, 6, 7} if plyr.dY > 0 and collide(plyr,"down", {0}) then if collide(plyr, "down", dFlags, 51) then doPlayerDie() elseif collide(plyr, "down", {0}, plyr.curCol) then destroyTile(plyr.x+2, plyr.y+plyr.h+1) elseif collide(plyr, "down", {0}, plyr.curCol+32) then moveBlock(plyr.x+2, plyr.y+plyr.h+1, 0, 1) if opts.plySfx then sfx(9, "C-4", -1, 3) end else if opts.plySfx then sfx(6, "C-4", -1, 3) end end plyr.dY = -plyr.dY end if plyr.dY < 0 and collide(plyr,"up", {0}) then if collide(plyr, "up", dFlags, 51) then doPlayerDie() elseif collide(plyr, "up", {0}, plyr.curCol) then destroyTile(plyr.x+2, plyr.y-1) elseif collide(plyr, "up", {0}, plyr.curCol+32) then moveBlock(plyr.x+2, plyr.y-1, 0, -1) if opts.plySfx then sfx(9, "C-4", -1, 3) end else if opts.plySfx then sfx(6, "C-4", -1, 3) end end plyr.dY = -plyr.dY end if plyr.dX > 0 and collide(plyr,"right", {0}) then if collide(plyr, "right", dFlags, 51) then doPlayerDie() elseif collide(plyr,"right",{0},plyr.curCol) then destroyTile(plyr.x+plyr.w+1, plyr.y+2) elseif collide(plyr,"right",{0},plyr.curCol+32) then moveBlock(plyr.x+plyr.w+1, plyr.y+2, 1, 0) if opts.plySfx then sfx(9, "C-4", -1, 3) end else if opts.plySfx then sfx(6, "C-4", -1, 3) end end plyr.dX = -.8 plyr.push = true end if plyr.dX < 0 and collide(plyr,"left", {0}) then if collide(plyr,"left",dFlags,51) then doPlayerDie() elseif collide(plyr,"left",{0},plyr.curCol) then destroyTile(plyr.x-1, plyr.y+2) elseif collide(plyr,"left",{0},plyr.curCol+32) then moveBlock(plyr.x-1, plyr.y+2, -1, 0) if opts.plySfx then sfx(9, "C-4", -1, 3) end else if opts.plySfx then sfx(6, "C-4", -1, 3) end end plyr.dX = .8 plyr.push = true end if plyr.deadSoundPlayed == false and plyr.dead then if opts.plySfx then sfx(8, "C-5", -1, 3) end plyr.deadSoundPlayed = true end end function doPlayerDie() plyr.dead = true plyr.deadSoundPlayed = false end function collide(obj, aim, flags, tId) local x,y,w,h = obj.x, obj.y, obj.w, obj.h local x1,y1,x2,y2,tx,ty = 0,0,0,0,0,0 tId = tId or nil if aim=="left" then x1=x-1 y1=y+2 x2=x-1 y2=y+h-2 elseif aim=="right" then x1=x+w+1 y1=y+2 x2=x+w+1 y2=y+h-2 elseif aim=="up" then x1=x+2 y1=y-1 x2=x+w-2 y2=y-1 elseif aim=="down" then x1=x+2 y1=y+h x2=x+w-2 y2=y+h end tile = tileId(x1, y1) x1 = x1//8 y1 = y1//8 x2 = x2//8 y2 = y2//8 if chkMultFlags(mget(x1,y1), flags) or chkMultFlags(mget(x1,y2), flags) or chkMultFlags(mget(x2,y1), flags) or chkMultFlags(mget(x2,y2), flags) then if tId then if tile == tId then return true else return false end else return true end else return false end end function showScore() local hiScore = hiScores[1].score if plyr.score > hiScore then hiScore = plyr.score end if plyr.bonusScore >= 10000 then plyr.lives = plyr.lives + 1 if plyr.lives > 7 then plyr.lives = 7 else if opts.plySfx then sfx(11, "C-5", 15, 3) end end plyr.bonusScore = 0 end font("SCORE", 170, 0) font(plyr.score, 170, 8) font("BEST", 170, 20) font(hiScore, 170, 28) font("LEVEL", 170, 40) font(game.Lvl.num, 170, 48) font("LIVES", 170, 60) font(plyr.lives, 170, 68) font("BLOCKS", 170, 80) font(game.Lvl.blocks, 170, 88) font("BONUS", 170, 100) font(math.floor(game.Lvl.bonus), 170, 108) font("|/x - lose a life and reset", 0, 120) if opts.plyMusic then font("{/y - turn music off", 0, 105) else font("{/y - turn music on", 0, 105) end if opts.plySfx then font("~/s - turn sfx off", 0, 112) else font("~/s - turn sfx on", 0, 112) end end function calcBonus() if game.addBonus then game.Lvl:decBonus(5) if opts.plySfx then sfx(10, math.floor(game.bonusPitch), 3, 3) end plyr:incScore(15) plyr:incBonus(15) game.bonusPitch = game.bonusPitch + .15 if game.Lvl.bonus < 1 then game.bonusPitch = 20 game.addBonus = false game.clrLevel = true if not game.randomLevel then game.level = game.level + 1 else game.level = math.random(1,25) end end end end function checkColorChange() local cols = 6 for i = 1, 6, 1 do if checkColl({0, 7}, 16+i, false) then plyr.curCol = i if opts.plySfx then sfx(0, "C-5", -1, 3) end end end end function checkColl(flags, tId) local dirs = {{1, -1}, {1, 5}, {-1, 1}, {5, 5}} for k, v in pairs(dirs) do if chkMultFlags(tileId(plyr.x+v[1], plyr.y+v[2]), flags) and tileId(plyr.x+v[1], plyr.y+v[2]) == tId then return true end end return false end function destroyTile(x, y) clearTile(x, y) addExplo(x, y) if opts.plySfx then sfx(7, "C-5", -1, 3) end game.Lvl:decBlocks(1) plyr:incScore(25) plyr:incBonus(25) end function clearLevel() if game.clrLevel == true and #game.explosions == 0 and #game.movingBlocks == 0 then for x=1, 15, 1 do for y=1, 11, 1 do mset(x, y, game.clrAnim[math.floor(game.curClrAnim)]) end end game.curClrAnim = game.curClrAnim + .2 if game.curClrAnim > 11 then game.curClrAnim = 1 game.clrLevel = false plyr.dead = false loadLevel(game.level) end end end function chkMultFlags(tId, flags) c = false for k, v in pairs(flags) do c = fget(tId, v) end return c end function tileId(x,y) return mget((x)//8,(y)//8) end function clearTile(x,y) mset((x)//8, (y)//8, 0) end function addExplo(x, y) local expl = { x = ((x)//8)*8, y = ((y)//8)*8, sId = 273, aLength = 8, curFrame = 1, frmSpeed = .3 } table.insert(game.explosions, expl) end function moveBlock(x, y, dX, dY) local block = { x = ((x)//8)*8, y = ((y)//8)*8, sId = plyr.curCol+32, spd = .6, mv = 0, dX = dX, dY = dY, orig = mget((x)//8, (y)//8) } mset((x)//8, (y)//8, 0) table.insert(game.movingBlocks, block) end function setTiles(index) local indexes = {144, 80} local indexesPlyr = {144, 128} for y = 0, 3, 1 do for x = 0, 8, 1 do memcpy(0x4000+(y*16*32)+x*32,0x4000+(y*16*32)+(indexes[index]*32)+x*32, 32) end end for x = 0, 5, 1 do memcpy(0x6000+x*32, 0x6000+(indexesPlyr[index]*32)+x*32, 32) end end function setPalette(index) local pal=colors[index].data local ADDR=0x3FC0 for i=1,#pal,2 do poke(ADDR+i//6*3+i//2%3,tonumber(pal:sub(i,i+1),16)) end end function optionScreen() local tSet = {"modern", "classic"} local pals = {"colodore", "pepto"} map(30, 34, 20, 13, 45, 25) font("OPTIONS", 100, 32) font("GFX", 75, 47) font(tSet[opts.tileSet], 125, 47) font("SFX", 75, 57) if opts.plySfx then font("on", 125, 57) else font("off", 125, 57) end font("MUSIC", 75, 67) if opts.plyMusic then font("on", 125, 67) else font("off", 125, 67) end font("TRACK", 75, 77) font(opts.gameTrack, 125, 77) font("COLOR", 75, 87) font(pals[opts.palIdx], 125, 87) font("reset options", 80, 97) font("BACK", 110, 107) spr(209, 60, title.optsCy) if btnp(1) then title.optsCy = title.optsCy + 10 if title.optsCy > 110 then title.optsCy = 110 else title.optEntry = title.optEntry + 1 end elseif btnp(0) then title.optsCy = title.optsCy - 10 if title.optsCy < 50 then title.optsCy = 50 else title.optEntry = title.optEntry - 1 end end if btnp(6) then if title.optEntry == 1 then opts.tileSet = opts.tileSet + 1 if opts.tileSet > 2 then opts.tileSet = 1 end setTiles(opts.tileSet) elseif title.optEntry == 2 then opts.plySfx = not opts.plySfx elseif title.optEntry == 3 then opts.plyMusic = not opts.plyMusic saveOptions() loadOptions() elseif title.optEntry == 4 then opts.gameTrack = opts.gameTrack + 1 if opts.gameTrack > 4 then opts.gameTrack = 1 end if opts.plyMusic then music(opts.gameTrack) end elseif title.optEntry == 5 then opts.palIdx = opts.palIdx + 1 if opts.palIdx > 2 then opts.palIdx = 1 end setPalette(opts.palIdx) elseif title.optEntry == 6 then resetOptions() loadOptions() elseif title.optEntry == 7 then saveOptions() title.showOpts = false end end end function loadOptions() -- tile set m = pmem(0) if m ~= 0 then opts.tileSet = m else opts.tileSet = 1 end setTiles(opts.tileSet) -- palette m = pmem(1) if m ~=0 then opts.palIdx = m else opts.palIdx = 1 end setPalette(opts.palIdx) -- play music m = pmem(2) if m ~= 0 then if m == 1 then opts.plyMusic = false music(-1) else opts.plyMusic = true music(0) end else opts.plyMusic = true music(0) end -- play sfx m = pmem(3) if m ~= 0 then if m == 1 then opts.plySfx = false else opts.plySfx = true end else opts.plySfx = true end -- game music track m = pmem(4) if m ~= 0 then opts.gameTrack = m else opts.gameTrack = 1 end end function saveOptions() pmem(0, opts.tileSet) pmem(1, opts.palIdx) pm = 1 if opts.plyMusic == true then pm = 2 end pmem(2, pm) ps = 1 if opts.plySfx == true then ps = 2 end pmem(3, ps) pmem(4, opts.gameTrack) end function resetOptions() for x = 0, 4, 1 do pmem(x, 0) end end function hasValue(tab, val) for k, v in ipairs(tab) do if v == val then return true end end return false end function clearHiScores() for x = 10, 89, 1 do pmem(x, 0) end end function loadHiScores() hiScores = {} for x = 1, 8, 1 do curScore = pmem(x*10) curName = "" for y = 1, 9, 1 do local cID = pmem(x*10+y) if cID > 0 then curName = curName .. string.char(cID) else curName = curName .. " " end end table.insert(hiScores, {score = curScore, name = curName}) end table.sort(hiScores, function(a, b) return (a.score > b.score) end) end function saveScore(score, playerName) hiScores[8] = {score = score, name = playerName} for x = 1, 8, 1 do curScore = pmem(x*10, hiScores[x].score) curName = hiScores[x].name for y = 1, 9, 1 do local cID = string.byte(string.sub(curName,y,y+1)) if cID then pmem(x*10+y, cID) else pmem(x*10+y, 0) end end end loadHiScores() end function cntr(text, ypos) width = font(text, 0, -20) px = (240-width)//2 font(text, px, ypos) return {width, px} end function TIC() for k, v in pairs(states) do if v:getName() == curState then if v.initialized == false then v:init() end v:run() end end end