Home > front end >  How to add a sprite on top of another sprite in Flame Flutter?
How to add a sprite on top of another sprite in Flame Flutter?

Time:01-18

The app has a background image with using SpriteComponent and I try to add another Tile image on top of background image. Why the crate.png image doesn't appear on top of background image. Why?

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';

void main() async {
  runApp(GameWidget(
    game: CGame(),
  ));
}

class CGame extends FlameGame {
  @override
  Future<void>? onl oad() async {
    SpriteComponent crate = SpriteComponent()
      ..sprite = await loadSprite('crate.png')
      ..size = Vector2(100, 100)
      ..position = Vector2(250, 300);

    add(crate);
    add(Background());   //<== comment this line to see the loaded crate.png
    add(Crate());

    return super.onLoad();
  }
}

class Background extends SpriteComponent with HasGameRef {
  @override
  Future<void>? onl oad() async {
    sprite = await Sprite.load('background.png');
    size = gameRef.size;

    return super.onLoad();
  }

  @override
  void render(Canvas canvas) {
    super.render(canvas);
  }
}

class Crate extends SpriteComponent with HasGameRef {
  @override
  Future<void>? onl oad() async {
    sprite = await Sprite.load('crate.png');
    size = Vector2(100, 100);
    position = Vector2(200, 200);

    return super.onLoad();
  }
}

CodePudding user response:

Your crate will be behind the background because it loads faster and therefore is added to the component tree faster, to solve this you'll have to set the priority of the crate:

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';

void main() async {
  runApp(GameWidget(
    game: CGame(),
  ));
}

class CGame extends FlameGame {
  @override
  Future<void>? onl oad() async {
    add(Background());
    add(Crate());

    return super.onLoad();
  }
}

class Background extends SpriteComponent with HasGameRef {
  @override
  Future<void>? onl oad() async {
    sprite = await Sprite.load('background.png');
    size = gameRef.size;

    return super.onLoad();
  }
}

class Crate extends SpriteComponent with HasGameRef {
  Crate() : super(priority: 1); // <-- This is what changed

  @override
  Future<void>? onl oad() async {
    sprite = await Sprite.load('crate.png');
    size = Vector2(100, 100);
    position = Vector2(200, 200);

    return super.onLoad();
  }
}

The default priority of components are 0 and the higher the priority is the "closer" to you the component will be, like a higher z-index. So here when we set the crate's priority to 1 it will always appear in front of the background which still has the default priority 0.

And a side note: you don't have to call the render method manually in Background, it is done automatically.

CodePudding user response:

I could solve the issue by adding

 SpriteComponent spriteCompo = SpriteComponent()
      ..sprite = await loadSprite('background.png')
      ..size = size;

    add(spriteCompo);

to the CGame class, but there is a question why it is not working when calling a class Background?

Working snippet:

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';

void main() async {
  runApp(GameWidget(
    game: CGame(),
  ));
}

class CGame extends FlameGame {
  @override
  Future<void>? onl oad() async {

    SpriteComponent spriteCompo = SpriteComponent()
      ..sprite = await loadSprite('background.png')
      ..size = size;

    add(spriteCompo);

    // add(Background());
    add(Crate());

    return super.onLoad();
  }
}

class Background extends SpriteComponent with HasGameRef {
  @override
  Future<void>? onl oad() async {
    sprite = await Sprite.load('background.png');
    size = gameRef.size;

    return super.onLoad();
  }
}

class Crate extends SpriteComponent with HasGameRef {
  @override
  Future<void>? onl oad() async {
    sprite = await Sprite.load('crate.png');
    size = Vector2(100, 100);
    position = Vector2(200, 200);

    return super.onLoad();
  }
}
  •  Tags:  
  • Related