• Home
  • Insight
  • Blog
  • Business
  • Entertainment
  • Health
  • Politics
  • Shop
    • Gift Shop
    • Value Shop
    • Store
    • Bargain Shop
    • Discount
  • Sports
  • Tech
  • Travel
  • USA
  • Video
  • World
    • Asia
    • Africa
    • South America
    • North America
    • Europe
    • Oceania
Sunday, March 15, 2026
No Result
View All Result
Subscribe Now
  • Home
  • Insight
  • Blog
  • Business
  • Entertainment
  • Health
  • Politics
  • Shop
    • Gift Shop
    • Value Shop
    • Store
    • Bargain Shop
    • Discount
  • Sports
  • Tech
  • Travel
  • USA
    Headless victim in 1976 New York cold case identified through DNA: police

    Headless victim in 1976 New York cold case identified through DNA: police

    What’s Good? – The New York Times

    What’s Good? – The New York Times

    Israel’s Deadly Blockade Traps 7 U.S. Doctors in Gaza

    Israel’s Deadly Blockade Traps 7 U.S. Doctors in Gaza

    Carney announces billions for defense and infrastructure in Canada’s North

    Carney announces billions for defense and infrastructure in Canada’s North

    Right-wing media’s Mamdani outrage fuels GOP anti-Muslim rhetoric

    Right-wing media’s Mamdani outrage fuels GOP anti-Muslim rhetoric

    12-year-old girl dies days after collapsing following fight near school bus stop

    12-year-old girl dies days after collapsing following fight near school bus stop

    Speaker Mike Johnson Sketches ‘Course Correction’ in DHS Deportation Policy

    Speaker Mike Johnson Sketches ‘Course Correction’ in DHS Deportation Policy

    Where Was ‘War Machine’ Filmed? Discover the ‘War Machine’ 2026 Filming Locations for Alan Ritchson’s Netflix Movie

    Where Was ‘War Machine’ Filmed? Discover the ‘War Machine’ 2026 Filming Locations for Alan Ritchson’s Netflix Movie

    L.A. City Council candidate stays in race after report that he stabbed a boy at age 12

    L.A. City Council candidate stays in race after report that he stabbed a boy at age 12

  • Video
  • World
    • Asia
    • Africa
    • South America
    • North America
    • Europe
    • Oceania
The Insight Post
  • Home
  • Insight
  • Blog
  • Business
  • Entertainment
  • Health
  • Politics
  • Shop
    • Gift Shop
    • Value Shop
    • Store
    • Bargain Shop
    • Discount
  • Sports
  • Tech
  • Travel
  • USA
    Headless victim in 1976 New York cold case identified through DNA: police

    Headless victim in 1976 New York cold case identified through DNA: police

    What’s Good? – The New York Times

    What’s Good? – The New York Times

    Israel’s Deadly Blockade Traps 7 U.S. Doctors in Gaza

    Israel’s Deadly Blockade Traps 7 U.S. Doctors in Gaza

    Carney announces billions for defense and infrastructure in Canada’s North

    Carney announces billions for defense and infrastructure in Canada’s North

    Right-wing media’s Mamdani outrage fuels GOP anti-Muslim rhetoric

    Right-wing media’s Mamdani outrage fuels GOP anti-Muslim rhetoric

    12-year-old girl dies days after collapsing following fight near school bus stop

    12-year-old girl dies days after collapsing following fight near school bus stop

    Speaker Mike Johnson Sketches ‘Course Correction’ in DHS Deportation Policy

    Speaker Mike Johnson Sketches ‘Course Correction’ in DHS Deportation Policy

    Where Was ‘War Machine’ Filmed? Discover the ‘War Machine’ 2026 Filming Locations for Alan Ritchson’s Netflix Movie

    Where Was ‘War Machine’ Filmed? Discover the ‘War Machine’ 2026 Filming Locations for Alan Ritchson’s Netflix Movie

    L.A. City Council candidate stays in race after report that he stabbed a boy at age 12

    L.A. City Council candidate stays in race after report that he stabbed a boy at age 12

  • Video
  • World
    • Asia
    • Africa
    • South America
    • North America
    • Europe
    • Oceania
No Result
View All Result
No Result
View All Result
Home Mobile

Create 2D games quickly and easily with Flutter Flame

by Theinsightpost
August 2, 2022
in Mobile
0 0
0
Create 2D games quickly and easily with Flutter Flame


Ivy Walobwa shows you in this article how to build a game with Flutter Flame.

