webdevpuneet.com

Cave Flyer Game: 6 Levels, Gems, Stars and Power-Ups

Cave Flyer Game · Games · Plain HTML, CSS & JS · Live preview

CategoryGames

For supporters

Source Code

Want the source code?

Play the game for free. Become a WebDevPuneet supporter to unlock the complete HTML, CSS and JavaScript source code, the exports (HTML, React, Vue, Angular, Tailwind) and Fork.

Play freeSource code: Patreon

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Six levels defined as data (length, gap and speed ramps, hazard chances, theme), with a portal that ends each one
Three stars per level based on the share of gems collected, a level-select grid, and unlocked levels saved in localStorage
One-button hold-to-thrust physics (lift or gravity every frame, clamped velocity), set by a button, the keyboard or a tap and released on pointer up, cancel and leave
A procedural cave of recycled slices with a bounded random-walk centre, a narrowing gap and calm chambers
Gem trails with a combo multiplier up to x5, and a near-miss bonus for skimming spikes
Spikes, moving gates and bats, each with its own cheap collision test (circles and rectangles)
Shield, magnet and slow-motion power-ups
Three themed cave palettes, glowing crystals, parallax silhouettes and a darkness that deepens along each level
Screen shake, particle bursts, thrust sparks, a spinning rotor and a level progress bar
Synthesised sound effects and a rotor hum (Web Audio API) with a mute button, and pause on P, a button or a tab switch

About this UI Snippet

Cave Flyer: Six Levels of One-Button Thrust Physics, Hazards and Game Feel

Screenshot of the Cave Flyer Game snippet rendered live

The one-button "helicopter" game is a lesson in doing the most with the least: one input (hold to rise, release to fall) against a tunnel that keeps tightening. This snippet builds a complete level-based version on one HTML5 <canvas> with no libraries and no image files. You fly a small helicopter through six procedurally generated caves, collect gems in chains for a combo multiplier, dodge spikes, sliding gates and bats, pick up a shield, a magnet or slow-motion, and reach the glowing exit portal at the end of each level to earn up to three stars. It plays with a hold button, Space or the up arrow, or a press anywhere on the game.

Levels are data

Each level is one object in the LEVELS array: a name, a colour theme (crystal, magma or abyss), a length in pixels, a gap that runs from a wide start value to a narrow end value, a speed that runs from slow to fast, and the chance per slice of spikes, gates, bats, power-ups and gem trails. Level 1 has only a few spikes and a wide cave; gates arrive in level 2, bats in level 3, and the last level has a gap down to 96 pixels at close to five pixels per frame. Adding a seventh level means adding one more object. A level ends when the craft crosses the portal at world x = length, and the last 250 pixels before it are kept free of hazards so the run-in feels like a reward.

Stars, level select and saved progress

When you reach the portal you get one star for finishing, a second for collecting at least half of the gems that were generated, and a third for 80% or more. Stars, the best score per level and the number of unlocked levels are saved as one JSON object in localStorage (inside try/catch). The start screen shows a six-button level grid with locks and stars, "Play" continues from the first level you have not cleared, and the clear screen offers "Next level" or "Levels". A crash gives a hint and lets you retry the same level.

Hold-to-thrust physics on one axis

The craft only moves vertically and is driven by one flag. Every frame, if flying is true an upward LIFT acceleration is added to its velocity, otherwise a downward GRAV is added, and the velocity is clamped and added to the position. The craft is never set to a height; it is always accelerating one way or the other, so you hover by feathering the button. The same flag is set by the hold button, the keyboard and a press on the canvas, and cleared on pointer up, cancel and leave, so thrust can never get stuck on.

A procedural cave from recycled slices

The cave is a list of thin vertical slices, each storing a ceiling and a floor height. genSlice() makes the next one by moving the cave's centre with a bounded random walk (so the tunnel curves instead of jittering), narrowing the gap along the level, and occasionally widening it into a calm chamber. Slices that scroll off the left are removed and new ones are added on the right, so memory stays constant. Hazards and pickups live in world coordinates and are spawned as each slice is made, kept out of gem trails and spaced with a cooldown so the cave stays fair.

Cheap, fair collision and a lot of game feel

