updated
This commit is contained in:
@@ -298,7 +298,9 @@ local function physicsLoop()
|
|||||||
local MAX_TIME = 14.0
|
local MAX_TIME = 14.0
|
||||||
|
|
||||||
-- Per-peg cooldown to prevent vibrating stuck against one peg.
|
-- 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).
|
-- Pre-build bucket divider X positions (walls between buckets).
|
||||||
-- Each divider is a thin vertical wall from bucketTop downward.
|
-- Each divider is a thin vertical wall from bucketTop downward.
|
||||||
@@ -326,10 +328,16 @@ local function physicsLoop()
|
|||||||
vx = vx * s; vy = vy * s
|
vx = vx * s; vy = vy * s
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Tick peg cooldowns
|
-- Tick peg cooldowns; restore normal colour when glow expires
|
||||||
for k, v in pairs(pegCooldown) do
|
for k, v in pairs(pegCooldown) do
|
||||||
pegCooldown[k] = v - DT
|
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
|
end
|
||||||
|
|
||||||
-- ── Peg collisions (only while above bucket zone) ───────────
|
-- ── Peg collisions (only while above bucket zone) ───────────
|
||||||
@@ -363,7 +371,8 @@ local function physicsLoop()
|
|||||||
vy = vy - newVn * ny
|
vy = vy - newVn * ny
|
||||||
end
|
end
|
||||||
|
|
||||||
pegCooldown[i] = 0.08
|
pegCooldown[i] = 0.18 -- glow duration (s)
|
||||||
|
pegLit[i] = true
|
||||||
drawPeg(p, COL_PEG_HIT)
|
drawPeg(p, COL_PEG_HIT)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -67,16 +67,20 @@ local COL_BALL_SHD = 0x444444
|
|||||||
|
|
||||||
-- Ball physics
|
-- Ball physics
|
||||||
local BALL_RADIUS = 8 -- px
|
local BALL_RADIUS = 8 -- px
|
||||||
local BALL_SPEED_MIN = 420 -- px/s initial tangential speed
|
local BALL_SPEED_MIN = 900 -- px/s initial tangential speed
|
||||||
local BALL_SPEED_MAX = 620
|
local BALL_SPEED_MAX = 1300
|
||||||
local TRACK_RESTITUTION = 0.72 -- speed fraction kept on track-wall bounce
|
local TRACK_RESTITUTION = 0.82 -- speed fraction kept on track-wall bounce
|
||||||
local POCKET_RESTITUTION = 0.45 -- speed fraction kept bouncing inside pocket ring
|
local POCKET_RESTITUTION = 0.52 -- speed fraction kept bouncing inside pocket ring
|
||||||
local FRICTION_TRACK = 0.992 -- multiplier per frame while in track (energy loss)
|
local FRICTION_TRACK = 0.9985 -- multiplier per frame while in track
|
||||||
local FRICTION_POCKET = 0.970 -- higher damping once in pocket ring
|
local FRICTION_POCKET = 0.972 -- higher damping once in pocket ring
|
||||||
-- Ball enters pocket ring when its speed drops below this
|
-- Centripetal slide: inward acceleration applied as ball slows, simulating
|
||||||
local DROP_SPEED = 90 -- px/s
|
-- 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
|
-- 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
|
-- GPU / pixel primitives
|
||||||
@@ -315,6 +319,23 @@ local function spin()
|
|||||||
vx = vx * fric
|
vx = vx * fric
|
||||||
vy = vy * 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
|
-- Integrate
|
||||||
bx = bx + vx * dt
|
bx = bx + vx * dt
|
||||||
by = by + vy * dt
|
by = by + vy * dt
|
||||||
|
|||||||
Reference in New Issue
Block a user