@@ -39,7 +39,7 @@ private const val BIRD_RADIUS = 0.05f // fraction of canvas height
3939private const val PIPE_WIDTH = 0.15f // fraction of canvas width
4040private const val PIPE_GAP = 0.30f // gap height as fraction of canvas height
4141private const val PIPE_SPEED = 0.32f // canvas-widths per second
42- private const val PIPE_SPAWN_MS = 2000L
42+ private const val PIPE_SPACING = 0.64f // distance between consecutive pipe left edges
4343private const val GRAVITY = 2.0f // height-fraction per second squared
4444private const val TAP_IMPULSE = - 0.65f // height-fraction per second, upward
4545// Collision radius is smaller than the visual radius to be forgiving
@@ -74,7 +74,6 @@ class FlappyGameState(
7474 private set
7575
7676 private var lastTickMs = 0L
77- private var lastSpawnMs = 0L
7877
7978 fun tap () {
8079 if (isGameOver) return
@@ -95,11 +94,10 @@ class FlappyGameState(
9594 isGameOver = true ; return
9695 }
9796
98- if (lastSpawnMs == 0L ) lastSpawnMs = nowMs
99- if (nowMs - lastSpawnMs >= PIPE_SPAWN_MS ) {
97+ // Spawn once the previous pipe has moved far enough - keeps spacing consistent at any frame rate
98+ if (pipes.isEmpty() || pipes.last().x <= 1.05f - PIPE_SPACING ) {
10099 // Gap center constrained to 0.26..0.64 so pipes are always passable
101100 pipes = pipes + FlappyPipe (x = 1.05f , gapCenter = Random .nextFloat() * 0.38f + 0.26f )
102- lastSpawnMs = nowMs
103101 }
104102
105103 val hitR = BIRD_RADIUS * HIT_SHRINK
@@ -131,7 +129,6 @@ class FlappyGameState(
131129 isStarted = false
132130 isPaused = false
133131 lastTickMs = 0L
134- lastSpawnMs = 0L
135132 }
136133
137134 fun pause () { if (isStarted && ! isGameOver) isPaused = true }
0 commit comments