ldjam-44/right_coin.lua

569 lines
21 KiB
Lua

-- 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
-- <TILES>
-- 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
-- </TILES>
-- <SPRITES>
-- 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
-- </SPRITES>
-- <MAP>
-- 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
-- </MAP>
-- <WAVES>
-- 000:00000000ffffffff00000000ffffffff
-- 001:0123456789abcdeffedcba9876543210
-- 002:0123456789abcdef0123456789abcdef
-- </WAVES>
-- <SFX>
-- 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000
-- </SFX>
-- <PALETTE>
-- 000:140c1c44243430346d4e4a4e854c30346524d04648757161597dced27d2c8595a16daa2cd2aa996dc2cadad45edeeed6
-- </PALETTE>