1

Set Up Basic Flutter Project

Set the app orientation and initialize the app.

💡 Tip: Use the button on the right side to easily copy the code.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
    WidgetsFlutterBinding.ensureInitialized();
    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
    runApp(const BalloonBlaster());
}

class BalloonBlaster extends StatelessWidget {
    const BalloonBlaster({super.key});

    @override
    Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Balloon Blaster',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: const GameScreen(),
    );
    }
}

2

Define Balloon and Arrow Classes

Create basic classes to define Balloon and Arrow objects.
These classes store attributes for each balloon and arrow in the game.

💡 Tip: Use the button on the right side to easily copy the code.

import 'dart:math';

class Balloon {
    double x, y;
    final Color color;
    final double speed;
    final int points;
    bool isPopped;

    Balloon({
    required this.x,
    required this.y,
    required this.color,
    required this.speed,
    this.points = 100,
    this.isPopped = false,
    });
}

class Arrow {
    double x, y;
    Offset velocity;
    final double angle;

    Arrow({
    required this.x,
    required this.y,
    required this.velocity,
    required this.angle,
    });
}
                                
3

Set Up Game Screen Widget

Create GameScreen widget to manage the game interface and state.
This widget will control game elements like score, levels, and balloons.

💡 Tip: Use the button on the right side to easily copy the code.

class GameScreen extends StatefulWidget {
    const GameScreen({super.key});
    
    @override
    GameScreenState createState() => GameScreenState();
    }
    
    class GameScreenState extends State<GameScreen> with TickerProviderStateMixin {
    // Game variables
    double _bowX = 0, _bowY = 0;
    double _arrowAngle = 0, _power = 0;
    bool _isDragging = false;
    int _score = 0;
    List<Balloon> _balloons = [];
    List<Arrow> _arrows = [];
    int _level = 1, _remainingArrows = 10;
    bool _isGameActive = false;
    }                             
4

Initialize Game and Balloons

Set up the game initializer and balloon spawner.
Initialize game variables and create balloons based on the level.

💡 Tip: Use the button on the right side to easily copy the code.

void _startGame() {
    setState(() {
        _balloons.clear();
        _arrows.clear();
        _remainingArrows = 10;
        _score = 0;
        _level = 1;
        _spawnBalloons();
        _isGameActive = true;
    });
    }
    
    void _spawnBalloons() {
    final random = Random();
    for (int i = 0; i < 5 + _level; i++) {
        _balloons.add(Balloon(
        x: random.nextDouble() * MediaQuery.of(context).size.width,
        y: MediaQuery.of(context).size.height + random.nextDouble() * 200,
        color: Colors.primaries[random.nextInt(Colors.primaries.length)],
        speed: 2.0 + (_level * 0.5) + random.nextDouble(),
        points: 100 + (_level * 10),
        ));
    }
    }
                                
5

Create Game Loop for Continuous Updates

Implement a game loop to update positions and check collisions.
This loop keeps the game active by updating balloon and arrow positions.

💡 Tip: Use the button on the right side to easily copy the code.

void _startGameLoop() {
    Timer.periodic(const Duration(milliseconds: 16), (timer) {
        _updateGame();
    });
    }
    
    void _updateGame() {
    setState(() {
        for (var balloon in _balloons) {
        if (!balloon.isPopped) balloon.y -= balloon.speed;
        }
        for (var arrow in _arrows) {
        arrow.x += arrow.velocity.dx;
        arrow.y += arrow.velocity.dy;
        arrow.velocity = Offset(arrow.velocity.dx, arrow.velocity.dy + 0.2);
        }
        _checkCollisions();
    });
    }
    
6

Add Collision Detection

Detect collisions between arrows and balloons.
Update score when a collision is detected.

💡 Tip: Use the button on the right side to easily copy the code.

void _checkCollisions() {
    for (var arrow in _arrows) {
        for (var balloon in _balloons) {
        if (!balloon.isPopped && _checkCollision(arrow, balloon)) {
            balloon.isPopped = true;
            _score += balloon.points;
            Future.delayed(const Duration(milliseconds: 100), () {
            setState(() => _balloons.remove(balloon));
            });
            break;
        }
        }
    }
    }
    
    bool _checkCollision(Arrow arrow, Balloon balloon) {
    final dx = arrow.x - balloon.x;
    final dy = arrow.y - balloon.y;
    return sqrt(dx * dx + dy * dy) < 30;
    }
                              
7

Shooting Mechanism for Arrows

Implement functionality for shooting arrows.
Trigger an arrow with a calculated angle and power based on user drag.

💡 Tip: Use the button on the right side to easily copy the code.

void _shootArrow() {
    if (_remainingArrows <= 0) return;
    final velocity = Offset(cos(_arrowAngle) * _power * 20, sin(_arrowAngle) * _power * 20);
    _arrows.add(Arrow(x: _bowX, y: _bowY, velocity: velocity, angle: _arrowAngle));
    _remainingArrows--;
    }  
8

Game Over and Game Painter for Graphics

Add game-over dialog and custom painter for game graphics.
Display the final score and restart option on game over.

💡 Tip: Use the button on the right side to easily copy the code.

void _showGameOver() {
    showDialog(
        context: context,
        builder: (context) => AlertDialog(
        title: const Text('Game Over'),
        content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [Text('Score: $_score'), Text('Level: $_level')],
        ),
        actions: [
            TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('Play Again'),
            ),
        ],
        ),
    );
    }
                                                        
 
Step 1 of 8