Flutter enables you to develop applications for platforms such as Android, iOS, desktop, and the web from a single codebase. As a multiplatform UI toolkit, the Flutter team is dedicated to enabling all kinds of developers to quickly build and release applications. Game developers, for instance, are now able to build beautiful game apps without worrying about performance, load times, and app sizes.

This tutorial will provide you with an introduction to the Flutter Flame game engine. You’ll learn how to set up and build a Flutter Flame game, load sprites, and add animations.

This tutorial assumes that you have a working knowledge of Dart and Flutter.

Flame engine

Flame is a 2D game development framework that runs on top of Flutter. The Flame engine makes it easy to implement a game loop and other necessary functions, such as animations, collision and bounce detection, and parallax scrolling.

Flame is modular and provides independent packages that you can use to extend its functionality, such as:

Flutter Flame setup

To get started with Flame, you need to install the package. In your pubspec.yaml file, add the dependency as shown below:

    dependencies:
      flame: ^1.1.1

To render a game, you use the GameWidget. Adding the code snippet below in the main.dart file renders a Flame game, which is currently a black screen.

    void main() {
      final game = FlameGame();
      runApp(
        GameWidget(
          game: game,
        ),
      );
    }

You are now ready to add some graphics to your game.

Loading sprites

To render static images, you’ll need to make use of the SpriteComponent class. Add your game graphics in the assets/images folder, and update your pubspec.yaml file to load the assets. This tutorial contains player and background images that will be loaded.

You’ll create and update the three files below in the lib folder:

  • dino_player.dart, which will load and position our player:
    import 'package:flame/components.dart';
    
    class DinoPlayer extends SpriteComponent with HasGameRef {
      DinoPlayer() : super(size: Vector2.all(100.0));
    
      @override
      Future<void> onLoad() async {
        super.onLoad();
        sprite = await gameRef.loadSprite('idle.png');
        position = gameRef.size / 2;
      }
    }

  • dino_world.dart, which will load our game background:
    import 'package:flame/components.dart';
    
    class DinoWorld extends SpriteComponent with HasGameRef {
      @override
      Future<void> onLoad() async {
        super.onLoad();
        sprite = await gameRef.loadSprite('background.png');
        size = sprite!.originalSize;
      }
    }
  • dino_game.dart, which will manage all our game components. It adds our game player and background and positions them:
    import 'dart:ui';
    
    import 'package:flame/game.dart';
    import 'dino_player.dart';
    import 'dino_world.dart';
    
    class DinoGame extends FlameGame{
      DinoPlayer _dinoPlayer = DinoPlayer();
    DinoWorld _dinoWorld = DinoWorld();
      @override
      Future<void> onLoad() async {
        super.onLoad();
        await add(_dinoWorld);
        await add(_dinoPlayer);
        _dinoPlayer.position = _dinoWorld.size / 1.5;
        camera.followComponent(_dinoPlayer,
            worldBounds: Rect.fromLTRB(0, 0, _dinoWorld.size.x, _dinoWorld.size.y));
      }
    }

The camera.followComponent function sets the game viewport to follow the player. This function is necessary, as we’ll be adding motion to our player.

Update your main.dart file to load the DinoGame as shown below:

    import 'package:flame/game.dart';
    import 'package:flutter/material.dart';
    import 'dino_game.dart';
    
    void main() {
      final game = DinoGame();
      runApp(
        GameWidget(game: game),
      );
    }

Running your application should display your player and a background.

Sprite movement

To move your player, you need to detect and respond to the direction you select. In this tutorial, you’ll use the game’s arrow keys to add movement to your player.

