Android Flutter实现精灵图的使用详解

 更新时间:2022年08月31日 11:20:25   作者:JulyYu  
在游戏开发中,精灵图会将一个人物所有动作放置在一张图片中,通过坐标定位选取其中一张图展示。本文就来教你如何使用精灵图,感兴趣的可以了解一下

前言

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

如何使用精灵图

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

自定义实现加载

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

  • 每帧图片尺寸固定后就能确认每一帧图片在整张图片的定位位置,因此能够根据X-Y坐标来找到相应图片。
  • 创建定时器调整间隔时间计算出坐标位置切换需要展示图片。
  • 再结合Container+Positioned形式来实现采用偏移量方式显示哪张图片。
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)
        ],
      ),
    );
  }
}

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实现精灵图的使用详解的文章就介绍到这了,更多相关Android Flutter精灵图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Android开发之StackView用法和遇到的坑分析

    Android开发之StackView用法和遇到的坑分析

    这篇文章主要介绍了Android开发之StackView用法和遇到的坑,结合实例形式分析了Android StackView图片操作用法及常见问题解决方法,需要的朋友可以参考下
    2019-03-03
  • Android实现手势滑动多点触摸缩放平移图片效果

    Android实现手势滑动多点触摸缩放平移图片效果

    这篇文章主要介绍了Android实现手势滑动多点触摸缩放平移图片效果,实现图片支持多点触控,自由的进行缩放、平移的注意事项,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • Android仿最新微信相机功能

    Android仿最新微信相机功能

    这篇文章主要为大家详细介绍了Android仿最新微信相机功能,长按拍摄,轻点拍照功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • android studio安装时 AVD出现问题如何快速解决

    android studio安装时 AVD出现问题如何快速解决

    这篇文章主要介绍了安装android studio时 AVD出现问题如何快速处理,其实解决方法也很简单,文中通过截图的形式给大家及时的非常详细,对大家的工作或学习具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • 详解Android性能优化之内存泄漏

    详解Android性能优化之内存泄漏

    内存泄漏(memory leak)是指由于疏忽或错误造成程序未能释放已经不再使用的内存。本篇文章主要介绍了Android性能优化之内存泄漏,有兴趣的可以了解一下。
    2016-12-12
  • Android UI仿QQ好友列表分组悬浮效果

    Android UI仿QQ好友列表分组悬浮效果

    这篇文章主要为大家详细介绍了Android UI仿QQ好友列表分组悬浮效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • Android快速实现无预览拍照功能

    Android快速实现无预览拍照功能

    这篇文章主要为大家详细介绍了Android快速实现无预览拍照功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • Flutter仿微信通讯录实现自定义导航条的示例代码

    Flutter仿微信通讯录实现自定义导航条的示例代码

    某些页面比如我们在选择联系人或者某个城市的时候需要快速定位到我们需要的选项,一般都会需要像微信通讯录右边有一个导航条一样的功能,本文将利用Flutter实现这一效果,需要的可以参考一下
    2022-04-04
  • Android实现系统打印功能

    Android实现系统打印功能

    这篇文章主要为大家详细介绍了Android实现系统打印功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • React Native之在Android上添加阴影的实现

    React Native之在Android上添加阴影的实现

    这篇文章主要介绍了React Native之在Android上添加阴影的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03

最新评论