首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >元素的周期性运动。动画中的小延迟问题

元素的周期性运动。动画中的小延迟问题
EN

Stack Overflow用户
提问于 2022-09-14 11:51:01
回答 1查看 88关注 0票数 0

所以我创造了游戏,我想让敌人移动。现在最简单的动作就是一直向左转。我想使它的方式,我下一个移动到数组,所以我不想做无限循环,而是一个机制,应用新的动画。

代码语言:javascript
复制
AnimationController enemy;
Animation _enemyAnimation;
  

void initEnemyAnim(double from, double to, Duration in_time ) {

    enemy = AnimationController(
    vsync: this,
    duration: in_time);

    _enemyAnimation = Tween<double>(begin: from, end: to).animate(CurvedAnimation(parent: enemy, curve: Curves.linear));
    _enemyAnimation.addListener(() {
      _changeMove(_enemyAnimation.value); // this function steers my character position
    });
  }

  void runAi() async {


    double from = 0.0;
    double to = 800.0;

    await Future.delayed(Duration(milliseconds: 8200)); // it's intro, doesnt matter
  
    const oneSec = Duration(seconds:1);

   
    double temp = 0.0;
   
    initEnemyAnim(from, to, Duration(milliseconds: 1000));
    enemy.forward();

    temp=to;
    to=from;
    from=temp;

    Timer.periodic(oneSec, (Timer t)  {
      debugPrint("run $_enemyAnimation.value");

      enemy.reset();
      initEnemyAnim(from, to, Duration(milliseconds: 1000));
      enemy.forward();

      temp=to;
      to=from;
      from=temp;
                
    });

    
  }

敌人的位置在0到800之间。我用TickerProviderStateMixin表示AnimationController

对于委派一个运动,我使用Timer.periodic

问题是,每两个周期的动作都有200毫秒(甚至更多)的停顿。

我的敌人一开始就向右移动。没事的。它向左转,马上就向右转。太棒了。那就是某种停顿。我不知道它为什么表现得像挡风玻璃雨刷。它向左转,向左暂停,向左暂停。

我想用它向左、向右、向右移动的方式.

当我用来添加下一个动画时

代码语言:javascript
复制
_enemyAnimation.addStatusListener((status) {
      
      if(status == AnimationStatus.completed){ }
}

它也有这种滞后性

你知道如何以一种没有中断的方式链接和添加动画吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-14 15:05:58

  1. 动画控制器不应该在动画更改时重新分配。重新分配动画。控制器应该在dispose.
  2. Do中分配一次,在initState中处理,而不是依赖单独的Timer来更改动画。使用控制器侦听器:

代码语言:javascript
复制
enemy.addListener(() {
  if(enemy.isCompleted) {
    _enemyAnimation = ... // Change animation here
    enemy.forward()
  }
});

  1. ,我猜您是在_changeMove中调用setState,这是不建议的,因为当值发生变化时,您正在构建整个小部件树。使用AnimatedBuilder代替并提供AnimatedBuilder只需要对齐顶部、左、右和底部,然后使用对齐而不是双对齐。

完整代码示例:

代码语言:javascript
复制
import 'dart:collection';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin{
 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Material App Bar'),
        ),
        body: AnimationWidget(),
      ),
    );
  }
}

class AnimationWidget extends StatefulWidget {

  @override
  State<AnimationWidget> createState() => _AnimationWidgetState();
}

class _AnimationWidgetState extends State<AnimationWidget> with SingleTickerProviderStateMixin {

   late AnimationController _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 1)
   );

  late Animation<Alignment> _animation;

  var topLeft = Alignment.topLeft;
  var topRight = Alignment.topRight;
  var bottomLeft = Alignment.bottomLeft;
  var bottomRight = Alignment.bottomRight;

  @override
  void initState() {
    _animation = Tween<Alignment>(begin: topLeft, end: topRight)
    .animate(_controller);
     _controller.addListener(() {
      if (_animation.isCompleted && directions.isNotEmpty) {
        changeAnimation();
      }
    });
    _controller.forward();
    super.initState();
  }

  late Queue<Alignment> directions = Queue.from([
    topLeft,
    bottomLeft,
    bottomRight
  ]);

  @override
  Widget build(BuildContext context) {
    print(_animation);
    return Stack(
      alignment: Alignment.center,
      children: [
        AnimatedBuilder(
          animation: _animation,
          builder: (context, child) {
            return Align(
              alignment: _animation.value,
              child: Container(
                color: Colors.red,
                width: 50,
                height: 50,
              ),
            );
          }
        ),
        Center(
          child: ButtonBar(
            alignment: MainAxisAlignment.center,
            children: [
              TextButton(
                child: Text("Up"),
                onPressed: () {
                  press(Alignment(_animation.value.x, -1));
                },
              ),
              TextButton(
                child: Text("Down"),
                onPressed: () {
                  press(Alignment(_animation.value.x, 1));
                },
              ),
              TextButton(
                child: Text("Left"),
                onPressed: () {
                  press(Alignment(-1, _animation.value.y));
                },
              ),
              TextButton(
                child: Text("Right"),
                onPressed: () {
                  press(Alignment(1, _animation.value.y));
                },
              ),
            ],
          ),
        )
      ],
    );
  }

  void press(Alignment alignment) {
    if (alignment == _animation.value) return;
    directions.add(alignment);
    if (!_controller.isAnimating) changeAnimation();
  }

  void changeAnimation() {
     _animation = Tween<Alignment>(
        begin: _animation.value, 
        end: directions.removeFirst()
    ).animate(_controller);
    _controller.reset();
    _controller.forward();
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73716385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档