First, create a helpers folder with the files below, and update them as shown:

  • directions.dart contains the directions enum:
    enum Direction { up, down, left, right, none }
  • navigation_keys.dart contains the UI and logic of the navigation keys:
    import 'package:flutter/gestures.dart';
    import 'package:flutter/material.dart';
    import 'directions.dart';
    
    class NavigationKeys extends StatefulWidget {
      final ValueChanged<Direction>? onDirectionChanged;
    
      const NavigationKeys({Key? key, required this.onDirectionChanged})
          : super(key: key);
    
      @override
      State<NavigationKeys> createState() => _NavigationKeysState();
    }
    
    class _NavigationKeysState extends State<NavigationKeys> {
      Direction direction = Direction.none;
    
      @override
      Widget build(BuildContext context) {
        return SizedBox(
          height: 200,
          width: 120,
          child: Column(
            children: [
              ArrowKey(
                icons: Icons.keyboard_arrow_up,
                onTapDown: (det) {
                  updateDirection(Direction.up);
                },
                onTapUp: (dets) {
                  updateDirection(Direction.none);
                },
                onLongPressDown: () {
                  updateDirection(Direction.up);
                },
                onLongPressEnd: (dets) {
                  updateDirection(Direction.none);
                },
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ArrowKey(
                    icons: Icons.keyboard_arrow_left,
                    onTapDown: (det) {
                      updateDirection(Direction.left);
                    },
                    onTapUp: (dets) {
                      updateDirection(Direction.none);
                    },
                    onLongPressDown: () {
                      updateDirection(Direction.left);
                    },
                    onLongPressEnd: (dets) {
                      updateDirection(Direction.none);
                    },
                  ),
                  ArrowKey(
                    icons: Icons.keyboard_arrow_right,
                    onTapDown: (det) {
                      updateDirection(Direction.right);
                    },
                    onTapUp: (dets) {
                      updateDirection(Direction.none);
                    },
                    onLongPressDown: () {
                      updateDirection(Direction.right);
                    },
                    onLongPressEnd: (dets) {
                      updateDirection(Direction.none);
                    },
                  ),
                ],
              ),
              ArrowKey(
                icons: Icons.keyboard_arrow_down,
                onTapDown: (det) {
                  updateDirection(Direction.down);
                },
                onTapUp: (dets) {
                  updateDirection(Direction.none);
                },
                onLongPressDown: () {
                  updateDirection(Direction.down);
                },
                onLongPressEnd: (dets) {
                  updateDirection(Direction.none);
                },
              ),
            ],
          ),
        );
      }
    
      void updateDirection(Direction newDirection) {
        direction = newDirection;
        widget.onDirectionChanged!(direction);
      }
    }
    
    class ArrowKey extends StatelessWidget {
      const ArrowKey({
        Key? key,
        required this.icons,
        required this.onTapDown,
        required this.onTapUp,
        required this.onLongPressDown,
        required this.onLongPressEnd,
      }) : super(key: key);
      final IconData icons;
      final Function(TapDownDetails) onTapDown;
      final Function(TapUpDetails) onTapUp;
      final Function() onLongPressDown;
      final Function(LongPressEndDetails) onLongPressEnd;
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTapDown: onTapDown,
          onTapUp: onTapUp,
          onLongPress: onLongPressDown,
          onLongPressEnd: onLongPressEnd,
          child: Container(
            margin: const EdgeInsets.all(8),
            decoration: BoxDecoration(
              color: const Color(0x88ffffff),
              borderRadius: BorderRadius.circular(60),
            ),
            child: Icon(
              icons,
              size: 42,
            ),
          ),
        );
      }
    }

Then, update the main.dart file to display your game and keys as shown below:

    void main() {
      final game = DinoGame();
      runApp(
        MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: Stack(
              children: [
                GameWidget(
                  game: game,
                ),
                Align(
                  alignment: Alignment.bottomRight,
                  child: NavigationKeys(onDirectionChanged: game.onArrowKeyChanged,),
                ),
              ],
            ),
          ),
        ),
      );
    }

Add the function below into the dino_game.dart file to execute the player’s movement:

    onArrowKeyChanged(Direction direction){
      _dinoPlayer.direction = direction;
    }

Finally, update the dino_player.dart file to update the player’s position by including the code snippet below:

    Direction direction = Direction.none;
    
    @override
    void update(double dt) {
      super.update(dt);
      updatePosition(dt);
    }
    
    updatePosition(double dt) {
      switch (direction) {
        case Direction.up:
          position.y --;
          break;
        case Direction.down:
          position.y ++;
          break;
        case Direction.left:
          position.x --;
          break;
        case Direction.right:
          position.x ++;
          break;
        case Direction.none:
          break;
      }
    }

Running your application and pressing any of the arrow keys should update your player’s position.

Sprite animations

Now, your player moves as expected, but the movement is not yet animated to look natural. To animate your player, you’ll need to make use of a sprite sheet.

A sprite sheet is a collection of sprites arranged in rows and columns. It is quick to load compared with individual sprites. The Flame engine can load and render only a section of the sprite sheet. The image below displays a sprite sheet of the dino player.

Sprite sheet

The sprite sheet contains different player frames that can be animated to illustrate actions like walking right or left. The sprite sheet is added to the assets/images folder.

