1

Set up the Flutter App and Basic Configuration

This sets up the main function, ensuring the app runs in portrait mode and full-screen mode.

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

// Step 1: Import essential libraries and set up main entry point
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
    WidgetsFlutterBinding.ensureInitialized();
    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
    runApp(const MyApp());
}


2

Create the Main Application Widget

The MyApp widget initializes the app, disabling the debug banner and setting the theme. CarRacingGame is set as the main screen.

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

// Step 2: Define MyApp, the root widget of the application
class MyApp extends StatelessWidget {
    const MyApp({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Car Racing Game',
        theme: ThemeData(primarySwatch: Colors.blue),
        home: const CarRacingGame(),
    );
    }
}                                                              
3

Define the Main Game Screen

This step initializes variables for the game, including screen dimensions, the player’s car position, obstacle list, and game state.

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

// Step 3: Create a StatefulWidget for the main game screen
class CarRacingGame extends StatefulWidget {
    const CarRacingGame({Key? key}) : super(key: key);

    @override
    _CarRacingGameState createState() => _CarRacingGameState();
}

class _CarRacingGameState extends State<CarRacingGame> {
    late double screenWidth;
    late double screenHeight;
    late double playerCarX;
    late double laneWidth;
    List<Map<String, dynamic>> obstacles = [];
    Timer? gameTimer;
    Timer? obstacleTimer;
    bool isGameRunning = false;
    int score = 0;
    double roadSpeed = 5;
    double roadPosition = 0;
    final Random random = Random();

    @override
    void didChangeDependencies() {
    super.didChangeDependencies();
    screenWidth = MediaQuery.of(context).size.width;
    screenHeight = MediaQuery.of(context).size.height;
    laneWidth = screenWidth / 3;
    playerCarX = screenWidth / 2 - 25; // Center the car initially
    }
}
                            
4

Implement Start and End Game Functions

startGame() initializes game variables, sets a game loop timer, and starts obstacle generation.
endGame() stops the timers and shows the Game Over dialog.

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

// Step 4: Define functions to start and end the game
void startGame() {
    setState(() {
    isGameRunning = true;
    score = 0;
    roadSpeed = 5;
    obstacles.clear();
    playerCarX = screenWidth / 2 - 25;
    });

    // Start game and obstacle generation timers
    gameTimer = Timer.periodic(const Duration(milliseconds: 16), (timer) {
    updateGame();
    });

    obstacleTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) {
    generateObstacle();
    });
}

void endGame() {
    setState(() {
    isGameRunning = false;
    gameTimer?.cancel();
    obstacleTimer?.cancel();
    });
    showGameOverDialog();
}
                                
5

Show Game Over Dialog

This dialog appears when the game ends, displaying the player’s score and a button to restart.

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

// Step 5: Create a dialog to show when the game ends
void showGameOverDialog() {
    showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
        return AlertDialog(
        title: const Text('Game Over!'),
        content: Text('Your Score: $score'),
        actions: [
            TextButton(
            child: const Text('Play Again'),
            onPressed: () {
                Navigator.of(context).pop();
                startGame();
            },
            ),
        ],
        );
    },
    );
}
                               
6

Generate Obstacles and Update Game State

generateObstacle() randomly creates obstacles on the road.
updateGame() manages road and obstacle positions, checks for collisions, and increments the score.

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

// Step 6: Generate obstacles and update game logic
void generateObstacle() {
    if (!isGameRunning) return;

    setState(() {
    int lane = random.nextInt(3);
    obstacles.add({
        'x': lane * laneWidth + (laneWidth - 50) / 2,
        'y': -100.0,
        'width': 50.0,
        'height': 80.0,
    });
    });
}

void updateGame() {
    if (!isGameRunning) return;

    setState(() {
    roadPosition += roadSpeed;
    if (roadPosition >= 50) roadPosition = 0;

    for (var obstacle in obstacles) {
        obstacle['y'] = (obstacle['y'] as double) + roadSpeed;
    }

    obstacles.removeWhere((obstacle) => obstacle['y'] > screenHeight);

    for (var obstacle in obstacles) {
        if (checkCollision(
        playerCarX,
        screenHeight - 150,
        50.0,
        100.0,
        obstacle['x'],
        obstacle['y'],
        obstacle['width'],
        obstacle['height'],
        )) {
        endGame();
        return;
        }
    }

    score++;
    if (score % 500 == 0) {
        roadSpeed += 0.5;
    }
    });
}

                        
7

Implement Collision Detection and Player Movement

checkCollision() determines if the player’s car has hit an obstacle.
movePlayer() updates the car’s horizontal position when the player drags.

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

// Step 7: Check collisions and move player’s car
bool checkCollision(
    double x1, double y1, double w1, double h1, double x2, double y2, double w2, double h2) {
    return (x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2);
}

void movePlayer(double dx) {
    if (!isGameRunning) return;

    setState(() {
    double newX = playerCarX + dx;
    if (newX >= 0 && newX <= screenWidth - 50) {
        playerCarX = newX;
    }
    });
}

8

Build the Game UI and Components

This creates the main game interface, including road lines, player car, obstacles, score, and a start button overlay. The GestureDetector handles player input for movement.

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

// Step 8: Create the game UI, including player car, obstacles, road lines, and score display
@override
Widget build(BuildContext context) {
    return Scaffold(
    body: GestureDetector(
        onHorizontalDragUpdate: (details) {
        movePlayer(details.delta.dx);
        },
        child: Container(
        width: screenWidth,
        height: screenHeight,
        color: Colors.grey[800],
        child: Stack(
            children: [
            // Road lines
            ...List.generate(20, (index) {
                return Positioned(
                top: (index * 50 + roadPosition - 50).toDouble(),
                left: screenWidth / 3 - 5,
                child: Container(width: 10, height: 30, color: Colors.white),
                );
            }),
            ...List.generate(20, (index) {
                return Positioned(
                top: (index * 50 + roadPosition - 50).toDouble(),
                left: (screenWidth / 3) * 2 - 5,
                child: Container(width: 10, height: 30, color: Colors.white),
                );
            }),

            // Obstacles
            ...obstacles.map((obstacle) {
                return Positioned(
                left: obstacle['x'],
                top: obstacle['y'],
                child: Container(
                    width: obstacle['width'],
                    height: obstacle['height'],
                    color: Colors.blue,
                ),
                );
            }).toList(),

            // Player car
            Positioned(
                left: playerCarX,
                bottom: 50,
                child: Container(
                width: 50,
                height: 100,
                color: Colors.red,
                ),
            ),

            // Score display
            Positioned(
                top: 40,
                left: 20,
                child: Text(
                'Score: ${score ~/ 10}',
                style: const TextStyle(fontSize: 24, color: Colors.white),
                ),
            ),

            // Start game overlay
            if (!isGameRunning)
                Center(
                child: ElevatedButton(
                    onPressed: startGame,
                    child: const Text('START GAME'),
                ),
                ),
            ],
        ),
        ),
    ),
    );
}

                                                        
 
Step 1 of 8