-- title: The Right Coin -- author: Fabien Freling, Pascal Batty -- desc: Ludum Dare 44 -- script: lua t=0 s=8 -- sprite/cell size w=240 mw=w/s h=136 mh=h/s GameState = { start=0, game=1, gameover=2, market=3 } currentState = GameState.game life=100 coinBlue=0 valueBlue=1.0 coinRed=0 valueRed=5.0 coinYellow=0 valueYellow=0.8 MarketOptions = { blue=0, red=1, yellow=2, all=3, done=4 } marketSelection = MarketOptions.blue solids={} do local sols={1, 2, 3, 17} for i,v in pairs(sols) do solids[v]=true end end function sol(x,y) return solids[mget(x//8,y//8)] end g = .3 j = -4 anis={ idle={257,257,258,258,259,259,260,260}, run= {273,274,275,276}, jump={289}, fall={290}, coin={ blue= {321,321,322,322,323,323,324,324}, red= {337,337,338,338,339,339,340,340}, yellow={353,353,354,354,355,355,356,356}, } } function drawActor(self) self.spr=self.ani[(((t)//3)% #self.ani)+1] local flip if self.isFlipped then flip = 1 else flip = 0 end spr(self.spr, self.x, self.y, 0, 1, flip) end function hitTest(rect1, rect2) return rect1.x < rect2.x + rect2.w and rect1.x + rect1.w > rect2.x and rect1.y < rect2.y + rect2.h and rect1.y + rect1.h > rect2.y end coinCooldown=120 coinTimer=coinCooldown colors={"blue","red","yellow"} spawnLocs={ {x=28*8,y=5*8}, {x=12*8,y=11*8}, {x=20*8,y=9*8}, {x=7*8,y=13*8} } coins={} do -- Coin Coin={ color=colors[1], ani=anis.coin.red, spr=0, x=0,y=0, w=8,h=8, } function Coin:new(o) o = o or {} self.__index = self setmetatable(o, self) return o end function Coin:setColor(c) self.color = c if c=="red" then self.ani=anis.coin.red elseif c=="blue" then self.ani=anis.coin.blue elseif c=="yellow" then self.ani=anis.coin.yellow end end function Coin:draw() drawActor(self) end end function randomColor() return colors[math.random(#colors)] end function coinAtLoc(loc) for i,v in pairs(coins) do if v.x == loc.x and v.y == loc.y then return true end end return false end function randomValidSpawnLoc() local loc repeat loc=spawnLocs[math.random(#spawnLocs)] until not coinAtLoc(loc) return loc end function canAddCoin() return #coins < #spawnLocs end function addRandomCoin() if not canAddCoin() then return end local newCoin=Coin:new() local loc=randomValidSpawnLoc() newCoin:setColor(randomColor()) newCoin.x=loc.x newCoin.y=loc.y coins[#coins + 1]=newCoin coinTimer=coinCooldown end -- MOCK addRandomCoin() addRandomCoin() -- /MOCK do -- Player Player = { spr=0, ani=anis.idle, x=8,y=120, w=8,h=8, vx=0,vy=0, isFlipped=false } function Player:direct() if btn(2) then self.vx = -2 self.isFlipped = true elseif btn(3) then self.vx = 2 self.isFlipped = false else self.vx = 0 end if btnp(0) and self.vy == 0 then self.vy = j end end function Player:update() self:resolve() self.x = self.x + self.vx self.y = self.y + self.vy self:collectCoin() end function Player:resolve() if sol(self.x + self.vx, self.y + self.h-1) or sol(self.x + self.vx + self.w-1, self.y + self.h-1) then self.vx = 0 end local roof = self:distanceToRoof() local floor = self:distanceToFloor() if self.vy < roof then self.vy = roof end if self.vy >= floor then self.vy = floor else self.vy = self.vy + g end if self.vy < 0 then self.ani = anis.jump elseif self.vy > 0 then self.ani = anis.fall elseif not (self.vx == 0) then self.ani = anis.run else self.ani = anis.idle end end function Player:distanceToFloor() local y = 0 while (not sol(self.x + self.vx, self.y + y + self.h)) and (not sol(self.x + self.vx + self.w-1, self.y + y + self.h)) and (self.y + y < 128) do y = y + 1 end return y end function Player:distanceToRoof() local y = 0 while (not sol(self.x + self.vx, self.y + y - 1)) and (not sol(self.x + self.vx + self.w-1, self.y + y - 1)) and (self.y + y > 0) do y = y - 1 end return y end function Player:collectCoin() for i,v in pairs(coins) do if hitTest(self, v) then table.remove(coins,i) if v.color == "blue" then coinBlue=coinBlue+1 elseif v.color == "red" then coinRed=coinRed+1 elseif v.color == "yellow" then coinYellow=coinYellow+1 end end end end function Player:draw() drawActor(self) end end function drawStart() cls(1) print("The Right Coin",80,24) spr(80, 20, 30, 0, 3) spr(81, 50, 50, 0, 2) spr(82, 40, 70, 0, 1) print("You're dying, and medicine",130,40,15,false,1,true) print("ain't cheap. Exchange your",130,50,15,false,1,true) print("most valuable coins for life.",130,60,15,false,1,true) if t%60 > 20 then print("Press Z to start",75,100) end print("Fabien Freling & Pascal Batty", 65, 128, 15, false, 1, true) end function drawGameOver() cls(1) print("You died",80,36,6) print("Press Z",75,96,15) end function drawGame() map(0,0,30,17) p:draw() for i,v in pairs(coins) do v:draw() end drawLife(0,0,0) -- Coins / market local coinsOff=110 spr(80,coinsOff,0) print("x"..coinBlue,coinsOff+s,2) spr(81,coinsOff+25,0) print("x"..coinRed,coinsOff+25+s,2) spr(82,coinsOff+50,0) print("x"..coinYellow,coinsOff+50+s,2) -- spr(84,190,0) print(valueBlue,190,2,8) print(valueRed,206,2,12) print(valueYellow,222,2,14) end function drawLife(x,y,next) spr(83,x,y,0) local color=11 -- green if life < 25 then color=6 -- red elseif life < 50 then color=9 -- orange end local xmin=11 local xmax=107 local lifeLimit=(xmax-xmin)*life/100+xmin for i=lifeLimit,xmax do pix(x+i,y+1,0) pix(x+i,y+2,0) pix(x+i,y+3,0) pix(x+i,y+4,0) pix(x+i,y+5,0) pix(x+i,y+6,0) end if t%60 > 30 then local potential=math.min(xmax,lifeLimit+next) for i=lifeLimit,potential do pix(x+i,y+1,8) pix(x+i,y+2,8) pix(x+i,y+3,8) pix(x+i,y+4,8) pix(x+i,y+5,8) pix(x+i,y+6,8) end end for i=xmin,lifeLimit do pix(x+i,y+1,color) pix(x+i,y+2,color) pix(x+i,y+3,color) pix(x+i,y+4,color) pix(x+i,y+5,color) pix(x+i,y+6,color) end spr(85,x+10,y,0) for i=18,100,8 do spr(86,x+i,y,0) end spr(85,x+100,y,0,1,1) end function drawMarket() -- Background xOff=2 yOff=2 for i=xOff+1, mw-2-xOff do spr(64,i*s,yOff*s,0,1,0,1) spr(64,i*s,(mh-1-yOff)*s,0,1,2,1) end for j=yOff+1, mh-2-xOff do spr(64,xOff*s,j*s,0,1,0,0) spr(64,(mw-1-xOff)*s,j*s,0,1,1,0) end spr(65,xOff*s,yOff*s,0,1,0,1) spr(65,(mw-1-xOff)*s,yOff*s,0,1,0,2) spr(65,(mw-1-xOff)*s,(mh-1-yOff)*s,0,1,0,3) spr(65,xOff*s,(mh-1-yOff)*s,0,1,0,0) for i=xOff+1, mw-2-xOff do for j=yOff+1, mh-2-xOff do spr(66,i*s,j*s,0,1,0,1) end end -- Coins spr(80,4*s,4*s,0) print("x"..coinBlue,5*s+4,4*s+2) print("x"..valueBlue,8*s+4,4*s+2,8) print("= "..math.floor(coinBlue*valueBlue),12*s,4*s+2) spr(83,15*s,4*s,0) print("Buy",20*s,4*s+2) spr(81,4*s,6*s,0) print("x"..coinRed,5*s+4,6*s+2) print("x"..valueRed,8*s+4,6*s+2,12) print("= "..math.floor(coinRed*valueRed),12*s,6*s+2) spr(83,15*s,6*s,0) print("Buy",20*s,6*s+2) spr(82,4*s,8*s,0) print("x"..coinYellow,5*s+4,8*s+2) print("x"..valueYellow,8*s+4,8*s+2,14) print("= "..math.floor(coinYellow*valueYellow),12*s,8*s+2) spr(83,15*s,8*s,0) print("Buy",20*s,8*s+2) print("Buy all",19*s,10*s+2) print("Done",20*s,12*s+2) -- Selection local next=0 if marketSelection == MarketOptions.blue then spr(97,19*s,4*s+1,0) spr(97,22*s,4*s+1,0,1,1) next=math.floor(coinBlue*valueBlue) elseif marketSelection == MarketOptions.red then spr(97,19*s,6*s+1,0) spr(97,22*s,6*s+1,0,1,1) next=math.floor(coinRed*valueRed) elseif marketSelection == MarketOptions.yellow then spr(97,19*s,8*s+1,0) spr(97,22*s,8*s+1,0,1,1) next=math.floor(coinYellow*valueYellow) elseif marketSelection == MarketOptions.all then spr(97,18*s,10*s+1,0) spr(97,24*s,10*s+1,0,1,1) next=math.floor(coinBlue*valueBlue) next=next+math.floor(coinRed*valueRed) next=next+math.floor(coinYellow*valueYellow) elseif marketSelection == MarketOptions.done then spr(97,19*s,12*s+1,0) spr(97,23*s,12*s+1,0,1,1) end drawLife(4*s,12*s,next) end function draw(state) if currentState == GameState.start then drawStart() elseif currentState == GameState.game then drawGame() elseif currentState == GameState.market then drawGame() drawMarket() elseif currentState == GameState.gameover then drawGameOver() end end function update(state) if currentState == GameState.start then if btnp(4) then -- A (Z key) currentState = GameState.game life=100 end elseif currentState == GameState.game then updateGame() elseif currentState == GameState.market then updateMarket() elseif currentState == GameState.gameover then if btnp(4) then -- A (Z key) currentState = GameState.start end end end function updateGame() if life == 0 then currentState = GameState.gameover return end if t%10 ==0 then life=life-1 end if btnp(4) then -- A (Z key) currentState = GameState.market end if btnp(5) then -- B (X key) currentState = GameState.gameover end if coinTimer>0 then coinTimer=coinTimer-1 end if coinTimer == 0 then addRandomCoin() end p:direct() p:update() -- Coin market valueBlue=math.floor((math.sin(t/100)+1)*10)/10 if t%60 == 0 then valueRed=math.random(0,99)/10 end valueYellow=0.1*coinYellow*coinYellow end function updateMarket() if btnp(0) then -- Up if marketSelection ~= MarketOptions.blue then marketSelection = marketSelection - 1 end elseif btnp(1) then -- Down if marketSelection ~= MarketOptions.done then marketSelection = marketSelection + 1 end elseif btnp(4) then -- A (Z key) if marketSelection == MarketOptions.blue then life = life + math.floor(coinBlue*valueBlue) coinBlue=0 elseif marketSelection == MarketOptions.red then life = life + math.floor(coinRed*valueRed) coinRed=0 elseif marketSelection == MarketOptions.yellow then life = life + math.floor(coinYellow*valueYellow) coinYellow=0 elseif marketSelection == MarketOptions.all then life = life + math.floor(coinBlue*valueBlue) life = life + math.floor(coinRed*valueRed) life = life + math.floor(coinYellow*valueYellow) coinBlue=0 coinRed=0 coinYellow=0 elseif marketSelection == MarketOptions.done then currentState = GameState.game end life=math.min(life,100) elseif btnp(5) then -- B (X key) currentState = GameState.game end end p=Player function TIC() update(currentState) draw(currentState) t=t+1 end -- -- 001:0bbbbbbbbb5b55b5b54544545444444444444444444444c44c44444444444444 -- 002:bbbbbbbb5b55b55b454454454444444444444444444444c44c44444444444444 -- 003:bbbbbbb0b55b555b544544554444444544444444444444c44c44444444444444 -- 017:444444444444c4444c444444444444c444444444444444c444c4444444444444 -- 064:03aaaa3703aaaa3703aa3a3703aaaa3703aaaa3703aaaa3703a3aa3703aaaa37 -- 065:03aaaa3703aa3a3303aaaaaa03aaaaaa03aaaa3a033aaaaa0033333300000000 -- 066:7777777777777777777777777777777777777777777777777777777777777777 -- 080:0088880008822880082882800828828008288280082882800882288000888800 -- 081:00cccc000cc66cc00c6cc6c00c6cc6c00c6cc6c00c6cc6c00cc66cc000cccc00 -- 082:00eeee000ee99ee00e9ee9e00e9ee9e00e9ee9e00e9ee9e00ee99ee000eeee00 -- 083:0660066066666666666666666666666666666666066666600066660000066000 -- 084:000008880000880000880000008eeeee08ee00008ee666608666006680000000 -- 085:0333333333000000300000003000000030000000300000003300000003333333 -- 086:3333333300000000000000000000000000000000000000000000000033333333 -- 096:7773377777733377777333373333333333333333777333377773337777733777 -- 097:0006660000660000066000000660000006600000066000000066000000066600 -- -- -- 001:000000000000000000001100000111100000cc00000666600006c66c00080080 -- 002:0000000000001100000111100000cc00000666600006c66c0008008000080080 -- 003:0000000000001100000111100000cc000006c66c000666600008008000080080 -- 004:000000000000000000001100000111100000cc000006c66c0006666000080080 -- 017:0000000000001100000111100000cc00000666600006c66c0008008000000080 -- 018:000000000000000000001100000111100000cc00000666600006c66c00080080 -- 019:0000000000001100000111100000cc00000666600006c66c0008008000080000 -- 020:000000000000000000001100000111100000cc00000666600006c66c00080080 -- 033:00001100000111100000cc0c00066c6000066660000800800080008000000000 -- 034:000011000001111000c0cc0c0006666000066660000800880000800000000000 -- 065:0088880008822880082882800828828008288280082882800882288000888800 -- 066:0008800000882200008828000088280000882800008828000088220000088000 -- 067:0008800000288200002882000028820000288200002882000028820000088000 -- 068:0008800000228800008288000082880000828800008288000022880000088000 -- 081:00cccc000cc66cc00c6cc6c00c6cc6c00c6cc6c00c6cc6c00cc66cc000cccc00 -- 082:000cc00000cc660000cc6c0000cc6c0000cc6c0000cc6c0000cc6600000cc000 -- 083:000cc000006cc600006cc600006cc600006cc600006cc600006cc600000cc000 -- 084:000cc0000066cc0000c6cc0000c6cc0000c6cc0000c6cc000066cc00000cc000 -- 097:00eeee000ee99ee00e9ee9e00e9ee9e00e9ee9e00e9ee9e00ee99ee000eeee00 -- 098:000ee00000ee990000ee9e0000ee9e0000ee9e0000ee9e0000ee9900000ee000 -- 099:000ee000009ee900009ee900009ee900009ee900009ee900009ee900000ee000 -- 100:000ee0000099ee0000e9ee0000e9ee0000e9ee0000e9ee000099ee00000ee000 -- -- -- 001:111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 002:110000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 003:110000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 004:110000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 005:110000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 006:110000000000000000000000000000000000000000000000000010202011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 007:110000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 008:110000000000000000000000000000000000000000001020300000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 009:110000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 010:110000000000000000000000000000000000001030000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 011:110000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 012:110000000000000000000000102020203000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 013:110000000000000000000000111111111100000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 014:110000001020202020300000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 015:110000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- 016:112020202020202020202020202020202020202020202020202020202011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -- -- -- 000:00000000ffffffff00000000ffffffff -- 001:0123456789abcdeffedcba9876543210 -- 002:0123456789abcdef0123456789abcdef -- -- -- 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000 -- -- -- 000:140c1c44243430346d4e4a4e854c30346524d04648757161597dced27d2c8595a16daa2cd2aa996dc2cadad45edeeed6 --