DEV Community

Cover image for 🐦 VibeCoding - AmazonQ CLI Building Flappy Bird with Phaser 3 + TypeScript: A Journey from Bugs to Victory
Phạm Tiến Thuận Phát
Phạm Tiến Thuận Phát

Posted on • Edited on

🐦 VibeCoding - AmazonQ CLI Building Flappy Bird with Phaser 3 + TypeScript: A Journey from Bugs to Victory

How I created a fully functional Flappy Bird game and learned valuable lessons about game development, debugging, and problem-solving along the way pair with AmazonQ CLI


🎮 The Challenge

Ever wondered what it takes to recreate one of the most addictive mobile games of all time? I recently embarked on a journey to build Flappy Bird from scratch using modern web technologies, and let me tell you - it was quite an adventure!

Tech Stack:

  • 🎯 Phaser 3 - Game engine
  • 📝 TypeScript - Type safety and better DX
  • 📦 Rollup - Module bundling
  • 🎨 HTML5 Canvas - Rendering
  • 🔊 Web Audio API - Sound effects

Image description

🚀 The Development Journey

Phase 1: Setting Up the Foundation

The project started with a clean architecture approach:

flappy-bird-game/ ├── src/ │ ├── scenes/ # Game scenes (Menu, Game, GameOver) │ ├── objects/ # Game entities (Bird, PipeManager, Background) │ ├── config/ # Game configuration │ └── assets/ # Images and sounds 
Enter fullscreen mode Exit fullscreen mode

Key decisions:

  • TypeScript for better code maintainability
  • Scene-based architecture for clean separation of concerns
  • Component-based game objects for reusability

Phase 2: The Physics and Animation

Creating the bird was surprisingly fun! Here's what made it special:

export class Bird { private sprite: Phaser.Physics.Arcade.Sprite; flap(): void { this.sprite.setVelocityY(GameConfig.bird.flapStrength); // -350 px/s this.flapSound.play(); } update(): void { // Realistic rotation based on velocity if (this.sprite.body.velocity.y < 0) { this.sprite.setRotation(-0.5); // Upward tilt } else { this.sprite.setRotation(Math.min(0.5, this.sprite.rotation + 0.05)); } } } 
Enter fullscreen mode Exit fullscreen mode

The magic details:

  • Smooth rotation that follows physics
  • 🎵 Sound feedback on every flap
  • 🎭 3-frame animation for wing flapping

Phase 3: The Great Scoring System Debugging Saga 🐛

This is where things got really interesting. What seemed like a simple feature turned into a fascinating debugging adventure!

The Problem: Score Wasn't Working! 😱

// ❌ This approach FAILED miserably this.physics.add.overlap(bird, pipes, (bird, object) => { if (object.getData('isScoreTrigger')) { score++; // Never executed! } }); 
Enter fullscreen mode Exit fullscreen mode

The symptoms:

  • Game loaded perfectly ✅
  • Bird physics worked ✅
  • Pipes generated correctly ✅
  • Score remained stubbornly at 0 ❌

Image description

The Investigation 🔍

Through extensive console logging, I discovered:

