From 64ffc312292e7230f1fa9a83c06fa7502ec73af4 Mon Sep 17 00:00:00 2001 From: yaw-man Date: Sat, 14 Jan 2023 08:43:54 -0400 Subject: [PATCH] Fixed second derivative bug! Looks good now; breaking up Update function for better encapsulation during collision detection. --- collision.lua | 9 +++----- main.lua | 22 ++++++++++++-------- marble.lua | 11 +++++++++- wave.lua | 57 +++++++++++++++++++++++++++++---------------------- 4 files changed, 59 insertions(+), 40 deletions(-) diff --git a/collision.lua b/collision.lua index 5fdcbab..5e0511d 100644 --- a/collision.lua +++ b/collision.lua @@ -1,9 +1,6 @@ -local function DetectCollision( - xi, yi, vx, vy, xf, yf, - GetRadius, - GetRadialDerivative) - - +local function DetectCollision( curMarble, newMarble, curWave, newWave ) + local t, r, th, normal + if t then return { t = t, r = r, th = th, normal = normal } end end return DetectCollision \ No newline at end of file diff --git a/main.lua b/main.lua index b201eed..63cdc9e 100644 --- a/main.lua +++ b/main.lua @@ -1,10 +1,10 @@ local love = love -step = 1.0 / 120.0 -local step = step +local step = 1.0 / 120.0 local sitelenpona local text local marble local wave +local DetectCollision local sounds = { @@ -76,6 +76,7 @@ function love.load() text = assert( require "text" ) marble = assert( require "marble" ) wave = assert( require "wave" ) + DetectCollision = assert ( require "collision" ) return state.Reset() end @@ -129,22 +130,26 @@ local function OnImpact( impact ) local score = BeatScore( impact.t ) --DEBUG state.lastBeatScore = score + + local sound if score > state.beatScoreThreshold then + sound = sounds.goodPing state.beatScoreThreshold = 1.0 state.currentBeat = state.currentBeat + 1 if state.currentBeat >= 120 then return OnVictory() end - love.audio.play(sounds.goodPing) + else + sound = sounds.badPing state.beatScoreThreshold = state.beatScoreThreshold - 0.05 - love.audio.play(sounds.badPing) + end - + love.audio.play( sound ) end @@ -165,7 +170,7 @@ function love.draw() wave.Draw() love.graphics.pop() - sitelenpona.Draw( text.tok[state.currentBeat] ) + sitelenpona.Draw( text.tok[state.currentBeat] ) marble.Draw() @@ -177,8 +182,9 @@ end function love.update( dt ) dt = dt + state.timeToSimulate while dt > step do - marble.Update() - wave.Update() + marble.Integrate( step ) + wave.Integrate( step ) + dt = dt - step end state.timeToSimulate = dt diff --git a/marble.lua b/marble.lua index 36ceb72..4ed3571 100644 --- a/marble.lua +++ b/marble.lua @@ -3,14 +3,21 @@ local love = love --local wave = assert( require "wave" ) local oldBuffer = love.graphics.newCanvas() local newBuffer = love.graphics.newCanvas() -local step = assert( step ) local state local FRICTION = 0.01 local MAXSPEED = 5.0 local t, x, y, dx, dy, ddx, ddy +local function OnImpact( impact ) + +end + local function Update() + +end + +local function Integrate( step ) t = love.timer.getTime() dx = (1.0 - FRICTION) * dx + FRICTION * ddx @@ -95,6 +102,8 @@ end Reset() return { + Integrate = Integrate, + OnImpact = OnImpact, Update = Update, OnKey = OnKey, Draw = Draw, diff --git a/wave.lua b/wave.lua index bd97a5d..4add5b0 100644 --- a/wave.lua +++ b/wave.lua @@ -1,8 +1,7 @@ --Render and simulate 1D wave equation. local love = love -local step = assert( step ) -local N = 25 +local N = 11 --Calculate discrete fourier transform of radius function. local DFT @@ -80,11 +79,11 @@ local SecondDerivative = function( wave, x ) local y = 0 for k = 1, N / 2 do - local c, s = k * k * math.cos( x * k ), k * k * math.sin( x * k ) + local c, s = -k * k * math.cos( x * k ), -k * k * math.sin( x * k ) y = y - - c * re[k + 1] + + c * re[k + 1] - s * im[k + 1] - - c * re[N - k + 1] + + c * re[N - k + 1] + s * im[N - k + 1] end @@ -119,7 +118,7 @@ local mt = { __index = { local function Wave( ) local t = { - --radii[k] = radius of point on curve at angle (k - 1) / 13 + --radii[k] = radius of point on curve at angle (k - 1) / N radii = {}, --TIME derivative of radius vrad = {}, @@ -130,7 +129,7 @@ local function Wave( ) } for i = 1, N do - t.radii[i] = 1.0 + t.radii[i] = 0.3 * math.sin( i * 2.0 * math.pi / N ) t.vrad[i] = 0.0 end DFT( t ) @@ -162,23 +161,27 @@ local function Draw() for k = 0.1, 1.0, 0.1 do --Interpolant. - love.graphics.setColor( 1.0, 0, 0, 0.5 ) + love.graphics.setColor( 1.0, 0, 0, 0.7 ) th = ( i - 1 + k ) * 2.0 * math.pi / N - r = cur:Interpolate( th ) - x, y = r * math.cos( th ), r * math.sin( th ) - love.graphics.circle( "fill", x, y, 0.01 ) + local r = cur:Interpolate( th ) + local x, y = r * math.cos( th ), r * math.sin( th ) + --love.graphics.circle( "fill", x, y, 0.01 ) + love.graphics.circle( "fill", th / math.pi - 1.0 , r, 0.01) --First derivative. - love.graphics.setColor( 0, 1.0, 0, 0.5 ) - r = 1.0 + cur:Derivative( th ) + love.graphics.setColor( 0, 1.0, 0, 0.7 ) + r = cur:Derivative( th ) x, y = r * math.cos( th ), r * math.sin( th ) - love.graphics.circle( "fill", x, y, 0.01 ) + --love.graphics.circle( "fill", x, y, 0.01 ) + love.graphics.circle( "fill", th / math.pi - 1.0, r, 0.01) --Second derivative. - love.graphics.setColor( 0, 0, 1.0, 0.5 ) - r = 1.0 + cur:SecondDerivative( th ) + love.graphics.setColor( 0, 0, 1.0, 0.7 ) + r = cur:SecondDerivative( th ) x, y = r * math.cos( th ), r * math.sin( th ) - love.graphics.circle( "fill", x, y, 0.01 ) + --love.graphics.circle( "fill", x, y, 0.01 ) + love.graphics.circle( "fill", th / math.pi - 1.0, r, 0.01) + end end @@ -188,23 +191,25 @@ local function Draw() love.graphics.circle( "fill", x, y, 0.02 ) end +local function OnImpact( impact ) + +end + local function Update() + +end + +local function Integrate( step ) local t = love.timer.getTime() for i = 1, N do - local rxx = old:SecondDerivative( 2.0 * math.pi * (i - 1) / N ) - cur.vrad[i] = 0.7 * old.vrad[i] + 0.5 * step * rxx - cur.radii[i] = old.radii[i] + step * cur.vrad[i] + cur.radii[i] = old.radii[i] end cur:DFT( ) - if love.math.random( 120 ) < 3 then - cur:Impulse( 0, 0.2 ) - end - --Deep copy of current state to old state. for name, t in pairs( cur ) do - for i = 1, 13 do + for i = 1, N do old[name][i] = t[i] end end @@ -225,6 +230,8 @@ Reset() return { Reset = Reset, Update = Update, + Integrate = Integrate, + OnImpact = OnImpact, DetectCollision = DetectCollision, Draw = Draw, } \ No newline at end of file