To animate your player, do the following in the dino_player.dart file:

  1. Extend SpriteAnimationComponent instead of SpriteComponent.
  2. Initialize your animations and animation speed. In this tutorial, we’ll focus on the animations for walking left and right.
    late final SpriteAnimation _walkingRightAnimation;
    late final SpriteAnimation _walkingLeftAnimation;
    late final SpriteAnimation _idleAnimation;
    
    final double _animationSpeed = .15;
  1. Load your sprites from the sprite sheet. The sprites are loaded depending on their position on the sheet. You can load the sprites by specifying the width and column of each sprite or by selecting each sprite based on its row and column position.
    Future<void> _loadAnimations() async {
      final spriteSheet = SpriteSheet.fromColumnsAndRows(
          image: await gameRef.images.load('spritesheet.png'),
          columns: 30,
          rows: 1);
    
      _idleAnimation = spriteSheet.createAnimation(
          row: 0, stepTime: _animationSpeed, from: 0, to: 9);
    
      _walkingRightAnimation = spriteSheet.createAnimation(
          row: 0, stepTime: _animationSpeed, from: 10, to: 19);
    
      _walkingLeftAnimation = spriteSheet.createAnimation(row: 0, stepTime: _animationSpeed, from: 20, to: 29);
    }

The spriteSheet.createAnimation function selects a sequence of sprites defined by the row, from, and to properties and animates them.

  1. Update the player to load the selected animation.

First, override the onLoad function to load the _idleAnimation.

    @override
    Future<void> onLoad() async {
      super.onLoad();
      await _loadAnimations().then((_) => {animation = _idleAnimation});
    }

Then update the updatePosition function to load different animations based on the direction the player is facing. The sprites for the idle state, right movement, and left movement are provided in this tutorial.

    updatePosition(double dt) {
      switch (direction) {
        case Direction.up:
          position.y --;
          break;
        case Direction.down:
          position.y ++;
          break;
        case Direction.left:
          animation = _walkingLeftAnimation;
          position.x --;
          break;
        case Direction.right:
          animation = _walkingRightAnimation;
          position.x ++;
          break;
        case Direction.none:
          animation = _idleAnimation;
          break;
      }
    }

Running your app and moving left or right updates your player’s movement, which looks more realistic now.

Congrats, you just made your first simple game with Flame!

You can use the flame_tiled package to load custom maps or tiles with an added collision layer to your app to improve your game. To design maps and tiles, you need to know how to create them using Tiled.

You can also add audio to your game using the flame_audio package.

Build and share your app artifacts with Codemagic

So you’ve created your game using the Flame engine, but how can you easily build it and share your app artifacts? The solution is to use a CI/CD tool like Codemagic to automatically handle all the builds, tests, and releases for your project.

To build and share your app artifacts with Codemagic, you first need to have your Flutter app hosted on your favorite Git provider. To prepare the app for release, you need to:

  • Set the app launcher icon
  • Set the app name
  • Assign a unique app ID

You can follow the guide in the official Flutter documentation to prepare your app for release.

You then need a Codemagic account to use the CI/CD tool. If you don’t already have one, you can sign up for Codemagic with your Git provider. Set up Codemagic by following the steps below:

  1. Create an application and connect a repository from your Git provider.
    Connect repository

  2. Select your project repository and type. In this case, the project type is “Flutter App (via WorkFlow Editor)”.

Select project

Your app is ready, and you can now add some settings to determine how your app is built.

Added application

To build your app, you need to customize the build settings to suit your app:

  1. Click on “Finish build setup” for first-time applications. For an existing app, click on the settings icon.
  2. Select “Android” as your build platform on the Workflow editor page.
    Select build platform
  3. Expand the “Build triggers” section and select your preferred build trigger. You can also configure the watched branches and tags. These settings will trigger an app build whenever they occur.
    Select build trigger
  4. Expand the “Build” section and select your app’s build format and mode.

Select build format

  1. Save the changes and start a new build. Codemagic will add a green check beside your app name if your app builds successfully. Downloadable Android artifacts are added as well.

Build app

Congrats! You just made your first build with Codemagic and can now download and share your app artifacts!

Conclusion

Flame is a lightweight game engine built on Flutter that enables developers to create 2D games quickly.

In this tutorial, you learned how to install and set up Flame. We also covered how to load sprites and add sprite movements and animations by working on a Flutter Flame game example. You were introduced to the different independent packages you can use to enhance your game. Finally, we showed you how to build and share your app artifacts with Codemagic.

You can find the application used in this tutorial on GitHub. We hope you enjoyed this tutorial!


This article is written by Ivy Walobwa, a Flutter Developer and Technical Author. She’s passionate about communities and always willing to help facilitate students’ learning in the tech space. If she’s not building communities or creating content, she’s probably hiking on a random trail. Check out her profile.



