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.