Your First Flutter Flame Game

Mar 6 2024 · Dart 3, Flutter 3.10.1, Android Studio 2021.3.1 or higher, Visual Studo Code 1.7.4 or higher

Part 1: Getting Started With Flame

04. Add Components to Meteormania

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 03. Learn Flame's Core Concepts Next episode: 05. Enable Debug Mode in Components

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 04. Add Components to Meteormania

In this episode, you’ll add more components to your game. Let’s start by looking at all the Components that Meteormania will have:

  • Background
  • Bullet
  • Meteorite
  • Saucer
  • Spaceship

For now, you only have to worry about Background, Meteorite, and Spaceship components. Let’s go over what they should do.

The first component in the list is Background. Background is just to display the stars on top of MeteormaniaGame’s background.

It should also cover all the available width and height of the device.

The second component is Spaceship. Spaceship is the component that the player will control when playing.

It should:

  • Paint itself in the center of the screen.
  • Rotate with gestures from the player.
  • Shoot Bullets to destroy Meteorites or Saucers visible in the screen.
  • Get destroyed when too many Meteorites hit the ship.

Finally, Meteorite is the main enemy. Here’s what Meteorite should be able to handle:

  • Paint itself at a randomly chosen coordinate of the screen.
  • Roam in random directions until hit by a Bullet or the Spaceship.
  • Randomly have one of two possible sizes: big or small.
  • Get destroyed if it hits a Spaceship or a Bullet.
  • If it’s a big Meteorite, then it should break down into pieces instead of getting destroyed.

Background

Start by refactoring the background. Open lib/components/brackground.dart and create a class that extends SpriteComponent.

import 'package:flame/components.dart';

class Background extends SpriteComponent {

}

Then, let’s create a constructor for the component that calls super in the same way that you do in MeteromaniaGame.

Background()
    : super(
        sprite: Sprite(
          Flame.images.fromCache('bg1.png'),
        ),
        size: Vector2(
          GameConstants.cameraWidth,
          GameConstants.cameraHeight,
        ),
      );

Now, open meteormania_game.dart and refactor the initialization of background to use your new component.

final background = Background();

Great, now your background is using a custom component.

Spaceship

Spaceship‘s sprite is located in a different image you’ll need to load it first. In onLoad function, load the spritesheet to Flame like so:

await Flame.images.load('meteormania_spritesheet.png');

This spritesheet contains the definition for most of the game’s asset. Spritesheets contain multiple images that can be loaded together efficiently since you only load it once.

Now, before defining a component, let’s make a utility function to load sprites from our spritesheet. Open lib/utils/load_sprite.dart.

Sprite loadMeteormaniaSprite(
  double x,
  double y,
  double width,
  double height,
) {
  return Sprite(
    Flame.images.fromCache('meteormania_spritesheet.png'),
    srcPosition: Vector2(x, y),
    srcSize: Vector2(width, height),
  );
}

Since you’ll need to load multiple sprites from the same spritesheet, it’s a good idea to define a helper function to do so. Spritesheets usually come with definitions for width, height, and positioning of each sprite in it.

Okay, time to define Spaceship. Open lib/components/spaceship.dart and define the new component.

import 'package:flame/components.dart';

class Spaceship extends SpriteComponent {

}

Then, define the size and position, load the sprite and create a constructor.

static const double spaceshipWidth = 96.0;
static const double spaceshipHeight = 96.0;
static final Vector2 spaceshipSize = Vector2(spaceshipWidth, spaceshipHeight);
static final Sprite shipSprite = loadMeteormaniaSprite(304, 384, 96, 96);

Spaceship() : super(sprite: shipSprite, size: spaceshipSize);

Now, back in MeteormaniaGame, define a new function called initializeGame. You’ll use this new function to add different components to your _world when the game starts.

void initializeGame() {
}

Next, create a new spaceship and set the anchor and position to the center, and call _world.add() from _world.

final spaceship = Spaceship()
  ..anchor = Anchor.center
  ..position = Vector2(
    GameConstants.cameraWidth / 2,
    GameConstants.cameraHeight / 2,
  );

_world.add(spaceship);

For now, call initializeGame inside onLoad.

Meteorite

Adding a Meteorite is a bit trickier since it needs to be positioned randomly in the screen.

Let’s start with the component, open lib/components/meteorite.dart, define the new component and add the possible sizes of a Meteorite.

import 'package:flame/components.dart';

class Meteorite extends SpriteComponent {
  static final Sprite smallSprite = loadMeteormaniaSprite(688, 287, 64, 64);
  static final Vector2 smallSize = Vector2(64, 64);
  static final Sprite bigSprite = loadMeteormaniaSprite(592, 288, 96, 96);
  static final Vector2 bigSize = Vector2(96, 96);
}

Let’s also define an enum with the possible sizes, it’ll make it easier to handle Meteorite in other parts of the game.

enum MeteoriteSize { small, big }

Now, add a new variable for the size of a Meteorite and add two constructors: the first one creates a small Meteorite and the other one creates a big Meteorite.

final MeteoriteSize meteoriteSize;

Meteorite.small()
    : meteoriteSize = MeteoriteSize.small,
      super(
        sprite: smallSprite,
        size: smallSize,
      );

Meteorite.big()
    : meteoriteSize = MeteoriteSize.big,
      super(
        sprite: bigSprite,
        size: bigSize,
      );

As the final step, open MeteormaniaGame again and add a small Meteorite to your game world.

final smallMeteorite = Meteorite.small();

_world.add(smallMeteorite);

Build and run the game to see everything that you have added to the game!