The wall height is interpolated between slices at three points across the craft, so you cannot clip a corner. Each spike is tested as four circles from its base to its tip, gates as two rectangles and bats as one circle, and skimming a spike gives a "CLOSE!" bonus. A shield absorbs one hit and destroys the hazard. Gems chain into a x5 combo, the magnet pulls gems in, and slow-motion slows the world but not your craft. The screen shakes and the craft bursts into sparks when you crash, the darkness deepens along the level with only a circle of light around the helicopter, and glowing crystals, parallax silhouettes, a spinning rotor and a progress bar add depth. Sound effects and a rotor hum come from the Web Audio API, with a mute button, and the game pauses on P, a button or a tab switch.

Step by step

How to Use

  1. 1
    Pick a level and take offPress Play to continue, or choose a level from the grid (later levels unlock as you clear earlier ones). Hold the HOLD TO FLY button, Space or the up arrow, or press anywhere on the game, to rise. Release to fall, and feather the button to hover.
  2. 2
    Grab gems and build a comboGem trails follow the middle of the cave in a wave. Collect them one after another within about two seconds to raise the multiplier up to x5.
  3. 3
    Dodge the hazardsAvoid spikes on the ceiling and floor, sliding gates (fly through the moving hole) and bats. Flying close to a spike without touching it gives a CLOSE! bonus.
  4. 4
    Use the power-upsA shield absorbs one hit, the magnet pulls gems in for seven seconds, and slow-motion slows the world for five seconds.
  5. 5
    Reach the portal for starsThe glowing portal ends the level. You get one star for finishing, two for collecting half of the gems and three for 80% or more, and the next level unlocks.
  6. 6
    Pause, retry and replayPress P or the pause button to pause (it also pauses when you switch tabs). A crash lets you retry the level, and your stars and best scores are saved in your browser.

Real-world uses

Common Use Cases

A one-button touch game template
Hold-to-thrust is the simplest mobile control, and one flag shared by a button, the keyboard and a canvas tap is a clean pattern to reuse.
Teaching level design as data
A level is one small object, so you can see how changing a gap range, a speed ramp or a spawn chance changes how hard a level feels.
A base for a fuller flyer
The world-coordinate spawner makes it easy to add new hazards, forking tunnels, bosses or fuel, and the level and star system is ready for more levels.
An instantly playable one-more-try game
A one-button game is learned in a second, which makes it a strong embeddable demo for a games site, a blog or a landing page.
An interactive 404 page or loading screen
It has no network dependency and starts instantly as a distraction, like the Flap Dodge Game.
Atmosphere on canvas
A radial-gradient darkness, additive glows and parallax silhouettes show how to get a moody look without images.
Related: Breakout Brick Breaker
See the Breakout Brick Breaker for a related games pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Each level is an object in the LEVELS array with a name, a biome (0, 1 or 2), a length in pixels, gap and speed as [start, end] pairs, and spawn chances for spikes, gates, bats, power-ups and gem trails, plus a darkness value. The gap and speed are interpolated along the level, so the cave tightens and speeds up toward the portal. Add an object to add a level.

The game counts the gems it generates in a level and the ones you collect. Finishing gives one star, collecting at least half gives two, and 80% or more gives three. The best stars and score per level and the number of unlocked levels are stored in localStorage under cave-flyer-progress.

The craft is always accelerating, upward while the button is held and downward when it is released, and the velocity is clamped. Because it is acceleration rather than a fixed speed, short taps give small corrections and feathering the button lets you hover, which is what makes tight gaps possible.

The cave is a list of slices. Each frame the ones that have left the screen are removed from the front and new ones are generated at the back by moving the centre with a bounded random walk. Hazards and pickups are spawned with each new slice and removed once they are behind the camera, so only what is on screen is kept.

Change its gap pair (a bigger minimum is easier), its speed pair, and the spike, gate and bat chances. Setting gate or bat to 0 removes them, and a longer length makes a level longer. GRAV and LIFT near the top of the JS change how the craft handles in every level.

After the cave is drawn, a radial gradient is painted over the whole canvas, clear in a circle just ahead of the craft and fading to a dark colour at the edges. The darkness value grows along the level, so the end of a level is harder to read. Gems, crystals and sparks are drawn afterwards with additive blending so they glow in the dark.