Search code examples
flutterspriteflame

How to make a sprite move in individual directions in Flutter/Flame?


I want a character to follow a set of changeable directions in Flutter and Flame Game. This character is a sprite component that should move by block spaces (so moves one block forward, then one block to the left, and so on). Right now, even though each type of movement (forward, left, right, etc.) has it's own movement, the character moves in an arch. It gets to where it needs to be, but it doesn't move in individual blocks, just an arch between them. How do I get the character to move x space one way, then y space another way, at different times?

These are some of the functions that do the movement, calling the functions is just an if statement that loops over a list.

  //moves the character one block up over 1 second
  Future moveForward(Character character) async{
    print("in moveforward");
    character.add(MoveByEffect(Vector2(0, -90), EffectController(duration: 1)),);

  }

  //moves the character to the block on the left over 1 second
  Future moveLeft(Character character) async{
    print("in moveleft");
    character.add(MoveByEffect(Vector2(-90, 0), EffectController(duration: 1)),);
  }

Individually they work the right way (only calling forward only moves forward, only calling left moves left), but when you add a forward and a left, it turns in an arch going through areas that it shouldn't. It almost looks like it's doing all directions over a second?


Solution

  • If you want to chain your effects you'll have to either set the last effect's onComplete to add the next effect or have a queue where you control the effects. When you add both effects like you do currently both of them will be active at the same time.

    To implement a queue system you'd do something like this in your Character class:

    final effectQueue = [];
    
    @override
    void update(double dt) {
      if (effectQueue.isNotEmpty && children.query<Effect>().isEmpty) {
        add(effectQueue.removeAt(0));
      }
    }
    
    // Moves the character one block up over 1 second
    void moveForward() {
      effectQueue.add(MoveByEffect(Vector2(0, -90), EffectController(duration: 1)));
    }