fix(ground): synchronize act-scene renderStarted with simulation clock domain and guard bounce height
This commit is contained in:
parent
1568fcbd10
commit
cef09dbd81
|
|
@ -148,12 +148,11 @@ export function resolveGroundItemMetadata(item: any, specifiedAmount?: number):
|
|||
/** Calculate parabolic bounce height h(t) at timestamp now. */
|
||||
export function calculateBounceHeight(bounceState: GroundItemBounceState, now: number): number {
|
||||
const elapsed = now - bounceState.startTime
|
||||
if (elapsed <= 0) return 0
|
||||
if (elapsed >= bounceState.durationMs) return 0
|
||||
if (elapsed <= 0 || elapsed >= bounceState.durationMs) return 0
|
||||
|
||||
const p = elapsed / bounceState.durationMs
|
||||
// Parabolic equation: h(p) = 4 * H * p * (1 - p)
|
||||
return 4 * bounceState.peakHeightPx * p * (1 - p)
|
||||
return Math.max(0, 4 * bounceState.peakHeightPx * p * (1 - p))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6604,9 +6604,10 @@ if (typeof window !== 'undefined') {
|
|||
)
|
||||
}
|
||||
|
||||
const groundSimTime = (engine.world.tick + ((engine.world as any).alpha ?? 0)) * 40
|
||||
for (const gItem of engine.groundItems.all) {
|
||||
pushEntity(gItem.x, gItem.y, () => {
|
||||
drawGroundItem(renderer, gItem, renderStarted, itemsAtlasHandle)
|
||||
drawGroundItem(renderer, gItem, groundSimTime, itemsAtlasHandle)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -438,6 +438,24 @@ describe('Milestone M11.3 (Issue #406) — Ground Item & Gold Spawning, Isometri
|
|||
expect(entity.bounceState).toBeNull()
|
||||
expect(manager.getRenderOffset(entity, 600)).toEqual({ x: 0, y: 0 })
|
||||
})
|
||||
|
||||
it('defensively guards calculateBounceHeight against non-positive or expired elapsed times', () => {
|
||||
const bounce = {
|
||||
startTime: 1000,
|
||||
durationMs: 400,
|
||||
peakHeightPx: 24,
|
||||
}
|
||||
|
||||
// Negative elapsed (sub-frame jitter / out of order): returns 0, never negative
|
||||
expect(calculateBounceHeight(bounce, 900)).toBe(0)
|
||||
expect(calculateBounceHeight(bounce, 999.9)).toBe(0)
|
||||
// Exactly at start (t = 1000): returns 0
|
||||
expect(calculateBounceHeight(bounce, 1000)).toBe(0)
|
||||
// At duration boundary (t = 1400): returns 0
|
||||
expect(calculateBounceHeight(bounce, 1400)).toBe(0)
|
||||
// Far in future: returns 0
|
||||
expect(calculateBounceHeight(bounce, 2000)).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('4. 2:1 Isometric Diamond Grid Scatter Algorithm Parity', () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue