Flappy Bird, but your pushups fly the bird. Prop your phone up, get into a plank, and the bird follows your eye line. Sink down to dive and push up to climb through the pipes.
A demo iOS app built with the QuickPose iOS SDK for on-device pose estimation.
![]() Home |
![]() Get in position |
![]() Gameplay |
![]() Results |
![]() Progress |
![]() Flock |
- Eye-line control. QuickPose tracks both eyes on the front camera and the bird sits exactly on your eye line in the mirrored camera view. There's no calibration step.
- Adaptive pipes. The game learns how far your head travels during a pushup, then sizes and places the openings to fit your range. Openings lean high and low alternately, so every pair of pipes is roughly one rep.
- Rep counting and form feedback. Reps are counted from head movement, with a live pace readout. You get a "GO LOWER!" warning when you push up too early, and a depth-per-rep chart after each run.
- Retro CRT look. Pixel fonts, scanlines and a see-through sky over your live camera feed.
- Progress tracking. Daily streak, reps per day, best runs and an average-depth trend, stored locally with SwiftData.
- Flock leaderboard. Friends' best runs through Game Center. It falls back to your personal bests when you're signed out.
Front camera ──▶ QuickPose (body landmarks) ──▶ eye midpoint ──▶ screen eye line ──▶ bird
│
└──▶ learned head range ──▶ pipe openings + rep counter
HeadTrackerruns QuickPose's light pose model on the front camera. It reads the left and right.eyelandmarks and publishes their midpoint.- The midpoint is mapped into the same aspect-fill, mirrored space as the camera preview. That way the bird lines up with your eyes on screen.
GameEnginetakes your eye position at the end of the countdown as the top of the pushup (arms locked out). It tracks how deep you go during the run and places pipe openings inside that range. The deepest range is remembered for the next run.RepCounterturns head height into reps, with hysteresis between the "top" and "deep" thresholds.
- Xcode 26 or later
- An iPhone running iOS 26.5 or later. The game needs the front camera; in the simulator you can drag to move the bird.
- A free QuickPose SDK key
-
Clone the repo and open
Flappy Pushups.xcodeproj. Xcode resolves thequickpose-ios-sdkSwift package automatically. -
In the target's Signing & Capabilities, pick your team and change the bundle identifier to your own.
-
Register at dev.quickpose.ai for a free SDK key tied to that bundle identifier. Paste it into
Flappy Pushups/Config.swift:static let quickPoseSDKKey = "YOUR_QUICKPOSE_SDK_KEY"
-
Build and run on your iPhone.
The Flock leaderboard uses a Game Center leaderboard with the ID flappypushups.best_pipes, set to "High score is best". Create it in App Store Connect for your app, or change Config.leaderboardID. Without it, the Flock tab shows your own best runs.
- Prop your phone up on the floor in front of you, screen facing you, so the front camera can see your face.
- Get into a plank with your arms locked out. On the Get in position screen the bird appears on your eye line. Hold still and the run starts.
- After the 3-2-1 countdown, sink down to dive and push up to climb. Keep your face in view: if tracking is lost, the game pauses until it finds you again.
| File | What it does |
|---|---|
HeadTracker.swift |
QuickPose and camera lifecycle, eye landmarks, mapping to screen space, lighting check |
GameEngine.swift |
Game loop, learned head range, pipe generation, collisions, rep counting |
GameView.swift |
Game world canvas, HUD, pause menu |
WorldPainter.swift |
Pixel-art drawing (sky, pipes, ground, bird) and the camera backdrop |
SetupView.swift |
"Get in position" screen, live camera preview |
HomeView.swift, StatsView.swift, FlockView.swift, ResultsView.swift |
Tab screens and the run summary |
RunRecord.swift |
SwiftData model and run statistics |
GameCenter.swift |
Game Center sign-in, score submission, friends leaderboard |
Theme.swift |
Palette, pixel fonts, buttons and panels |
To try screens without a camera (Debug builds only), add these under Scheme ▸ Run ▸ Arguments:
| Argument | Effect |
|---|---|
-startScreen home|setup|game|results|progress|flock |
Open straight to a screen |
-seedRuns |
Fill the history with four weeks of sample runs |
-autopilot |
The bird flies itself through every opening |
This is a demo, so there's plenty of room to grow. Pull requests are welcome. Most of these hook into GameEngine (speed, gapHeight, spawnPipe) or reuse QuickPose features that are already in the SDK.
- Easy / Medium / Hard. Presets for opening size, scroll speed, pipe spacing and how fast the game tightens. Easy could accept half-depth reps; Hard could require full depth for every low pipe.
- Speed-ups. Speed ramps after every 10 pipes, "turbo" stretches with a score multiplier, and a brief slow-mo after a crash-free streak.
- Power-ups. Collectables on the eye line: a shield that absorbs one hit, a feather that widens openings, a magnet for coins.
- Plank hold mode. Long runs of mid-height openings that reward holding still. A timed core challenge.
- Workout mode. Target a rep count ("50 pushups") or sets with rest timers instead of an endless run.
- Knee pushups / beginner mode. A shallower expected range, slower pipes and a gentler depth warning.
- Daily challenge. The same seeded pipe layout for everyone each day, with its own leaderboard.
- Squats, sit-ups and jumping jacks. Drive the bird with hip or shoulder height. QuickPose already ships these as fitness features (
.fitness(.squats)and others). - Form scoring from elbow angle. Use
.rangeOfMotion(.elbow(side:clockwiseDirection:))to confirm real depth rather than head travel alone, and flag sagging hips.
- Ghost races. Race a friend's recorded run, shown as a translucent bird.
- Share clips. Export a short video of a run with the overlay, ready for social media.
- Weekly flock challenges and push notifications when a friend passes you.
- 8-bit sound effects, music and voice coaching ("Lower!", "Nice rep!").
- Themes and worlds: day/night skies, city, space, unlocked by total reps.
- Apple Health integration to log workouts and estimated calories.
- A home screen widget and a Live Activity for your streak.
- Settings for camera visibility, CRT effect intensity and a colour-blind palette.
- iPad and landscape layouts; Apple TV with Continuity Camera.
- Unit tests for
GameEngine,RepCounterandHeadRange.
Camera frames are processed on-device by QuickPose. No images or video leave the phone. Run history is stored locally.
- Pose estimation by QuickPose
- Press Start 2P by CodeMan38 and VT323 by Peter Hull, both under the SIL Open Font License (licenses included in
Flappy Pushups/Fonts)






