怎么使用Android Flutter实现精灵图

发布时间:2022-08-31 13:58:29 作者:iii
来源:亿速云 阅读:138

这篇文章主要介绍“怎么使用Android Flutter实现精灵图”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Android Flutter实现精灵图”文章能帮助大家解决问题。

前言

在日常开发中遇到的图片展示一般是静态图和Gif图两种形式(静态和动态的不同)。与此同时当需要对图片做效果时让其动起来,常用方案是Gif图播放或者是帧动画(多种静态图轮询播放)。但在游戏开发中还有一种动图表现形式叫做Sprite图(雪碧图),其在前端开发中也是很常见。为什么需要使用精灵图,因为每张图片显示都需要去发起请求获取,若页面图片数量较多(一个页面有几十个小图)并发请求将是一个大数量级,可能会造成页面加载速度降低,精灵图其中一个特点就是减少服务器请求,一次性加载到所有图片。

如何使用精灵图

在游戏开发中精灵图会将一个人物所有动作放置在一张图片中,通过坐标定位选取其中一张图展示。根据精灵图配置信息来定位到不同图片再通过定时切换选取不同图片从而实现连贯动画效果。

怎么使用Android Flutter实现精灵图

自定义实现加载

自定义实习方式是对精灵图进行加载,因为每帧图片尺寸大小是一致的。

class SpriteWidget extends StatefulWidget {
  final Image image;
  final Size spriteSize;

  final Duration duration;

  SpriteWidget({
    Key key,
    @required this.image,
    @required this.spriteSize,
    @required this.duration,
  }) : super(key: key);

  @override
  _SpriteWidgetState createState() => _SpriteWidgetState();
}

class _SpriteWidgetState extends State<SpriteWidget> {
  Image get image => widget.image;

  Size get spriteSize => widget.spriteSize;

  Duration get duration => widget.duration;
  // 当前显示的图片位置
  int currentIndex = 0;
  int currentTimes = 0;
  
  int startIndex = 0;

  int endIndex = 1;
  int playTimes = 0;

  // 定时器用来更新精灵图加载
  Timer timer;

  @override
  void initState() {
    currentIndex = startIndex;
    timer = Timer.periodic(duration, (timer) {
      if (currentTimes <= playTimes) {
        setState(() {
          if (currentIndex >= endIndex) {
            if (playTimes != 0) currentTimes++;
            if (currentTimes < playTimes || playTimes == 0)
              currentIndex = startIndex;
            else
              currentIndex = endIndex;
          } else
            currentIndex++;
        });
      }
    });
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
    timer?.cancel();
  }

  @override
  Widget build(BuildContext context) {
    // 使用container+Positioned来限制图片显示区域
    return Container(
      width: spriteSize.width,
      height: spriteSize.height,
      child: Stack(
        children: [
          Positioned(
              left: -spriteSize.width * currentIndex,
              top: -spriteSize.height * currentIndex,
              child: image)
        ],
      ),
    );
  }
}

怎么使用Android Flutter实现精灵图

Flame加载精灵图

除了自定义方式实现精灵图加载外,Flutter官方还提供了Flame框架实现游戏内容制作帮助开发者更方便实现游戏相关功能开发。

首先在依赖库添加Flame库,此外bonfireFlame库的拓展封装了更多游戏开发相关功能接口。

  bonfire: ^2.0.0
  flame: ^1.0.0

实现角色资源加载类,bonfire中已经帮助开发者实现了Sprite功能只需要加载精灵图就能获取到精灵图加载能力。

abstract class BaseRole {
  // 速度
  double velocity;
  late Sprite sprite;

  BaseRole({
    this.velocity = 10,
  });

  dynamic load();

  void run();
}
class UserRole extends BaseRole {
  Vector2 offset = Vector2(0.0, 0.0);
  Vector2 size = Vector2(48.0, 48.0);

  @override
  void run() {
    double x = (48 + offset.x) % 192;
    double y = 0;
    offset = Vector2(x, y);
    sprite.srcPosition = offset;
    sprite.srcSize = size;
  }

  @override
  Future load() async {
    sprite = await Sprite.load(
      'user_role.png',
      srcPosition: offset,
      srcSize: size,
    );
    return sprite;
  }
}

bonfire游戏开发中还有SpriteComponent组件,开发者只需要继承它加载使用Sprite即可。

class UserRoleComponent extends SpriteComponent {
  late UserRole userRole;

  UserRoleComponent()
      : super(
          size: Vector2.all(100),
        );

  double minDt = 1 / 8; // 30 fps
  double dtOverflow = 0;

  @override
  Future<void>? onLoad() async {
    userRole = UserRole();
    sprite = await userRole.load();
    super.onLoad();
  }

  @override
  void update(double dt) {
    dtOverflow += dt;
    if (dtOverflow < minDt) {
      return;
    }
    userRole.run();
    dtOverflow = 0;
  }
}

关于“怎么使用Android Flutter实现精灵图”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。

推荐阅读:
  1. css怎么使用精灵图
  2. flutter实现轮播图效果

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

android flutter

上一篇:Java @SentinelResource实例代码分析

下一篇:SQL字符串的合并与拆分怎么实现

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》