  1. Overlap detection wasn't firing for invisible score triggers
  2. Mixed object types in physics groups caused conflicts
  3. Phaser's collision system was more complex than expected
// Debug logs revealed the truth: console.log('Bird position:', birdX, birdY); // ✅ Working console.log('Score trigger created:', triggerX); // ✅ Working  console.log('Overlap detected:', object); // ❌ Never appeared! 
Enter fullscreen mode Exit fullscreen mode

The Breakthrough: Manual Position Tracking 💡

Instead of fighting with Phaser's physics system, I implemented a custom scoring algorithm:

private checkScoreManually(): void { const birdX = 50; // Bird stays at fixed X position this.scoreTriggers.forEach(trigger => { // Pipes move left: X(t) = X₀ + velocity × deltaTime trigger.x += GameConfig.pipes.speed * deltaTime; // -200 px/s // Score when pipe passes bird (left movement) if (!trigger.scored && trigger.x <= birdX && trigger.x > birdX - 50) { trigger.scored = true; this.passedPipes++; this.scene.events.emit('score-updated', this.passedPipes); } }); } 
Enter fullscreen mode Exit fullscreen mode

The key insight: In Flappy Bird, the bird doesn't move horizontally - the pipes move toward the bird! 🤯

🎯 Technical Highlights

1. Smart Asset Management

// Automated asset copying during build const copyAssets = () => { copyDir('./src/assets', './dist/src/assets'); console.log('Assets copied successfully!'); }; 
Enter fullscreen mode Exit fullscreen mode

2. Persistent High Score System

// Simple but effective localStorage implementation const highScore = localStorage.getItem('flappyHighScore') || 0; if (currentScore > highScore) { localStorage.setItem('flappyHighScore', String(currentScore)); showNewRecordAnimation(); // ✨ Visual feedback } 
Enter fullscreen mode Exit fullscreen mode

3. Performance Optimizations

  • Object pooling for pipes
  • Manual cleanup of off-screen objects
  • Efficient collision detection only where needed
  • Optimized sprite animations

🏆 The Final Result

After solving the scoring system puzzle, everything clicked into place:

Game Features:

  • Smooth 60fps gameplay
  • Accurate collision detection
  • Persistent high scores
  • Sound effects and animations
  • Responsive controls (mouse + keyboard)
  • Mobile-friendly design

🎓 Lessons Learned

1. Sometimes Simple Solutions Win

Complex framework features aren't always the answer. My manual position tracking turned out to be more reliable than Phaser's built-in collision system.

2. Debug Logging is Your Best Friend

console.log('🎯 Manual score detection! Pipe passed bird at X:', triggerX); console.log('✅ New score:', this.passedPipes); 
Enter fullscreen mode Exit fullscreen mode

Those emoji-filled logs made debugging actually enjoyable!

3. Understanding Game Mechanics Matters

I initially misunderstood how Flappy Bird works. The bird doesn't move horizontally - this insight was crucial for fixing the scoring system.

4. TypeScript + Game Development = ❤️

Type safety caught numerous bugs before runtime and made refactoring much safer.

🔧 The Architecture That Worked

graph TB A[GameScene] --> B[Bird] A --> C[PipeManager] A --> D[Background] C --> E[Manual Score Detection] B --> F[Physics & Animation] A --> G[Collision System] H[GameConfig] --> A 
Enter fullscreen mode Exit fullscreen mode

Detailed Class Diagram

Key Components:

  • GameScene: Orchestrates everything
  • Bird: Physics-based player character
  • PipeManager: Obstacle generation + custom scoring
  • Background: Scrolling environment
  • GameConfig: Centralized configuration

🚀 Try It Yourself!

Want to build your own version? Here's the quick start:

# Clone and setup git clone <your-repo> cd flappy-bird-game npm install # Build and run npm run build npm run serve # Open http://localhost:8080 
Enter fullscreen mode Exit fullscreen mode

Pro tips for aspiring game developers:

  1. Start with a simple game loop
  2. Add one feature at a time
  3. Debug with extensive logging
  4. Don't be afraid to try different approaches
  5. Test frequently on different devices

🎮 What's Next?

The game is fully playable, but there's always room for improvement:

  • 📱 Mobile touch controls
  • 🎨 Particle effects for enhanced visuals
  • 🏆 Online leaderboards
  • 🎵 Background music
  • 🔧 Level editor

💭 Final Thoughts

Building Flappy Bird taught me that game development is as much about problem-solving as it is about coding. The scoring system bug that initially frustrated me became the most educational part of the entire project.

The real victory wasn't just creating a working game - it was learning to debug systematically, think creatively about solutions, and persist through challenging problems.

Whether you're a seasoned developer or just starting out, I encourage you to try building a simple game. You'll be surprised by how much you learn about programming, problem-solving, and the satisfaction of creating something interactive and fun!


🔗 Resources & Links


What's your experience with game development? Have you faced similar debugging challenges? Share your stories in the comments below! 👇

Happy coding, and may your birds always flap smoothly! 🐦✨


Tags: #AmazonQCLI #gamedev #typescript #phaser #javascript #webdev #debugging #flappybird #html5games

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.