Compare commits

..

No commits in common. "a22b6d1e228a8d6bfd06afd10b21bcc567b6495f" and "0f0d092339db27cd1e8dc71ed3ae254f0b1b9d67" have entirely different histories.

22 changed files with 58 additions and 309 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

View File

@ -1,6 +1,6 @@
ease = require 'lib.ease'
FISH_SPLINE_QUALITY = 6 -- bigger number = more lag, smaller number = more noise
FISH_SPLINE_QUALITY = 5 -- bigger number = more lag, smaller number = more noise
FISH_RENDER_ITERS = 4 -- a bigger number allows for more smoother flipper movement and rotation, but is significantly laggier
FISH_RENDER_ITEROFF = 0.025 -- should be 1/iters*0.1, lower numbers will make movement snappier and higher numbers will make it smoother but glitchier
@ -11,10 +11,8 @@ FISH_EASE = ease.inOutSine -- ease used for fish movement
FISH_ANGLE = 30 -- bigger angle allows for fish to swim further down/up at once
FISH_FOLLOW_RANDOM = 10
FISH_FOOD_CHECK_FREQ = 1 -- how often to check for food
FISH_FOOD_1_COOLDOWN = 10
FISH_FOOD_2_COOLDOWN = 20
FISH_FOOD_3_COOLDOWN = 25
FISH_FOOD_CHECK_FREQ = 10 -- how often to check for food
FISH_FOOD_COOLDOWN = 10
FISH_FOOD_HUNGRY = -5
FISH_FOOD_DEAD = -15

View File

@ -52,7 +52,7 @@ function self.food(x, y, type)
speed = 0.2,
time = math.random(),
deathtimer = 0,
type = type
type = 1
}
return food

View File

@ -1,5 +1,3 @@
require 'lib.audio'
local assets = {}
function assets.clear()
@ -72,8 +70,8 @@ function assets.addAudio(base, d, type)
if type == "sfx" then
sound_path[audioname] = dir .. "/" .. file
if sounds then
registerSound(audioname, (sounds[audioname] or {}).volume or 1)
if sounds and sounds[audioname] then
registerSound(audioname, sounds[audioname].volume)
end
elseif type == "bgm" then
music_path[audioname] = dir .. "/" .. file

View File

@ -1,34 +0,0 @@
local tick = require 'lib.tick'
sfx_volume = 1
sounds = {}
local current_volume = 1
local old_volume = 1
local sound_instances = {}
function registerSound(sound, volume)
sounds[sound] = {
data = love.sound.newSoundData(sound_path[sound]),
volume = volume or 1
}
end
function playSound(sound, volume, pitch)
if sounds[sound] then
if not sound_instances[sound] then
sound_instances[sound] = 0
end
local source = love.audio.newSource(sounds[sound].data, "static")
local adjusted_volume = 1/(2^sound_instances[sound])
source:setVolume((volume or 1) * adjusted_volume * sounds[sound].volume * sfx_volume)
source:setPitch(pitch or 1)
source:play()
sound_instances[sound] = sound_instances[sound] + 1
tick.delay(function() sound_instances[sound] = sound_instances[sound] - 1 end, sounds[sound].data:getDuration()/4)
end
end

View File

