Search code examples
animationflutterflutter-positioned

how can I animate a sprite to move to an arbitrary point in flutter?


I am trying to learn to use Animations with Stack and PositionedTransitions in Flutter and to that end am making a simple sprite based game. Currently my sprite appear at the end position of their animations rather than at the beginning and then sliding to the end position.
My code looks like this:

if (lamb != null) {
  beginTop = ((lamb.lastY - 1) * roomLength) + lamb.lastY;
  beginLeft = ((lamb.lastX - 1) * roomLength) + lamb.lastX;
  endTop = ((lamb.y - 1) * roomLength) + lamb.y;
  endLeft = ((lamb.x - 1) * roomLength) + lamb.x;
  layerAnimation = RelativeRectTween(
    begin: RelativeRect.fromLTRB(beginLeft, beginTop, 0.0, 0.0),
    end: RelativeRect.fromLTRB(endLeft, endTop, 0.0, 0.0),
  ).animate(_controller.view);
  return PositionedTransition(
    rect: layerAnimation,
    child: Text(
      lamb.emoji,
      style: TextStyle(color: Colors.black, fontSize: roomLength - 12),
    ),
  );
}

Should I include a call to _controller.forward() somewhere? Where or when? There are up to 10 animated widgets on screen at once all using the same _controller, all must slide around at the same time.

Thanks

PS: the following code, instead of the PositionedTransition stuff, seems to be going in the right direction:

 return AnimatedPositioned(
        left: endLeft,
        top: endTop,
        duration: Duration(milliseconds: 900),
        child: Text(
          widget.maze.minotaur.emoji,
          style: TextStyle(color: Colors.black, fontSize: roomLength),
        ),
      );

However I do not know how to specify the beginning point of the animation - it seems to end at the right place and sometimes begins at the right place but how to I force it to begin at the right place? A "Tween" I suppose but if so I'm not sure how to hook that up. Or by adding a key like so, seems to be helping so far :

return AnimatedPositioned(
    key: Key('uniquekey'),
    left: endLeft,
    top: endTop,
    curve: Curves.linear,
    duration: Duration(milliseconds: 900),
    child: Text(
      widget.maze.minotaur.emoji,
      style: TextStyle(color: Colors.black, fontSize: roomLength),
    ),
  );
}

Solution

  • Adding a key like so, seems to be the answer to API question, the key tells the flutter which AnimatedPositioned widget is which between updates so It can know where each begins its journey, without it each is new on each update and the old one is gone so there is no beginnig position to use:

    return AnimatedPositioned(
        key: Key('uniquekey'),
        left: endLeft,
        top: endTop,
        curve: Curves.linear,
        duration: Duration(milliseconds: 900),
        child: Text(
          widget.maze.minotaur.emoji,
          style: TextStyle(color: Colors.black, fontSize: roomLength),
        ),
      );
    }