Flutter Spine动画渲染插件spine_flutter_patch的使用

Flutter Spine动画渲染插件spine_flutter_patch的使用

spine-flutter 提供了使用 Flutter 加载、操作和渲染 Spine 骨骼动画数据的功能。spine-flutter 基于 spine-cpp,支持桌面和移动 Flutter 部署目标。spine-flutter 不支持 Flutter 的 Web 部署目标。

关于详细的文档

请参阅 spine-flutter 文档 获取更详细的信息。

许可证

欢迎您免费评估 Spine 运行时和本仓库提供的示例。您可以免费将 Spine 运行时集成到您的软件中,但您的软件用户必须拥有自己的 Spine 许可证。请确保您的用户了解这一要求!此选项通常由开发工具(如 SDK、游戏工具包或软件库)的开发者选择。

为了向没有 Spine 许可证的其他人分发包含 Spine 运行时的软件,您需要在集成时获得 Spine 许可证。然后您可以以任何方式分发您的软件,只要其他人不对其进行修改或用于创建新软件。如果其他人想要这样做,他们需要自己的 Spine 许可证。

有关 Spine 运行时的官方法律条款,请阅读 Spine 运行时许可协议Spine 编辑器许可协议 的第 2 节。

Spine 版本

spine-flutter 可以与从 Spine 4.2.xx 导出的数据一起工作。spine-flutter 支持所有 Spine 功能,除了双色涂装和屏幕混合模式。

支持的平台

spine-flutter 运行时可以在桌面、移动和 Web 上工作。Web 部署需要 Canvaskit,这将在您的 Web 部署中增加约 2MB 的依赖项。您可以通过以下命令编译带有 Canvaskit 的应用:

flutter build web --web-renderer canvaskit

设置

要将 spine_flutter 添加到您的 Flutter 项目中,在 pubspec.yaml 文件中添加以下依赖项:

dependencies:
  ...
  spine_flutter: ^4.2.11

在您的 main() 函数中,添加以下两行以初始化 Spine Flutter 运行时:

void main() {
    WidgetsFlutterBinding.ensureInitialized();
    await initSpineFlutter(enableMemoryDebugging: false);
    ...
}

示例

如果您直接从 pub.dev 拉取了 spine_flutter 包,您可以运行 example/ 文件夹中的示例:

cd path/to/downloaded/spine_flutter
cd example
flutter run

否则,您可以按以下步骤运行示例:

  1. 安装 Flutter SDK,然后运行 flutter doctor,它会指导您安装其他所需的依赖项。
  2. 克隆此仓库 git clone https://github.com/esotericsoftware/spine-runtimes
  3. spine-flutter/ 文件夹中运行 setup.sh。在 Windows 上,您可以使用 Git for Windows 中包含的 Git Bash 来运行 setup.sh Bash 脚本。

然后您可以使用支持 Flutter 的 IDE 或编辑器(如 IntelliJ IDEA/Android StudioVisual Studio Code)打开 spine-flutter 并检查和运行示例。

或者,您也可以通过 命令行 运行示例。

开发

如果您仅修改了插件的 Dart 源代码,则开发设置与上面“示例”部分中描述的设置相同。

如果您需要对 dart:ffi 绑定进行 spine-cpp 的工作,您还需要安装 Emscripten

要基于 src/spine_flutter.h 头文件生成绑定,请运行 dart run ffigen --config ffigen.yaml。在生成绑定后,您必须将 src/spine_flutter_bindings_generated.dart 文件中的 import 'dart:ffi' as ffi; 替换为 import 'ffi_proxy.dart' as ffi;。否则,绑定将无法为 Web 编译。

如果您对 spine-cppsrc/ 文件夹中的源文件进行了更改,您必须运行 compile-wasm.sh。这将编译 spine-cpp 和绑定以供 Web 使用,并将更新版本的 libspine_flutter.jslibspine_flutter.wasm 放置在 lib/assets/ 文件夹中。对于 Web 构建,lib/init_web.dart 中的 initSpineFlutterFFI() 函数将从包的资产包中加载这些文件。

示例代码

import 'package:spine_flutter/spine_flutter.dart';
import 'package:flutter/material.dart';
import 'package:spine_flutter_example/debug_rendering.dart';

import 'animation_state_events.dart';
import 'dress_up.dart';
import 'flame_example.dart';
import 'ik_following.dart';
import 'pause_play_animation.dart';
import 'simple_animation.dart';