@ -1,166 +0,0 @@
--
-- tick
--
-- Copyright (c) 2015 rxi
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.
--
local tick = { _version = "0.1.1" }
tick.__index = tick
local iscallable = function(x)
if type(x) == "function" then return true end
local mt = getmetatable(x)
return mt and mt.__call ~= nil
end
local noop = function()
end
local event = {}
event.__index = event
function event.new(parent, fn, delay, recur, err)
err = err or 0
-- Create and return event
return setmetatable({
parent = parent,
delay = delay,
timer = delay + err,
fn = fn,
recur = recur,
}, event)
end
function event:after(fn, delay)
-- Error check
if self.recur then
error("cannot chain a recurring event")
end
-- Chain event
local oldfn = self.fn
local e = event.new(self.parent, fn, delay, false)
self.fn = function()
oldfn()
e.timer = e.timer + self.parent.err
self.parent:add(e)
end
return e
end
function event:stop()
tick.remove(self.parent, self)
end
function tick.group()
return setmetatable({ err = 0 }, tick)
end
function tick:add(e)
self[e] = true
table.insert(self, e)
return e
end
function tick:remove(e)
if type(e) == "number" then
-- Remove and return event
local idx = e
e = self[idx]
self[e] = nil
self[idx] = self[#self]
table.remove(self)
return e
end
self[e] = false
for i, v in ipairs(self) do
if v == e then
return self:remove(i)
end
end
end
function tick:update(dt)
for i = #self, 1, -1 do
local e = self[i]
e.timer = e.timer - dt
while e.timer <= 0 do
if e.recur then
e.timer = e.timer + e.delay
else
self:remove(i)
end
self.err = e.timer
e.fn()
if not e.recur then
break
end
end
end
self.err = 0
end
function tick:event(fn, delay, recur)
delay = tonumber(delay)
-- Error check
if not iscallable(fn) then
error("expected `fn` to be callable")
end
if type(delay) ~= "number" then
error("expected `delay` to be a number")
end
if delay < 0 then
error("expected `delay` of zero or greater")
end
-- If, factoring in the timing error, the event should happen *now* the
-- function is immediately called and the error is temporarily carried
-- through. This assures nested events with delays shorter than the update()
-- delta-time do not accumulate error; several nested events with very small
-- delays may end up being called on the same frame. A dummy event is created
-- and returned so :after() still functions correctly.
local d = delay + self.err
if d < 0 then
local err = self.err
self.err = d
fn()
self.err = err
return self:add(event.new(self, noop, delay, recur, self.err))
end
-- Create, add and return a normal event
return self:add(event.new(self, fn, delay, recur, self.err))
end
function tick:delay(fn, delay)
return self:event(fn, delay, false)
end
function tick:recur(fn, delay)
return self:event(fn, delay, true)
end
local group = tick.group()
local bound = {
update = function(...) return tick.update(group, ...) end,
delay = function(...) return tick.delay (group, ...) end,
recur = function(...) return tick.recur (group, ...) end,
remove = function(...) return tick.remove(group, ...) end,
}
setmetatable(bound, tick)
return bound

143
main.lua
View File

@ -3,11 +3,9 @@ require 'util'
constr = require 'constructors'
require 'lib.audio'
assets = require 'lib.assets'
ease = require 'lib.ease'
bench = require 'lib.benchmark'
tick = require 'lib.tick'
sprites = {}
sound_path = {}
@ -19,9 +17,6 @@ debug = false
food = {}
feesh = {}
foodtier = 1
foodcount = 1
footerbuttons = {
{
cost = 100,
@ -29,40 +24,27 @@ footerbuttons = {
openanim = 1,
open = true,
func = function()
playSound('splash', 0.7, 0.8)
table.insert(feesh, constr.fish(math.random(), 0.3))
end
},
{
cost = 200,
sprite = 'food',
tier = foodtier,
tier = 1,
openanim = 1,
open = true,
func = function(self)
self.openanim = 0
foodtier = foodtier + 1
if foodtier >= 3 then
self.open = false
else
self.tier = foodtier
end
func = function()
--table.insert(feesh, constr.fish(math.random(), 0.3))
end
},
{
cost = 300,
sprite = 'foodcount',
tier = foodcount,
tier = 3,
openanim = 1,
open = true,
func = function(self)
self.openanim = 0
foodcount = foodcount + 1
if foodcount >= 9 then
self.open = false
else
self.tier = foodcount
end
func = function()
--table.insert(feesh, constr.fish(math.random(), 0.3))
end
}
}
@ -121,15 +103,8 @@ local unfocusinterval = 5
function love.update(dt)
frame = frame + 1
bench.update()
tick.update(dt)
bench.startBenchmark('update')
bench.startBenchmark('update_buttons')
for _,btn in ipairs(footerbuttons) do
btn.openanim = btn.openanim + dt * 6
end
bench.stopBenchmark('update_buttons')
bench.startBenchmark('update_food')
for i,f in ipairs(food) do
f.y = f.y + dt * f.speed
@ -265,21 +240,16 @@ function love.update(dt)
local dist = math.abs(n.render.x - f.x) + math.abs(n.render.y - f.y)
if dist < FOOD_HITBOX then
playSound('slurp')
table.remove(food, n.shortestfood)
local cooldowns = {FISH_FOOD_1_COOLDOWN, FISH_FOOD_2_COOLDOWN, FISH_FOOD_3_COOLDOWN}
n.eattimer = cooldowns[f.type]
n.eattimer = FISH_FOOD_COOLDOWN
n.render.eattimer = 0
n.shortestfood = -1
if n.lifetime > FISH_AGE_MEDIUM and n.size == 0 then
if n.lifetime > FISH_AGE_MEDIUM then
n.size = 1
playSound('grow')
end
if n.lifetime > FISH_AGE_BIG and n.size == 1 then
if n.lifetime > FISH_AGE_BIG then
n.size = 2
playSound('grow')
end
end
end
@ -323,7 +293,7 @@ function love.update(dt)
n.render.turn = n.render.turn + dt * math.sign(n.render.x - n.render.prevx) * 2
n.render.turn = clamp(n.render.turn, 0, 1)
if n.render.turn == 0 or n.render.turn == 1 then
n.render.swim = (n.render.swim + dt * (math.abs(n.render.xspeed) * 250 + 0.5)) % 1
n.render.swim = (n.render.swim + dt * math.abs(n.render.xspeed) * 300) % 1
else
n.render.swim = 0
end
@ -341,9 +311,6 @@ function love.update(dt)
n.render.hungry = clamp(n.render.hungry + dt * m * 3, 0, 1)
bench.stopBenchmark('update_fish_render')
if n.eattimer <= FISH_FOOD_DEAD and not n.dead then
playSound('die')
end
if n.eattimer <= FISH_FOOD_DEAD then
n.dead = true
@ -537,7 +504,7 @@ function love.draw()
bench.startBenchmark('render_food')
for _,f in ipairs(food) do
local sheet = sheets['food' .. (f.type)]
local sheet = sheets.food1
local x = f.x * sw
local y = f.y * sh
local frame = math.floor((f.time%1) * #sheet.quads) + 1
@ -572,52 +539,50 @@ function love.draw()
love.graphics.draw(sprites['footer/buttonbg'], x * size, y * size, 0, size, size)
end
if btn then
if btn.open then
-- sprite inside
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
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]
if btn and btn.open then
-- sprite inside
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
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
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 scale = (sprites['footer/buttonbg']:getWidth() / sheet.width) * 0.65
local offset = (sprites['footer/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 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')
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')
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')
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.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.setBlendMode('alpha')
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')
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.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.setBlendMode('alpha')
-- open/close anim
if (btn and btn.openanim < 1) then
if (btn and not btn.openanim == 1) then
local sheet = sheets.buttonopen
local anim = 0
if btn then anim = btn.openanim end
@ -641,11 +606,12 @@ 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 == 2 then
table.insert(food, constr.food(x/love.graphics.getWidth(), y/love.graphics.getHeight(), 1))
end
end
function love.mousereleased(x, y, b)
local footerheight = FOOTER_HEIGHT * love.graphics.getWidth()/640
local size = footerheight / FOOTER_HEIGHT
@ -656,8 +622,7 @@ function love.mousepressed(x, y, b)
if hovered then
if footerbuttons[i] and footerbuttons[i].open then
footerbuttons[i].func(footerbuttons[i])
playSound('buttonclick')
footerbuttons[i].func()
end
end
@ -669,10 +634,6 @@ function love.mousepressed(x, y, b)
end
end
function love.mousereleased(x, y, b)
end
function love.keypressed(key)
if key == 'f3' then
debug = not debug

View File

@ -55,12 +55,4 @@ end
function math.sign(a)
if a >= 0 then return 1 else return -1 end
end
function string.starts(str, start)
return str:sub(1, #start) == start
end
function string.ends(str, ending)
return ending == "" or str:sub(-#ending) == ending
end