Doodle Jump JavaScript: Separate Height From Camera

A repeated bounce from one platform should not keep adding its height to a score. Track the highest world position once and let the camera follow that record.

The jumper moves through a positive-up world of one-way platforms. The display keeps current bottom height, maximum attained height, and camera floor separate. Two explanation buttons compare descending from 42 to 38 with ascending from 38 to 42 at platform height 40.

Doodle Jump JavaScript: Separate Height From Camera
Doodle Jump JavaScript: Separate Height From Camera
Open the full example ↗

Use the worked example

Start the jumper and use Left or Right to adjust horizontal position. Pause to inspect world bottom, high-water height, and camera floor. In the crossing inspector, choose Descending for a landing at 40 and a new upward velocity; choose Ascending to leave the crossing unlanded.

Trace the result step by step

The view covers 320 × 240 world units. The player is 16 × 16, starts at x = 152 with bottom height zero, and bounces upward at 280 units per second under gravity of −560. Left and Right each advance one tick with a horizontal pulse at 100 units per second, clamped to x = 0 through 304.

Each platform is an original horizontal landing surface, 96 wide. Platform Pi has world height 40 × i, for nonnegative integer i. Even-index platforms start at x = 112; odd-index ones at x = 150.

Platform positions belong to the world; the camera only changes where they are drawn. The Descending and Ascending buttons provide fixed explanations of two crossing cases. They are independent teaching examples, not editable inputs or a record of the live jumper's latest landing.

A one-way platform catches a descending player when its previous bottom is at or above platform height, its new bottom reaches or passes that height, and horizontal intervals strictly overlap at the crossing. Moving upward through that height does not land. The platform has no solid underside in this model.

A landing sets upward velocity to +280 at the first eligible descending contact. The rest of that tick then advances from the contact height with the new velocity and gravity. Horizontal overlap is evaluated at the contact time, and an apex reached within either segment contributes to the maximum height. Edge touching without horizontal overlap is not a landing.

Track the largest attained bottom height, including an apex between update endpoints. Camera floor is max(0, maximum height − 120), and the visible interval extends 240 units above it. A maximum of 150 therefore places the floor at 30, regardless of how far the jumper subsequently falls.

The maximum never decreases, so the camera stays up when the jumper falls. Bouncing back to an already reached height does not add points. Read this as a height record: a second visit to height 150 still leaves a maximum of 150 rather than producing a total of 300.

To draw the player's top in a downward-positive screen coordinate system, use 240 − ((bottomHeight + 16) − cameraFloor). A platform surface at height H draws at 240 − (H − cameraFloor). These transformations change the display, not the underlying landing coordinates.

For highWater = 150, cameraFloor = 30. If the player's bottom falls to 12, its top is 28: the whole player lies below the view, producing loss because 28 < 30. Equality is touching the view boundary and does not satisfy this strict loss rule.

Choose First landing example, then Step, to inspect this directly. The preset pauses at step 49 of the initial flight. P1 is reached at about 0.827327 seconds, during the tick ending at 0.833333 seconds. After the remaining 0.006006 seconds, the bottom is about 41.672 and vertical velocity is 276.636. The player has already risen from height 40; the bounce does not wait for the next tick.

Copy a prompt for this example

Build a single HTML automatic-bounce game with an original 320 by 240 world. World height increases upward. A sixteen-by-sixteen player starts at x 152 with bottom height zero and upward velocity 280. Gravity is -560 units per second squared.

Platforms are ninety-six units wide at height 40 times their nonnegative index. Even-index platforms start at x 112; odd-index platforms start at x 150. A descending player lands only when its bottom crosses a platform from above with strict horizontal overlap. Choose the first crossed eligible platform, bounce upward at 280 at contact time, and integrate the remaining tick with gravity. Track maxima on both segments. Upward crossings do not land.

Keep maximum attained bottom height separate from current height. Camera floor is max(0, maximum height minus 120) and never falls. Lose when the player's entire top is below that floor. Explain that maximum height is not an accumulated score. Display world bottom, top, velocity, x, camera floor, and step count.

Provide Start/Resume, Pause, Step, Reset, and single-step Left/Right pulses at 100 units per second, clamped to x zero through 304. Each pulse advances one fixed tick; it is not a held movement control.

Include two separate fixed teaching explanations: descending 42 to 38 lands on height 40; ascending 38 to 42 does not. Label them as examples rather than editable trajectories. Pause on a hidden page and reset all world and camera state. Add a First landing example paused at initial-flight step 49: elapsed time 49/60, bottom 280t − 280t², velocity 280 − 560t, maximum 70, x 152. The next Step must land on P1 and end near bottom 41.671718 and velocity 276.636361. Return responsive HTML with original simple graphics.

Compare the fixed Descending and Ascending examples, then follow world bottom and maximum height during one run. The prepared HTML jump lab can be previewed in NOS alongside the coordinate notes. Use those separate values to explain why a repeated bounce does not keep adding the same height.

Keep reading