经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Flutter » 查看文章
Android?Flutter实现精灵图的使用详解
来源:jb51  时间:2022/8/31 17:26:33  对本文有异议

前言

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

如何使用精灵图

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

自定义实现加载

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

  • 每帧图片尺寸固定后就能确认每一帧图片在整张图片的定位位置,因此能够根据X-Y坐标来找到相应图片。
  • 创建定时器调整间隔时间计算出坐标位置切换需要展示图片。
  • 再结合Container+Positioned形式来实现采用偏移量方式显示哪张图片。
  1. class SpriteWidget extends StatefulWidget {
  2. final Image image;
  3. final Size spriteSize;
  4.  
  5. final Duration duration;
  6.  
  7. SpriteWidget({
  8. Key key,
  9. @required this.image,
  10. @required this.spriteSize,
  11. @required this.duration,
  12. }) : super(key: key);
  13.  
  14. @override
  15. _SpriteWidgetState createState() => _SpriteWidgetState();
  16. }
  17.  
  18. class _SpriteWidgetState extends State<SpriteWidget> {
  19. Image get image => widget.image;
  20.  
  21. Size get spriteSize => widget.spriteSize;
  22.  
  23. Duration get duration => widget.duration;
  24. // 当前显示的图片位置
  25. int currentIndex = 0;
  26. int currentTimes = 0;
  27. int startIndex = 0;
  28.  
  29. int endIndex = 1;
  30. int playTimes = 0;
  31.  
  32. // 定时器用来更新精灵图加载
  33. Timer timer;
  34.  
  35. @override
  36. void initState() {
  37. currentIndex = startIndex;
  38. timer = Timer.periodic(duration, (timer) {
  39. if (currentTimes <= playTimes) {
  40. setState(() {
  41. if (currentIndex >= endIndex) {
  42. if (playTimes != 0) currentTimes++;
  43. if (currentTimes < playTimes || playTimes == 0)
  44. currentIndex = startIndex;
  45. else
  46. currentIndex = endIndex;
  47. } else
  48. currentIndex++;
  49. });
  50. }
  51. });
  52. super.initState();
  53. }
  54.  
  55. @override
  56. void dispose() {
  57. super.dispose();
  58. timer?.cancel();
  59. }
  60.  
  61. @override
  62. Widget build(BuildContext context) {
  63. // 使用container+Positioned来限制图片显示区域
  64. return Container(
  65. width: spriteSize.width,
  66. height: spriteSize.height,
  67. child: Stack(
  68. children: [
  69. Positioned(
  70. left: -spriteSize.width * currentIndex,
  71. top: -spriteSize.height * currentIndex,
  72. child: image)
  73. ],
  74. ),
  75. );
  76. }
  77. }

Flame加载精灵图

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

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

  1. bonfire: ^2.0.0
  2. flame: ^1.0.0

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

  1. abstract class BaseRole {
  2. // 速度
  3. double velocity;
  4. late Sprite sprite;
  5.  
  6. BaseRole({
  7. this.velocity = 10,
  8. });
  9.  
  10. dynamic load();
  11.  
  12. void run();
  13. }
  14. class UserRole extends BaseRole {
  15. Vector2 offset = Vector2(0.0, 0.0);
  16. Vector2 size = Vector2(48.0, 48.0);
  17.  
  18. @override
  19. void run() {
  20. double x = (48 + offset.x) % 192;
  21. double y = 0;
  22. offset = Vector2(x, y);
  23. sprite.srcPosition = offset;
  24. sprite.srcSize = size;
  25. }
  26.  
  27. @override
  28. Future load() async {
  29. sprite = await Sprite.load(
  30. 'user_role.png',
  31. srcPosition: offset,
  32. srcSize: size,
  33. );
  34. return sprite;
  35. }
  36. }

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

  1. class UserRoleComponent extends SpriteComponent {
  2. late UserRole userRole;
  3.  
  4. UserRoleComponent()
  5. : super(
  6. size: Vector2.all(100),
  7. );
  8.  
  9. double minDt = 1 / 8; // 30 fps
  10. double dtOverflow = 0;
  11.  
  12. @override
  13. Future<void>? onLoad() async {
  14. userRole = UserRole();
  15. sprite = await userRole.load();
  16. super.onLoad();
  17. }
  18.  
  19. @override
  20. void update(double dt) {
  21. dtOverflow += dt;
  22. if (dtOverflow < minDt) {
  23. return;
  24. }
  25. userRole.run();
  26. dtOverflow = 0;
  27. }
  28. }

到此这篇关于Android Flutter实现精灵图的使用详解的文章就介绍到这了,更多相关Android Flutter精灵图内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号