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 |
Front camera ──▶ QuickPose (body landmarks) ──▶ eye midpoint ──▶ screen eye line ──▶ bird
│
└──▶ learned head range ──▶ pipe openings + rep counter
HeadTracker runs QuickPose's light pose model on the front camera. It reads the left and right .eye landmarks and publishes their midpoint.GameEngine takes 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.RepCounter turns head height into reps, with hysteresis between the "top" and "deep" thresholds.Clone the repo and open Flappy Pushups.xcodeproj. Xcode resolves the quickpose-ios-sdk Swift 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.
| 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.
.fitness(.squats) and others)..rangeOfMotion(.elbow(side:clockwiseDirection:)) to confirm real depth rather than head travel alone, and flag sagging hips.GameEngine, RepCounter and HeadRange.Camera frames are processed on-device by QuickPose. No images or video leave the phone. Run history is stored locally.
Flappy Pushups/Fonts)3 commits
Swift
100.0%
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 |
Front camera ──▶ QuickPose (body landmarks) ──▶ eye midpoint ──▶ screen eye line ──▶ bird
│
└──▶ learned head range ──▶ pipe openings + rep counter
HeadTracker runs QuickPose's light pose model on the front camera. It reads the left and right .eye landmarks and publishes their midpoint.GameEngine takes 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.RepCounter turns head height into reps, with hysteresis between the "top" and "deep" thresholds.Clone the repo and open Flappy Pushups.xcodeproj. Xcode resolves the quickpose-ios-sdk Swift 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.
| 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.
.fitness(.squats) and others)..rangeOfMotion(.elbow(side:clockwiseDirection:)) to confirm real depth rather than head travel alone, and flag sagging hips.GameEngine, RepCounter and HeadRange.Camera frames are processed on-device by QuickPose. No images or video leave the phone. Run history is stored locally.
Flappy Pushups/Fonts)3 commits
Swift
100.0%