Compare commits
2 commits
f61d3383d4
...
e2703105dd
Author | SHA1 | Date | |
---|---|---|---|
|
e2703105dd | ||
|
74bf2a7045 |
BIN
assets/audio/sfx/buzzer.ogg
Executable file
BIN
assets/audio/sfx/collect.ogg
Executable file
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
assets/sprites/money/beetle.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
assets/sprites/money/chest.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
assets/sprites/money/coin1.png
Normal file
After Width: | Height: | Size: 8 KiB |
BIN
assets/sprites/money/coin2.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
assets/sprites/money/diamond.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/sprites/money/star.png
Normal file
After Width: | Height: | Size: 12 KiB |
|
@ -23,7 +23,7 @@ FISH_AGE_BIG = 65 -- see above, but for big
|
|||
|
||||
FISH_SIZE = 6 -- how many large guppies can you fit on the screen
|
||||
|
||||
FOOTER_HEIGHT = 68
|
||||
HEADER_HEIGHT = 68
|
||||
|
||||
FOOD_HITBOX = 0.08
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ function self.fish(x, y)
|
|||
y = y,
|
||||
size = 0, -- 0 for small, 1 for medium, 2 for big, 3 for king
|
||||
eattimer = 0 + math.random() * 2, -- starts out hungry, with a 2s delay
|
||||
moneytimer = 10 + math.random() * 5, -- min 10s before it can make money
|
||||
dead = false,
|
||||
|
||||
lifetime = 0,
|
||||
|
@ -58,4 +59,19 @@ function self.food(x, y, type)
|
|||
return food
|
||||
end
|
||||
|
||||
function self.money(x, y, type)
|
||||
local money = {
|
||||
x = x,
|
||||
y = y,
|
||||
speed = 0.12,
|
||||
time = math.random(),
|
||||
deathtimer = 0,
|
||||
collected = false,
|
||||
collecttimer = 0,
|
||||
type = type
|
||||
}
|
||||
|
||||
return money
|
||||
end
|
||||
|
||||
return self
|
212
main.lua
|
@ -18,16 +18,20 @@ debug = false
|
|||
|
||||
food = {}
|
||||
feesh = {}
|
||||
money = {}
|
||||
|
||||
local balance = 100
|
||||
|
||||
foodtier = 1
|
||||
foodcount = 1
|
||||
|
||||
footerbuttons = {
|
||||
headerbuttons = {
|
||||
{
|
||||
cost = 100,
|
||||
sprite = 'guppy',
|
||||
openanim = 1,
|
||||
open = true,
|
||||
openanim = 0,
|
||||
open = false,
|
||||
closed = false,
|
||||
func = function()
|
||||
playSound('splash', 0.7, 0.8)
|
||||
table.insert(feesh, constr.fish(math.random(), 0.3))
|
||||
|
@ -37,8 +41,9 @@ footerbuttons = {
|
|||
cost = 200,
|
||||
sprite = 'food',
|
||||
tier = foodtier,
|
||||
openanim = 1,
|
||||
open = true,
|
||||
openanim = 0,
|
||||
open = false,
|
||||
closed = false,
|
||||
func = function(self)
|
||||
self.openanim = 0
|
||||
foodtier = foodtier + 1
|
||||
|
@ -53,8 +58,9 @@ footerbuttons = {
|
|||
cost = 300,
|
||||
sprite = 'foodcount',
|
||||
tier = foodcount,
|
||||
openanim = 1,
|
||||
open = true,
|
||||
openanim = 0,
|
||||
open = false,
|
||||
closed = false,
|
||||
func = function(self)
|
||||
self.openanim = 0
|
||||
foodcount = foodcount + 1
|
||||
|
@ -105,9 +111,12 @@ function love.load()
|
|||
sheets.food2 = newAnimation(sprites['food/2'], sprites['food/2']:getWidth()/10, sprites['food/2']:getHeight())
|
||||
sheets.food3 = newAnimation(sprites['food/3'], sprites['food/3']:getWidth()/10, sprites['food/3']:getHeight())
|
||||
|
||||
sheets.buttonopen = newAnimation(sprites['footer/button_open'], sprites['footer/button_open']:getWidth()/3, sprites['footer/button_open']:getHeight())
|
||||
sheets.buttonopen = newAnimation(sprites['header/button_open'], sprites['header/button_open']:getWidth()/3, sprites['header/button_open']:getHeight())
|
||||
|
||||
for i = 1, 3 do
|
||||
sheets.money1 = newAnimation(sprites['money/coin1'], sprites['money/coin1']:getWidth()/10, sprites['money/coin1']:getHeight())
|
||||
sheets.money2 = newAnimation(sprites['money/coin2'], sprites['money/coin2']:getWidth()/10, sprites['money/coin2']:getHeight())
|
||||
|
||||
for i = 1, 2 do
|
||||
table.insert(feesh, constr.fish(math.random(), math.random()))
|
||||
end
|
||||
|
||||
|
@ -125,7 +134,7 @@ function love.update(dt)
|
|||
|
||||
bench.startBenchmark('update')
|
||||
bench.startBenchmark('update_buttons')
|
||||
for _,btn in ipairs(footerbuttons) do
|
||||
for _,btn in ipairs(headerbuttons) do
|
||||
btn.openanim = btn.openanim + dt * 6
|
||||
end
|
||||
bench.stopBenchmark('update_buttons')
|
||||
|
@ -146,6 +155,27 @@ function love.update(dt)
|
|||
end
|
||||
bench.stopBenchmark('update_food')
|
||||
|
||||
bench.startBenchmark('update_money')
|
||||
for i,f in ipairs(money) do
|
||||
if not f.collected then
|
||||
f.y = f.y + dt * f.speed
|
||||
f.y = clamp(f.y, 0, 0.9)
|
||||
end
|
||||
f.time = f.time + dt
|
||||
|
||||
if f.y == 0.9 and not f.collected then
|
||||
f.deathtimer = f.deathtimer + dt
|
||||
end
|
||||
if f.collected then
|
||||
f.collecttimer = f.collecttimer + dt
|
||||
end
|
||||
|
||||
if f.deathtimer > 1 or f.collecttimer > 1 then
|
||||
table.remove(money, i)
|
||||
end
|
||||
end
|
||||
bench.stopBenchmark('update_money')
|
||||
|
||||
bench.startBenchmark('update_fish')
|
||||
for fi, n in ipairs(feesh) do
|
||||
bench.startBenchmark('update_fish_eases')
|
||||
|
@ -175,6 +205,7 @@ function love.update(dt)
|
|||
|
||||
local angle = math.random(-FISH_ANGLE, FISH_ANGLE)
|
||||
local str = math.random(70, 200)/200/4
|
||||
angle = mix(angle, math.deg(math.atan2((0.5 + math.sin(love.timer.getTime()/10 + fi) * 0.2) - n.y, 0)), 0.1) -- slightly head towards the middle, to prevent getting stuck at the bottom or top
|
||||
|
||||
if n.eattimer <= 0 and not n.dead then -- needs to follow something
|
||||
local mx, my
|
||||
|
@ -219,7 +250,7 @@ function love.update(dt)
|
|||
e.x = 1 - math.abs(e.x%2-1)
|
||||
e.y = 1 - math.abs(e.y%2-1)
|
||||
|
||||
local fheight = (FOOTER_HEIGHT * love.graphics.getWidth()/640)/love.graphics.getHeight()
|
||||
local fheight = (HEADER_HEIGHT * love.graphics.getWidth()/640)/love.graphics.getHeight()
|
||||
if e.y < fheight then
|
||||
e.y = e.y + (fheight - e.y) * 2
|
||||
end
|
||||
|
@ -241,6 +272,17 @@ function love.update(dt)
|
|||
|
||||
n.lifetime = n.lifetime + dt
|
||||
n.eattimer = n.eattimer - dt
|
||||
n.moneytimer = n.moneytimer - dt
|
||||
|
||||
if n.moneytimer < 0 and not n.dead then
|
||||
n.moneytimer = n.moneytimer + math.random() * 5 + 5
|
||||
|
||||
if n.size > 0 then
|
||||
local type = 2
|
||||
if n.size == 1 then type = 1 end
|
||||
table.insert(money, constr.money(n.render.x, n.render.y, type))
|
||||
end
|
||||
end
|
||||
|
||||
local sumx = 0
|
||||
local sumy = 0
|
||||
|
@ -276,10 +318,24 @@ function love.update(dt)
|
|||
if n.lifetime > FISH_AGE_MEDIUM and n.size == 0 then
|
||||
n.size = 1
|
||||
playSound('grow')
|
||||
|
||||
if not headerbuttons[1].open and not headerbuttons[1].closed then
|
||||
headerbuttons[1].open = true
|
||||
headerbuttons[1].openanim = 0
|
||||
end
|
||||
end
|
||||
if n.lifetime > FISH_AGE_BIG and n.size == 1 then
|
||||
n.size = 2
|
||||
playSound('grow')
|
||||
|
||||
if not headerbuttons[2].open and not headerbuttons[1].closed then
|
||||
headerbuttons[2].open = true
|
||||
headerbuttons[2].openanim = 0
|
||||
end
|
||||
if not headerbuttons[3].open and not headerbuttons[1].closed then
|
||||
headerbuttons[3].open = true
|
||||
headerbuttons[3].openanim = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -370,13 +426,13 @@ function love.draw()
|
|||
love.graphics.setColor(1, 1, 1)
|
||||
|
||||
local sw, sh = love.graphics.getDimensions()
|
||||
local footerheight = FOOTER_HEIGHT * sw/640
|
||||
local yscale = (sh-footerheight)/sh
|
||||
local headerheight = HEADER_HEIGHT * sw/640
|
||||
local yscale = (sh-headerheight)/sh
|
||||
|
||||
local sample = fishsprite('medium', false, 'swim')
|
||||
local spritescale = (math.min(sw, sh)/FISH_SIZE) / math.min(sample.width, sample.height)
|
||||
|
||||
stretchto(sprites['bg/1'], 0, footerheight - FOOTER_HEIGHT, 0, sw, sh - (footerheight - FOOTER_HEIGHT))
|
||||
stretchto(sprites['bg/1'], 0, headerheight - HEADER_HEIGHT, 0, sw, sh - (headerheight - HEADER_HEIGHT))
|
||||
|
||||
-- waves
|
||||
bench.startBenchmark('render_wave')
|
||||
|
@ -396,11 +452,24 @@ function love.draw()
|
|||
if i == wavecount then
|
||||
sizex = -1
|
||||
end
|
||||
love.graphics.draw(sheet.spriteSheet, sheet.quads[math.max(frame, 1)], x + (sprites['wave/wavecenter']:getWidth() * wavescale)/2, footerheight + 20, 0, wavescale * sizex, wavescale, sprites['wave/wavecenter']:getWidth()/2)
|
||||
love.graphics.draw(sheet.spriteSheet, sheet.quads[math.max(frame, 1)], x + (sprites['wave/wavecenter']:getWidth() * wavescale)/2, headerheight + 20, 0, wavescale * sizex, wavescale, sprites['wave/wavecenter']:getWidth()/2)
|
||||
end
|
||||
love.graphics.setBlendMode('alpha')
|
||||
bench.stopBenchmark('render_wave')
|
||||
|
||||
bench.startBenchmark('render_food')
|
||||
for _,f in ipairs(food) do
|
||||
local sheet = sheets['food' .. (f.type)]
|
||||
local x = f.x * sw
|
||||
local y = f.y * sh
|
||||
local frame = math.floor((f.time%1) * #sheet.quads) + 1
|
||||
|
||||
love.graphics.setColor(1, 1, 1, 1 - f.deathtimer)
|
||||
|
||||
love.graphics.draw(sheet.spriteSheet, sheet.quads[math.max(math.min(frame, #sheet.quads), 1)], x, y, 0, spritescale, spritescale, sheet.width/2, sheet.height/2)
|
||||
end
|
||||
bench.stopBenchmark('render_food')
|
||||
|
||||
-- shadow
|
||||
bench.startBenchmark('render_shadow')
|
||||
for i, n in ipairs(feesh) do
|
||||
|
@ -534,24 +603,11 @@ function love.draw()
|
|||
end
|
||||
end
|
||||
bench.stopBenchmark('render_fish')
|
||||
|
||||
bench.startBenchmark('render_food')
|
||||
for _,f in ipairs(food) do
|
||||
local sheet = sheets['food' .. (f.type)]
|
||||
local x = f.x * sw
|
||||
local y = f.y * sh
|
||||
local frame = math.floor((f.time%1) * #sheet.quads) + 1
|
||||
|
||||
love.graphics.setColor(1, 1, 1, 1 - f.deathtimer)
|
||||
|
||||
love.graphics.draw(sheet.spriteSheet, sheet.quads[math.max(math.min(frame, #sheet.quads), 1)], x, y, 0, spritescale, spritescale, sheet.width/2, sheet.height/2)
|
||||
end
|
||||
bench.stopBenchmark('render_food')
|
||||
bench.stopBenchmark('render_tank')
|
||||
|
||||
bench.startBenchmark('render_footer')
|
||||
local base = sprites['footer/base']
|
||||
local size = footerheight / FOOTER_HEIGHT
|
||||
bench.startBenchmark('render_header')
|
||||
local base = sprites['header/base']
|
||||
local size = headerheight / HEADER_HEIGHT
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.draw(base, 0, 0, 0, size, size)
|
||||
|
||||
|
@ -559,17 +615,17 @@ function love.draw()
|
|||
local x = 19
|
||||
local y = 3
|
||||
for b = 1, 7 do
|
||||
local hovered = mouseOverBox(x * size, y * size, sprites['footer/buttonbg']:getWidth() * size, sprites['footer/buttonbg']:getHeight() * size)
|
||||
local btn = footerbuttons[b]
|
||||
local hovered = mouseOverBox(x * size, y * size, sprites['header/buttonbg']:getWidth() * size, sprites['header/buttonbg']:getHeight() * size)
|
||||
local btn = headerbuttons[b]
|
||||
|
||||
if (btn and not btn.open) or not btn then
|
||||
-- draw nothing
|
||||
elseif hovered and love.mouse.isDown(1) then
|
||||
love.graphics.draw(sprites['footer/buttonbg_down'], x * size, y * size, 0, size, size)
|
||||
love.graphics.draw(sprites['header/buttonbg_down'], x * size, y * size, 0, size, size)
|
||||
elseif hovered then
|
||||
love.graphics.draw(sprites['footer/buttonbg_hover'], x * size, y * size, 0, size, size)
|
||||
love.graphics.draw(sprites['header/buttonbg_hover'], x * size, y * size, 0, size, size)
|
||||
else
|
||||
love.graphics.draw(sprites['footer/buttonbg'], x * size, y * size, 0, size, size)
|
||||
love.graphics.draw(sprites['header/buttonbg'], x * size, y * size, 0, size, size)
|
||||
end
|
||||
|
||||
if btn then
|
||||
|
@ -578,41 +634,41 @@ function love.draw()
|
|||
if btn.sprite == 'guppy' then
|
||||
local sheet = fishsprite('medium', false, 'swim')
|
||||
local frame = math.floor((love.timer.getTime() * 2) % 1 * #sheet.quads) + 1
|
||||
local scale = (sprites['footer/buttonbg']:getWidth() / sheet.width) * 0.9
|
||||
local offset = (sprites['footer/buttonbg']:getWidth() * size) / 2
|
||||
local scale = (sprites['header/buttonbg']:getWidth() / sheet.width) * 0.9
|
||||
local offset = (sprites['header/buttonbg']:getWidth() * size) / 2
|
||||
love.graphics.draw(sheet.spriteSheet, sheet.quads[frame], x * size + offset, y * size + offset*0.75, 0, size * scale, size * scale, sheet.width/2, sheet.width/2)
|
||||
elseif btn.sprite == 'food' then
|
||||
local sheets = {sheets.food2, sheets.food3}
|
||||
local sheet = sheets[btn.tier]
|
||||
|
||||
local scale = (sprites['footer/buttonbg']:getWidth() / sheet.width) * 0.65
|
||||
local offset = (sprites['footer/buttonbg']:getWidth() * size) / 2
|
||||
local scale = (sprites['header/buttonbg']:getWidth() / sheet.width) * 0.65
|
||||
local offset = (sprites['header/buttonbg']:getWidth() * size) / 2
|
||||
love.graphics.draw(sheet.spriteSheet, sheet.quads[1], x * size + offset, y * size + offset*0.75, 0, size * scale, size * scale, sheet.width/2, sheet.width/2)
|
||||
elseif btn.sprite == 'foodcount' then
|
||||
love.graphics.setFont(fonts.continuum)
|
||||
local offset = (sprites['footer/buttonbg']:getWidth() * size) / 2
|
||||
local offset = (sprites['header/buttonbg']:getWidth() * size) / 2
|
||||
|
||||
local bordersize = 1
|
||||
for _,p in ipairs({{0, 1}, {1, 0}, {1, 1}, {-1, 0}, {0, -1}, {-1, -1}, {1, -1}, {-1, 1}}) do
|
||||
love.graphics.setColor(0, 0, 0, 0.5)
|
||||
love.graphics.printf(btn.tier + 1, round(x * size) + p[1] * bordersize, round(y * size + offset*0.75 - fonts.continuum:getHeight()/2) + p[2] * bordersize, round(sprites['footer/buttonbg']:getWidth() * size), 'center')
|
||||
love.graphics.printf(btn.tier + 1, round(x * size) + p[1] * bordersize, round(y * size + offset*0.75 - fonts.continuum:getHeight()/2) + p[2] * bordersize, round(sprites['header/buttonbg']:getWidth() * size), 'center')
|
||||
end
|
||||
|
||||
love.graphics.setColor(0, 1, 0)
|
||||
love.graphics.printf(btn.tier + 1, round(x * size), round(y * size + offset*0.75 - fonts.continuum:getHeight()/2), round(sprites['footer/buttonbg']:getWidth() * size), 'center')
|
||||
love.graphics.printf(btn.tier + 1, round(x * size), round(y * size + offset*0.75 - fonts.continuum:getHeight()/2), round(sprites['header/buttonbg']:getWidth() * size), 'center')
|
||||
end
|
||||
|
||||
-- price
|
||||
love.graphics.setFont(fonts.pix)
|
||||
local font = love.graphics.getFont()
|
||||
love.graphics.setColor(0, 1, 0)
|
||||
love.graphics.printf('$' .. btn.cost, round(x * size), round(y * size + 51 * size - font:getHeight()/2), round(sprites['footer/buttonbg']:getWidth() * size), 'center')
|
||||
love.graphics.printf('$' .. btn.cost, round(x * size), round(y * size + 51 * size - font:getHeight()/2), round(sprites['header/buttonbg']:getWidth() * size), 'center')
|
||||
love.graphics.setColor(1, 1, 1)
|
||||
love.graphics.setFont(fonts.default)
|
||||
|
||||
-- reflection
|
||||
love.graphics.setBlendMode('add')
|
||||
love.graphics.draw(sprites['footer/reflection'], x * size, y * size, 0, size, size)
|
||||
love.graphics.draw(sprites['header/reflection'], x * size, y * size, 0, size, size)
|
||||
love.graphics.setBlendMode('alpha')
|
||||
end
|
||||
|
||||
|
@ -631,7 +687,27 @@ function love.draw()
|
|||
if b >= 3 then incr = 73 end
|
||||
x = x + incr
|
||||
end
|
||||
bench.stopBenchmark('render_footer')
|
||||
|
||||
-- money count
|
||||
love.graphics.setFont(fonts.continuum)
|
||||
love.graphics.setColor(179/255, 254/255, 89/255)
|
||||
local leftpad = 100
|
||||
love.graphics.printf(balance, round(sw * 0.965 - leftpad), round(HEADER_HEIGHT - 25), leftpad, 'right')
|
||||
love.graphics.setFont(fonts.default)
|
||||
|
||||
bench.stopBenchmark('render_header')
|
||||
|
||||
bench.startBenchmark('render_money')
|
||||
for _,f in ipairs(money) do
|
||||
local sheet = sheets['money' .. (f.type)]
|
||||
local x = mix(f.x * sw, sw / 9 * 8, ease.outCubic(f.collecttimer))
|
||||
local y = mix(f.y * sh, HEADER_HEIGHT - 20, ease.outCubic(f.collecttimer))
|
||||
local frame = math.floor((f.time%1) * #sheet.quads) + 1
|
||||
|
||||
love.graphics.setColor(1, 1, 1, 1 - f.deathtimer)
|
||||
love.graphics.draw(sheet.spriteSheet, sheet.quads[math.max(math.min(frame, #sheet.quads), 1)], x, y, 0, spritescale, spritescale, sheet.width/2, sheet.height/2)
|
||||
end
|
||||
bench.stopBenchmark('render_money')
|
||||
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.print('FPS: ' .. 1 / love.timer.getDelta(), 0, sh - 16)
|
||||
|
@ -641,23 +717,49 @@ function love.draw()
|
|||
end
|
||||
|
||||
function love.mousepressed(x, y, b)
|
||||
if b == 1 and y > FOOTER_HEIGHT and #food < foodcount then
|
||||
table.insert(food, constr.food(x/love.graphics.getWidth(), y/love.graphics.getHeight(), foodtier))
|
||||
playSound('dropfood')
|
||||
if b == 1 then
|
||||
for _,m in ipairs(money) do
|
||||
local dist = math.abs(x/love.graphics.getWidth() - m.x) + math.abs(y/love.graphics.getHeight() - m.y)
|
||||
if dist < 0.1 and not m.collected then
|
||||
m.collected = true
|
||||
m.deathtimer = 0
|
||||
playSound('collect', 1, 1 + math.random() * 0.2 - 0.1)
|
||||
|
||||
if m.type == 1 then balance = balance + 15 end
|
||||
if m.type == 2 then balance = balance + 35 end
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local footerheight = FOOTER_HEIGHT * love.graphics.getWidth()/640
|
||||
local size = footerheight / FOOTER_HEIGHT
|
||||
if b == 1 and y > HEADER_HEIGHT and #food < foodcount then
|
||||
if balance >= 5 then
|
||||
table.insert(food, constr.food(x/love.graphics.getWidth(), y/love.graphics.getHeight(), foodtier))
|
||||
playSound('dropfood')
|
||||
balance = balance - 5
|
||||
else
|
||||
playSound('buzzer')
|
||||
end
|
||||
end
|
||||
|
||||
local headerheight = HEADER_HEIGHT * love.graphics.getWidth()/640
|
||||
local size = headerheight / HEADER_HEIGHT
|
||||
|
||||
if b == 1 then
|
||||
local x = 19
|
||||
for i = 1, 7 do
|
||||
local hovered = mouseOverBox(x * size, 3 * size, sprites['footer/buttonbg']:getWidth() * size, sprites['footer/buttonbg']:getHeight() * size)
|
||||
local hovered = mouseOverBox(x * size, 3 * size, sprites['header/buttonbg']:getWidth() * size, sprites['header/buttonbg']:getHeight() * size)
|
||||
|
||||
if hovered then
|
||||
if footerbuttons[i] and footerbuttons[i].open then
|
||||
footerbuttons[i].func(footerbuttons[i])
|
||||
playSound('buttonclick')
|
||||
if headerbuttons[i] and headerbuttons[i].open then
|
||||
if balance >= headerbuttons[i].cost then
|
||||
headerbuttons[i].func(headerbuttons[i])
|
||||
playSound('buttonclick')
|
||||
balance = balance - headerbuttons[i].cost
|
||||
else
|
||||
playSound('buzzer')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|