Source link

ShareTweetSend
Previous Post

Young innovator transforms dairy sector – Kenya News Agency

Next Post

Scottish independence ignites UK PM race after Liz Truss calls Nicola Sturgeon an ‘attention seeker’

Related News

ROI of AI in Manufacturing: Costs, Speed & Accuracy
Mobile

ROI of AI in Manufacturing: Costs, Speed & Accuracy

March 14, 2026
Avocado Health introduces AI-Powered text coaching for parents
Mobile

Avocado Health introduces AI-Powered text coaching for parents

March 13, 2026
India AI Impact Summit 2026: The Global South Takes Centre Stage in Shaping the Future of AI — Mobile App Development | Design
Mobile

India AI Impact Summit 2026: The Global South Takes Centre Stage in Shaping the Future of AI — Mobile App Development | Design

March 12, 2026
Mobile AppSec in CI/CD: Implementation Guide for DevSecOps
Mobile

Mobile AppSec in CI/CD: Implementation Guide for DevSecOps

March 11, 2026
Next Post
Scottish independence ignites UK PM race after Liz Truss calls Nicola Sturgeon an ‘attention seeker’

Scottish independence ignites UK PM race after Liz Truss calls Nicola Sturgeon an 'attention seeker'

Discussion about this post

Subscribe To Our Newsletters

    Customer Support


    1251 Wilcrest Drive
    Houston, Texas
    77042 USA
    Call-832.795.1420
    e-mail – news@theinsightpost.com

    Subscribe To Our Newsletters

      Categories

      • Africa
      • Africa-East
      • African Sports
      • American Sports
      • Arts
      • Asia
      • Australia
      • Business
      • Business Asia
      • Business- Africa
      • Canada
      • Defense
      • Education
      • Egypt
      • Energy
      • Entertainment
      • Europe
      • European Soccer
      • Finance
      • Germany
      • Ghana
      • Health
      • Insight
      • International
      • Investing
      • Japan
      • Latest Headlines
      • Life & Living
      • Markets
      • Mobile
      • Movies
      • New Zealand
      • Nigeria
      • Politics
      • Scholarships
      • Science
      • South Africa
      • South America
      • Sports
      • Tech
      • Travel
      • Travel-Africa
      • UK
      • USA
      • Weather
      • World
      No Result
      View All Result

      Recent News

      Larkey’s Kangaroos shut off Power for convincing win

      Larkey’s Kangaroos shut off Power for convincing win

      March 15, 2026
      Wild footage shows ‘drunk’ driver hitting multiple cars before being arrested in toilet

      Wild footage shows ‘drunk’ driver hitting multiple cars before being arrested in toilet

      March 15, 2026
      Where traditional education falls short in an increasingly digital world

      Where traditional education falls short in an increasingly digital world

      March 15, 2026
      Documents Reveal Health NZ Knew IT Job Cuts Would Risk Patient Care, Hospital Resilience

      Documents Reveal Health NZ Knew IT Job Cuts Would Risk Patient Care, Hospital Resilience

      March 15, 2026
      • Home
      • Advertise With Us
      • About Us
      • Corporate
      • Consumer Rewards
      • Forum
      • Privacy Policy
      • Social Trends

      Theinsightpost ©2026 | All Rights Reserved. Theinsightpost is an Elnegy LLC company, registered in Texas, USA

      Welcome Back!

      Login to your account below

      Forgotten Password?

      Retrieve your password

      Please enter your username or email address to reset your password.

      Log In

      Add New Playlist

      We are using cookies to give you the best experience on our website.

      You can find out more about which cookies we are using or switch them off in .

      No Result
      View All Result
      • Home
      • Insight
      • Blog
      • Business
      • Entertainment
      • Health
      • Politics
      • Shop
        • Gift Shop
        • Value Shop
        • Store
        • Bargain Shop
        • Discount
      • Sports
      • Tech
      • Travel
      • USA
      • Video
      • World
        • Asia
        • Africa
        • South America
        • North America
        • Europe
        • Oceania

      Theinsightpost ©2026 | All Rights Reserved. Theinsightpost is an Elnegy LLC company, registered in Texas, USA

      The Insight Post
      Powered by  GDPR Cookie Compliance
      Privacy Overview

      This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.

      Strictly Necessary Cookies

      Strictly Necessary Cookie should be enabled at all times so that we can save your preferences for cookie settings.

      Cookie Policy

      More information about our Cookie Policy