Search code examples
flutterflame

Why removing other sprite after collision not working in Flame?


I have two sprites in the game e.g Player and Enemy. After collision detection why remove(Component) method is not working?

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

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

class CGame extends FlameGame with HasCollidables {
  @override
  Future<void>? onLoad() async {
    add(Enemy());
    add(Player());

    return super.onLoad();
  }
}

class Enemy extends SpriteComponent with HasGameRef, HasHitboxes, Collidable {
  Enemy() : super(priority: 1);

  @override
  Future<void>? onLoad() async {
    sprite = await Sprite.load('crate.png');
    size = Vector2(100, 100);
    position = Vector2(200, gameRef.size.y / 3 * 2);
    anchor = Anchor.center;
    addHitbox(HitboxRectangle());

    return super.onLoad();
  }
}

class Player extends SpriteComponent with HasGameRef, HasHitboxes, Collidable {
  @override
  Future<void>? onLoad() async {
    sprite = await Sprite.load('player.png');
    size = Vector2(100, 100);
    position = Vector2(0, gameRef.size.y / 3 * 2);
    anchor = Anchor.center;
    addHitbox(HitboxRectangle());

    return super.onLoad();
  }

  @override
  void update(double dt) {
    position += Vector2(1, 0);
  }

  @override
  void onCollision(Set<Vector2> intersectionPoints, Collidable other) {
    if (other is Enemy) {
      print('Player hit the Enemy!');

      remove(Enemy());  //<== Why this line is not working?
    }
  }
}

Solution

  • You are trying to remove a new instance of an enemy component, you have to remove the specific one that you collided with, which in this case is other. You also want to remove other from the game where it is added, if you do remove on the component you are trying to remove a subcomponent.

      @override
      void onCollision(Set<Vector2> intersectionPoints, Collidable other) {
        if (other is Enemy) {
          other.removeFromParent();
          // It can also be done like this since you have the `HasGameRef` mixin
          // gameRef.remove(other);
        }
      }
    }