How to use a Sprite Sheet in Flutter with Flame 13 - Animated 2D Games

A sprite is nothing more than an object or character and they are widely used in any game engine such as Unity; in video game development, sprites are where all the movements (states) of a character or object are included; therefore, it is common for a 2D game to have multiple images for each animable object.

we are interested in not only processing a single image, but several of them, for this, we will use an image that consists of several images, like the one generated previously.

A sprite sheet is an image that contains several sprites or smaller images used in 2D game development. Sheets sprites typically represent objects, characters, and game items, and can be static or animated. The sprite sheet allows the game to load multiple images required for the game at once, which can improve loading efficiency and overall game performance. By having all the images in a single image, it makes it easier to manage and organize graphic resources in 2D game development.

Case study

Finally, at the level of our code, we will create the following class:

lib/components/player_sprite_sheet_component.dart

import 'package:flame/sprite.dart';
import 'package:flutter/material.dart';

import 'package:flame/flame.dart';
import 'package:flame/components.dart';

import 'dart:ui';


class PlayerSpriteSheetComponent extends SpriteComponent {
  late double screenWidth, screenHeight, centerX, centerY;
  final double spriteSheetWidth = 680, spriteSheetHeight = 472;

  @override
  Future<void>? onLoad() async {
    //sprite = await Sprite.load('tiger.png');

    final spriteImage = await Flame.images.load('dino.png');
    final spriteSheet = SpriteSheet(image: spriteImage, srcSize: Vector2(spriteSheetWidth, spriteSheetHeight));

    sprite = spriteSheet.getSprite(2, 1);

    screenWidth = MediaQueryData.fromWindow(window).size.width;
    screenHeight = MediaQueryData.fromWindow(window).size.height;

    size = Vector2(spriteSheetWidth, spriteSheetHeight);

    centerX = (screenWidth / 2) - (spriteSheetWidth / 2);
    centerY = (screenHeight / 2) - (spriteSheetHeight / 2);

    position = Vector2(centerX, centerY);

    return super.onLoad();
  } 
}

Explanation of the previous code

As you can see in the previous code, we define the size for each sprite in our sprite sheet; for the image we select, it would be 680 pixels x 472 pixels:

To do this, we use a couple of properties:

late double spriteSheetWidth = 680.0, spriteSheetHeight = 472.0;

It is important to note that you must specify the size according to the sprite you are using.

We load the sprite sheet:

var spriteImages = await Flame.images.load('dino.png');

And we define the spriteSheet so that it can be manipulated through a property; It is in this step that we use the individual dimensions of each state:

final spriteSheet = SpriteSheet(image: spriteImages, srcSize: Vector2(spriteSheetWidth, spriteSheetHeight));

Finally, it is now possible to consult each position of one of the steps of the sprite sheet individually:

sprite = spriteSheet.getSprite(1, 1);

There are sprite sheets with different sizes for each frame or sprite, therefore, you must be sure that the sprite sheet you are using has the same sizes for each of the sprites, in this example it is 680x472 px.

Load a sprite

It is also possible to load sprite using the load function; use the function loadSprite from the Flame class to load the sprite: sprite = await Flame.images.load('image.png');

Once the sprite is loaded, you could use the SpriteComponent component to render it in-game as if it were a component; this may not seem like much, but when using Flame components, we can use features like the collision system, data entry, and in general, any functionality available in a PositionComponent class.

Here is an example of how to load a sprite in Flame:

import 'package:flame/components/sprite_component.dart';
import 'package:flame/flame.dart';
class MyGame extends BaseGame {
 SpriteComponent _spriteComponent;
 MyGame() {
   _loadSprite();
 }
 void _loadSprite() async {
   var image = await Flame.images.load('ruta/a/la/imagen.png');
   _spriteComponent = SpriteComponent.fromImage(0, 0, image);
   add(_spriteComponent);
 }
}

This code will create a new game (MyGame) and load a sprite using Flame's load function, and render it to the SpriteComponent.

Remember that this material is part of my course and book on Flame for 2D game creation.

- Andrés Cruz

En español
Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.