前言
如何使用精灵图
自定义实现加载
- 每帧图片尺寸固定后就能确认每一帧图片在整张图片的定位位置,因此能够根据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
库,此外bonfire
是Flame
库的拓展封装了更多游戏开发相关功能接口。
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; } }
您可能感兴趣的文章: