Flutter敌人周期性左右移动动画延迟问题求助
无间隙实现敌人周期性左右移动动画解决方案
问题根源分析
你当前实现出现停顿的核心原因有两点:
- 每次移动都重新创建
AnimationController,初始化、重置控制器的额外开销会导致动画衔接出现间隙。 - 使用
Timer.periodic固定间隔触发动画,无法精准匹配动画实际完成时间,累积偏差后出现停顿。
解决方案:复用控制器+状态监听链式触发新动画
遵循你要求的「添加新动画机制而非无限循环」的思路,我们可以复用同一个AnimationController,在每次动画完成时立即创建新的反向移动动画并启动,确保无间隙衔接。
修正后的完整代码
import 'package:flutter/material.dart'; class EnemyMovementWidget extends StatefulWidget { const EnemyMovementWidget({super.key}); @override State<EnemyMovementWidget> createState() => _EnemyMovementWidgetState(); } class _EnemyMovementWidgetState extends State<EnemyMovementWidget> with TickerProviderStateMixin { AnimationController? _enemyController; Animation<double>? _enemyAnimation; double _currentFrom = 0.0; double _currentTo = 800.0; final Duration _moveDuration = const Duration(milliseconds: 1000); @override void initState() { super.initState(); // 仅初始化一次控制器,避免重复创建开销 _enemyController = AnimationController(vsync: this, duration: _moveDuration); _startMoveAnimation(); runAi(); } void _startMoveAnimation() { // 创建新的移动动画(符合添加新动画的机制) _enemyAnimation = Tween<double>(begin: _currentFrom, end: _currentTo) .animate(CurvedAnimation(parent: _enemyController!, curve: Curves.linear)) ..addListener(() { _changeMove(_enemyAnimation!.value); }) ..addStatusListener((status) { if (status == AnimationStatus.completed) { // 动画完成后立即切换方向,启动下一段新动画 _swapMoveDirection(); _enemyController!.reset(); _startMoveAnimation(); _enemyController!.forward(); } }); } void _swapMoveDirection() { final temp = _currentFrom; _currentFrom = _currentTo; _currentTo = temp; } void _changeMove(double position) { // 此处更新敌人位置逻辑 debugPrint("Enemy position: $position"); } void runAi() async { await Future.delayed(const Duration(milliseconds: 8200)); // 启动第一段动画 _enemyController!.forward(); } @override void dispose() { _enemyController?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return const Placeholder(); } }
关键优化点
- 复用控制器:仅在
initState中初始化一次AnimationController,避免重复创建带来的性能开销和延迟。 - 精准衔接:通过
AnimationStatus.completed监听动画完成事件,在回调中立即切换方向并启动新动画,确保两段动画无间隙衔接。 - 符合需求的新动画机制:每次移动都创建新的
Tween动画实例,而非使用无限循环动画,满足你的设计要求。
内容的提问来源于stack exchange,提问作者sonic
相关产品推荐
相关产品推荐

