A music-free, reflex-based mobile arcade game built with Expo SDK 54 (React Native).
Pattern spawns → Player inputs (tap / drag) → Hit accuracy judged → Score + combo updated → Difficulty increases → Miss = Game Over
| Feature | Detail |
|---|---|
| TAP | A shrinking ring converges on a circle. Tap at the right moment. |
| DRAG | Swipe from the start circle to the end circle within the time limit. |
| Accuracy | PERFECT (+2×mult) / GOOD (+1×mult) / MISS → Game Over |
| Combo | 10→×1.2 · 25→×1.5 · 50→×2.0 |
| Difficulty | Speeds up every 10 s of gameplay, 20 levels max |
| Best score | Persisted with AsyncStorage |
| Continue | Watch a rewarded ad once per run to resume |
| 15-min timer | Interstitial shown after 15 min of active gameplay (never mid-run) |
src/
ads/
adService.ts ← orchestrates all ad calls
rewarded.ts ← rewarded ad (mock → swap for real SDK)
interstitial.ts ← interstitial ad (mock → swap for real SDK)
adTimers.ts ← 15-min gameplay timer
game/
patternEngine.ts ← generates TAP/DRAG patterns
scoring.ts ← hit detection, combo math, AsyncStorage
gameLoop.ts ← re-exports / types
components/
GameCanvas.tsx ← renders patterns, handles PanResponder input
HUD.tsx ← score + combo overlay
GameOver.tsx ← end-of-run modal
screens/
Home.tsx ← main menu
Game.tsx ← game loop orchestration
App.tsx
npm install
npx expo startOpen on device with Expo Go (iOS/Android) or an emulator.
npm install react-native-google-mobile-ads- Add to
app.json:"plugins": [ ["react-native-google-mobile-ads", { "androidAppId": "ca-app-pub-xxxxxxxx~yyyyyyyy", "iosAppId": "ca-app-pub-xxxxxxxx~yyyyyyyy" }] ]
- Build a dev client:
npx expo run:iosornpx expo run:android - Replace the mock functions in
src/ads/rewarded.tsandsrc/ads/interstitial.tswith the real SDK calls. The interfaces stay the same.
Ads should never interrupt gameplay flow — only extend or transition it.