2021-01-24 17:46:52 +00:00
return function ( feesh , dt , food , headerbuttons , money )
2021-01-23 23:30:01 +00:00
for fi , n in ipairs ( feesh ) do
bench.startBenchmark ( ' update_fish_eases ' )
for _ , e in ipairs ( n.eases ) do
e.a = e.a + dt * e.speed
end
for i , e in ipairs ( n.eases ) do
if e.a > 1 then
local sumx = 0
local sumy = 0
for i2 , e2 in ipairs ( n.eases ) do
if i ~= i2 then
sumx = sumx + mix ( e2.fromx , e2.x , FISH_EASE ( math.min ( e2.a , 1 ) ) )
sumy = sumy + mix ( e2.fromy , e2.y , FISH_EASE ( math.min ( e2.a , 1 ) ) )
end
end
sumx = sumx + e.x
sumy = sumy + e.y
n.x = sumx / # n.eases
n.y = sumy / # n.eases
e.fromx = e.x
e.fromy = e.y
e.a = e.a - 1
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
if n.eattimer <= 0 then
if n.shortestfood and food [ n.shortestfood ] then
local f = food [ n.shortestfood ]
mx , my = f.x , f.y
elseif frame % FISH_FOOD_CHECK_FREQ == 0 then
local minfood = 0
local mindist = 9e9
for i , f in ipairs ( food ) do
local dist = math.sqrt ( math.pow ( math.abs ( f.x - n.render . x ) , 2 ) + math.pow ( math.abs ( f.y - n.render . y ) , 2 ) )
if dist < mindist then
mindist = dist
minfood = i
end
end
if minfood ~= 0 then
n.shortestfood = minfood
end
end
end
if mx and my then
angle = math.deg ( math.atan2 ( my - n.y , mx - n.x ) ) + math.random ( - FISH_FOLLOW_RANDOM , FISH_FOLLOW_RANDOM )
str = math.random ( 70 , 200 ) / 200 / 8
end
end
local x = math.cos ( math.rad ( angle ) ) * str
local y = math.sin ( math.rad ( angle ) ) * str
if not ( ( n.shortestfood and food [ n.shortestfood ] ) or n.dead ) then
x = x * math.sign ( n.render . x - n.render . prevx )
end
e.x = n.x + x
e.y = n.y + y
e.x = 1 - math.abs ( e.x % 2 - 1 )
e.y = 1 - math.abs ( e.y % 2 - 1 )
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
e.speed = 1 / ( math.sqrt ( math.pow ( math.abs ( e.x - e.fromx ) , 2 ) + math.pow ( math.abs ( e.y - e.fromy ) , 2 ) ) / 2 ) / 15
if n.eattimer < FISH_FOOD_HUNGRY or ( n.shortestfood and food [ n.shortestfood ] ) then
e.speed = e.speed * 1.3
end
if n.dead then
e.speed = e.speed * 0.2
end
end
end
bench.stopBenchmark ( ' update_fish_eases ' )
bench.startBenchmark ( ' update_fish_position ' )
n.x = clamp ( n.x , 0 , 1 )
n.y = clamp ( n.y , 0 , 0.5 )
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
for _ , e2 in ipairs ( n.eases ) do
sumx = sumx + mix ( e2.fromx , e2.x , FISH_EASE ( e2.a ) )
sumy = sumy + mix ( e2.fromy , e2.y , FISH_EASE ( e2.a ) )
end
n.render . prevx = n.render . x
n.render . prevy = n.render . y
n.render . x = sumx / # n.eases
n.render . y = sumy / # n.eases
n.render . x = clamp ( n.render . x , 0.05 , 0.95 )
n.render . y = clamp ( n.render . y , 0.1 , 0.85 )
bench.stopBenchmark ( ' update_fish_position ' )
bench.startBenchmark ( ' update_fish_colission ' )
if n.shortestfood and food [ n.shortestfood ] and frame % FISH_COLISSION_CHECK_FREQ == 0 then
local f = food [ n.shortestfood ]
if f then
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.render . eattimer = 0
n.shortestfood = - 1
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 ' )
2021-01-25 06:20:23 +00:00
if not headerbuttons [ 2 ] . open and not headerbuttons [ 2 ] . closed then
2021-01-23 23:30:01 +00:00
headerbuttons [ 2 ] . open = true
headerbuttons [ 2 ] . openanim = 0
end
2021-01-25 06:20:23 +00:00
if not headerbuttons [ 3 ] . open and not headerbuttons [ 3 ] . closed then
2021-01-23 23:30:01 +00:00
headerbuttons [ 3 ] . open = true
headerbuttons [ 3 ] . openanim = 0
end
end
end
end
end
bench.stopBenchmark ( ' update_fish_colission ' )
bench.startBenchmark ( ' update_fish_render ' )
if frame % FISH_RENDER_FREQ == 0 then
local dt = dt * FISH_RENDER_FREQ
local iter = FISH_RENDER_ITERS
local iteroff = FISH_RENDER_ITEROFF
local xspeed = { }
local yspeed = { }
local angle = { }
local sumxiter = { }
local sumyiter = { }
for i = 1 , iter do
local off = i * iteroff
local sumx2 = 0
local sumy2 = 0
for _ , e2 in ipairs ( n.eases ) do
sumx2 = sumx2 + mix ( e2.fromx , e2.x , FISH_EASE ( e2.a + off ) )
sumy2 = sumy2 + mix ( e2.fromy , e2.y , FISH_EASE ( e2.a + off ) )
end
table.insert ( xspeed , ( sumx2 - ( sumxiter [ i - 1 ] or sumx ) ) / # n.eases )
table.insert ( yspeed , ( sumy2 - ( sumyiter [ i - 1 ] or sumy ) ) / # n.eases )
table.insert ( angle , math.atan2 ( sumy2 - ( sumyiter [ i - 1 ] or sumy ) , sumx2 - ( sumxiter [ i - 1 ] or sumx ) ) )
table.insert ( sumxiter , sumx2 )
table.insert ( sumyiter , sumy2 )
end
n.render . xspeed = sum ( xspeed )
n.render . yspeed = sum ( yspeed )
n.render . angle = sum ( angle )
end
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
else
n.render . swim = 0
end
n.render . eattimer = n.render . eattimer + dt * 3
if n.render . eattimer < 1 then
n.render . swim = 0
end
if not n.dead then
n.render . turndir = math.sign ( n.render . x - n.render . prevx )
end
local m = n.eattimer < FISH_FOOD_HUNGRY and 1 or - 1
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
local timeSinceDead = math.abs ( n.eattimer - FISH_FOOD_DEAD )
n.render . y = n.render . y + timeSinceDead / 5 * math.min ( timeSinceDead , 1 )
n.render . y = clamp ( n.render . y , 0 , 0.85 )
if n.render . y == 0.85 then
n.render . deathanim = n.render . deathanim + dt
if n.render . deathanim > 1 then
table.remove ( feesh , fi )
end
end
end
end
end