class ExampleSelector extends StatelessWidget {
  const ExampleSelector({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    const spacer = SizedBox(height: 10);
    return Scaffold(
        appBar: AppBar(title: const Text('Spine Examples')),
        body: Center(
            child: Column(mainAxisSize: MainAxisSize.min, children: [
          ElevatedButton(
            child: const Text('Simple Animation'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute<void>(
                  builder: (context) => const SimpleAnimation(),
                ),
              );
            },
          ),
          spacer,
          ElevatedButton(
            child: const Text('Pause/Play animation'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute<void>(
                  builder: (context) => const PlayPauseAnimation(),
                ),
              );
            },
          ),
          spacer,
          ElevatedButton(
            child: const Text('Animation State Listener'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute<void>(
                  builder: (context) => const AnimationStateEvents(),
                ),
              );
            },
          ),
          spacer,
          ElevatedButton(
            child: const Text('Debug Rendering'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute<void>(
                  builder: (context) => const DebugRendering(),
                ),
              );
            },
          ),
          spacer,
          ElevatedButton(
            child: const Text('Dress Up'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute<void>(
                  builder: (context) => const DressUp(),
                ),
              );
            },
          ),
          spacer,
          ElevatedButton(
            child: const Text('IK Following'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute<void>(
                  builder: (context) => const IkFollowing(),
                ),
              );
            },
          ),
          spacer,
          ElevatedButton(
            child: const Text('Flame: Simple Example'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute<void>(
                  builder: (context) => SpineFlameGameWidget(SimpleFlameExample()),
                ),
              );
            },
          ),
          spacer,
          ElevatedButton(
            child: const Text('Flame: Pre-load and share Spine data'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute<void>(
                  builder: (context) => SpineFlameGameWidget(PreloadAndShareSpineDataExample()),
                ),
              );
            },
          ),
          spacer
        ])));
  }
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initSpineFlutter(enableMemoryDebugging: false);
  runApp(const MaterialApp(title: "Spine Examples", home: ExampleSelector()));
}

更多关于Flutter Spine动画渲染插件spine_flutter_patch的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Spine动画渲染插件spine_flutter_patch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


spine_flutter_patch 是一个用于在 Flutter 应用中渲染 Spine 动画的插件。Spine 是一个用于创建 2D 骨骼动画的工具,它通常用于游戏开发。spine_flutter_patch 插件允许你在 Flutter 应用中加载和播放 Spine 动画。

以下是如何在 Flutter 项目中使用 spine_flutter_patch 插件的步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 spine_flutter_patch 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  spine_flutter_patch: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 导入插件

在你的 Dart 文件中导入 spine_flutter_patch 插件:

import 'package:spine_flutter_patch/spine_flutter_patch.dart';

3. 加载和播放 Spine 动画

以下是一个简单的示例,展示如何在 Flutter 应用中加载和播放 Spine 动画:

import 'package:flutter/material.dart';
import 'package:spine_flutter_patch/spine_flutter_patch.dart';

class SpineAnimationWidget extends StatefulWidget {
  @override
  _SpineAnimationWidgetState createState() => _SpineAnimationWidgetState();
}

class _SpineAnimationWidgetState extends State<SpineAnimationWidget> {
  SpineWidgetController? _controller;

  @override
  void initState() {
    super.initState();
    _loadAnimation();
  }

  Future<void> _loadAnimation() async {
    final skeletonData = await SkeletonData.fromAsset('assets/spineboy.json');
    final atlasData = await AtlasData.fromAsset('assets/spineboy.atlas');

    setState(() {
      _controller = SpineWidgetController(
        skeletonData: skeletonData,
        atlasData: atlasData,
      );
    });

    _controller?.animationState.setAnimationByName(0, 'walk', true);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Spine Animation'),
      ),
      body: Center(
        child: _controller != null
            ? SpineWidget(controller: _controller!)
            : CircularProgressIndicator(),
      ),
    );
  }

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

void main() {
  runApp(MaterialApp(
    home: SpineAnimationWidget(),
  ));
}

4. 资源文件

确保你的 Spine 动画文件(skeleton.json.atlas 文件)已经放在 assets 文件夹中,并且在 pubspec.yaml 中正确配置了资源路径:

flutter:
  assets:
    - assets/spineboy.json
    - assets/spineboy.atlas

5. 运行应用

现在你可以运行应用,查看 Spine 动画在 Flutter 应用中的渲染效果。

6. 控制动画

你可以通过 SpineWidgetController 来控制动画的播放、暂停、切换动画等操作。例如:

_controller?.animationState.setAnimationByName(0, 'jump', false);
_controller?.animationState.addAnimationByName(0, 'walk', true, 0);

7. 处理用户输入

你还可以通过监听用户输入来触发不同的动画。例如,点击屏幕时播放跳跃动画:

GestureDetector(
  onTap: () {
    _controller?.animationState.setAnimationByName(0, 'jump', false);
    _controller?.animationState.addAnimationByName(0, 'walk', true, 0);
  },
  child: SpineWidget(controller: _controller!),
)
回到顶部