From e1e07aa3572521ae7463cbdca548dd351e84df74 Mon Sep 17 00:00:00 2001 From: itzmarkoni Date: Tue, 5 May 2026 19:46:57 -0400 Subject: [PATCH] updated --- programs/plinko.lua | 17 +++++++++++++---- programs/roulette.lua | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/programs/plinko.lua b/programs/plinko.lua index bbe11e6..0246e1c 100644 --- a/programs/plinko.lua +++ b/programs/plinko.lua @@ -298,7 +298,9 @@ local function physicsLoop() local MAX_TIME = 14.0 -- Per-peg cooldown to prevent vibrating stuck against one peg. - local pegCooldown = {} + -- Also used to track glow: peg stays lit while cooldown > 0. + local pegCooldown = {} -- index -> time remaining + local pegLit = {} -- index -> true while glowing -- Pre-build bucket divider X positions (walls between buckets). -- Each divider is a thin vertical wall from bucketTop downward. @@ -326,10 +328,16 @@ local function physicsLoop() vx = vx * s; vy = vy * s end - -- Tick peg cooldowns + -- Tick peg cooldowns; restore normal colour when glow expires for k, v in pairs(pegCooldown) do pegCooldown[k] = v - DT - if pegCooldown[k] <= 0 then pegCooldown[k] = nil end + if pegCooldown[k] <= 0 then + pegCooldown[k] = nil + if pegLit[k] then + drawPeg(pegs[k], COL_PEG) + pegLit[k] = nil + end + end end -- ── Peg collisions (only while above bucket zone) ─────────── @@ -363,7 +371,8 @@ local function physicsLoop() vy = vy - newVn * ny end - pegCooldown[i] = 0.08 + pegCooldown[i] = 0.18 -- glow duration (s) + pegLit[i] = true drawPeg(p, COL_PEG_HIT) end end diff --git a/programs/roulette.lua b/programs/roulette.lua index 8d08230..fc6a1ed 100644 --- a/programs/roulette.lua +++ b/programs/roulette.lua @@ -66,17 +66,21 @@ local COL_BALL = 0xF0F0F0 local COL_BALL_SHD = 0x444444 -- Ball physics -local BALL_RADIUS = 8 -- px -local BALL_SPEED_MIN = 420 -- px/s initial tangential speed -local BALL_SPEED_MAX = 620 -local TRACK_RESTITUTION = 0.72 -- speed fraction kept on track-wall bounce -local POCKET_RESTITUTION = 0.45 -- speed fraction kept bouncing inside pocket ring -local FRICTION_TRACK = 0.992 -- multiplier per frame while in track (energy loss) -local FRICTION_POCKET = 0.970 -- higher damping once in pocket ring --- Ball enters pocket ring when its speed drops below this -local DROP_SPEED = 90 -- px/s +local BALL_RADIUS = 8 -- px +local BALL_SPEED_MIN = 900 -- px/s initial tangential speed +local BALL_SPEED_MAX = 1300 +local TRACK_RESTITUTION = 0.82 -- speed fraction kept on track-wall bounce +local POCKET_RESTITUTION = 0.52 -- speed fraction kept bouncing inside pocket ring +local FRICTION_TRACK = 0.9985 -- multiplier per frame while in track +local FRICTION_POCKET = 0.972 -- higher damping once in pocket ring +-- Centripetal slide: inward acceleration applied as ball slows, simulating +-- the ball losing grip and sliding down the slope toward the centre. +local SLIDE_ACCEL = 380 -- px/s² inward pull (scales with 1/speed) +local SLIDE_THRESHOLD = 500 -- px/s below this speed the slide kicks in +-- Ball enters pocket ring when speed drops below this +local DROP_SPEED = 80 -- px/s -- Small random kick angle on each wall bounce -local BOUNCE_KICK_MAX = 0.12 -- rad +local BOUNCE_KICK_MAX = 0.10 -- rad ---------------------------------------------------------------------- -- GPU / pixel primitives @@ -315,6 +319,23 @@ local function spin() vx = vx * fric vy = vy * fric + -- Centripetal slide: as the ball slows it loses centripetal support + -- and slides inward, like a real ball on a tilted cone/bowl. + if not inPocket and speed < SLIDE_THRESHOLD and speed > DROP_SPEED then + local dx0 = bx - CX + local dy0 = by - CY + local d0 = math.sqrt(dx0*dx0 + dy0*dy0) + if d0 > 0 then + -- Inward unit vector + local inx = -dx0 / d0 + local iny = -dy0 / d0 + -- Acceleration scales up as speed decreases + local accel = SLIDE_ACCEL * (1 - speed / SLIDE_THRESHOLD) + vx = vx + inx * accel * dt + vy = vy + iny * accel * dt + end + end + -- Integrate bx = bx + vx * dt by = by + vy * dt