Browse Source

[flutter] Add physics example.

Mario Zechner 1 year ago
parent
commit
b7ee102dda

+ 4 - 0
examples/export/runtimes.sh

@@ -124,6 +124,10 @@ cp -f ../dragon/export/dragon.atlas "$ROOT/spine-flutter/example/assets/"
 cp -f ../dragon/export/dragon.png "$ROOT/spine-flutter/example/assets/"
 cp -f ../dragon/export/dragon_*.png "$ROOT/spine-flutter/example/assets/"
 
+cp -f ../celestial-circus/export/celestial-circus-pro.skel "$ROOT/spine-flutter/example/assets/"
+cp -f ../celestial-circus/export/celestial-circus.atlas "$ROOT/spine-flutter/example/assets/"
+cp -f ../celestial-circus/export/celestial-circus.png "$ROOT/spine-flutter/example/assets/"
+
 echo "spine-godot"
 rm -f "$ROOT"/spine-godot/example/assets/spineboy/*.atlas
 rm -f "$ROOT"/spine-godot/example/assets/spineboy/*.png

BIN
spine-flutter/example/assets/celestial-circus-pro.skel


+ 173 - 0
spine-flutter/example/assets/celestial-circus.atlas

@@ -0,0 +1,173 @@
+celestial-circus.png
+	size: 1024, 1024
+	filter: Linear, Linear
+	scale: 0.4
+arm-back-down
+	bounds: 324, 401, 38, 82
+	rotate: 90
+arm-back-up
+	bounds: 290, 44, 83, 116
+	rotate: 90
+arm-front-down
+	bounds: 706, 2, 36, 78
+	rotate: 90
+arm-front-up
+	bounds: 860, 138, 77, 116
+bench
+	bounds: 725, 256, 189, 48
+body-bottom
+	bounds: 879, 868, 154, 124
+	rotate: 90
+body-top
+	bounds: 725, 128, 126, 133
+	rotate: 90
+chest
+	bounds: 408, 26, 104, 93
+cloud-back
+	bounds: 752, 378, 202, 165
+cloud-front
+	bounds: 2, 2, 325, 196
+	rotate: 90
+collar
+	bounds: 786, 13, 47, 26
+ear
+	bounds: 1002, 643, 20, 28
+eye-back-shadow
+	bounds: 428, 395, 14, 10
+eye-front-shadow
+	bounds: 704, 529, 24, 14
+eye-reflex-back
+	bounds: 860, 128, 8, 7
+	rotate: 90
+eye-reflex-front
+	bounds: 726, 386, 10, 7
+eye-white-back
+	bounds: 835, 23, 13, 16
+eye-white-front
+	bounds: 1005, 1000, 22, 17
+	rotate: 90
+eyelashes-down-back
+	bounds: 232, 329, 11, 6
+	rotate: 90
+eyelashes-down-front
+	bounds: 913, 851, 15, 6
+	rotate: 90
+eyelashes-top-back
+	bounds: 408, 395, 18, 10
+eyelashes-top-front
+	bounds: 702, 179, 30, 16
+	rotate: 90
+face
+	bounds: 514, 26, 93, 102
+	rotate: 90
+feathers-back
+	bounds: 954, 625, 46, 46
+feathers-front
+	bounds: 706, 40, 72, 86
+fringe-middle-back
+	bounds: 200, 6, 33, 52
+	rotate: 90
+fringe-middle-front
+	bounds: 878, 76, 60, 50
+	rotate: 90
+fringe-side-back
+	bounds: 780, 41, 27, 94
+	rotate: 90
+fringe-side-front
+	bounds: 939, 161, 26, 93
+glove-bottom-back
+	bounds: 954, 572, 51, 41
+	rotate: 90
+glove-bottom-front
+	bounds: 916, 256, 47, 48
+hair-back-1
+	bounds: 444, 395, 132, 306
+	rotate: 90
+hair-back-2
+	bounds: 438, 211, 80, 285
+	rotate: 90
+hair-back-3
+	bounds: 719, 306, 70, 268
+	rotate: 90
+hair-back-4
+	bounds: 438, 121, 88, 262
+	rotate: 90
+hair-back-5
+	bounds: 438, 293, 88, 279
+	rotate: 90
+hair-back-6
+	bounds: 200, 41, 88, 286
+hair-hat-shadow
+	bounds: 232, 398, 90, 41
+hand-back
+	bounds: 954, 673, 60, 47
+	rotate: 90
+hand-front
+	bounds: 967, 172, 53, 60
+hat-back
+	bounds: 954, 802, 64, 45
+	rotate: 90
+hat-front
+	bounds: 780, 70, 96, 56
+head-back
+	bounds: 618, 17, 102, 86
+	rotate: 90
+jabot
+	bounds: 967, 234, 70, 55
+	rotate: 90
+leg-back
+	bounds: 232, 441, 210, 333
+leg-front
+	bounds: 444, 529, 258, 320
+logo-brooch
+	bounds: 954, 545, 16, 25
+mouth
+	bounds: 408, 121, 22, 6
+neck
+	bounds: 232, 342, 39, 56
+	rotate: 90
+nose
+	bounds: 742, 529, 6, 7
+	rotate: 90
+nose-highlight
+	bounds: 719, 300, 4, 4
+nose-shadow
+	bounds: 869, 128, 7, 8
+pupil-back
+	bounds: 730, 529, 10, 14
+pupil-front
+	bounds: 254, 21, 12, 18
+rope-back
+	bounds: 232, 383, 10, 492
+	rotate: 90
+rope-front
+	bounds: 232, 383, 10, 492
+	rotate: 90
+rope-front-bottom
+	bounds: 954, 735, 42, 65
+skirt
+	bounds: 2, 776, 440, 246
+sock-bow
+	bounds: 408, 407, 33, 32
+spine-logo-body
+	bounds: 879, 853, 13, 32
+	rotate: 90
+star-big
+	bounds: 939, 141, 18, 24
+	rotate: 90
+star-medium
+	bounds: 742, 537, 6, 8
+	rotate: 90
+star-small
+	bounds: 719, 378, 3, 4
+	rotate: 90
+underskirt
+	bounds: 2, 329, 445, 228
+	rotate: 90
+underskirt-back
+	bounds: 444, 851, 433, 171
+wing-back
+	bounds: 290, 129, 146, 252
+wing-front
+	bounds: 704, 545, 304, 248
+	rotate: 90

BIN
spine-flutter/example/assets/celestial-circus.png


+ 13 - 0
spine-flutter/example/lib/main.dart

@@ -36,6 +36,7 @@ import 'dress_up.dart';
 import 'flame_example.dart';
 import 'ik_following.dart';
 import 'pause_play_animation.dart';
+import 'physics.dart';
 import 'simple_animation.dart';
 
 class ExampleSelector extends StatelessWidget {
@@ -119,6 +120,18 @@ class ExampleSelector extends StatelessWidget {
               );
             },
           ),
+              spacer,
+              ElevatedButton(
+                child: const Text('Physics'),
+                onPressed: () {
+                  Navigator.push(
+                    context,
+                    MaterialPageRoute<void>(
+                      builder: (context) => const PhysicsTest(),
+                    ),
+                  );
+                },
+              ),
           spacer,
           ElevatedButton(
             child: const Text('Flame: Simple Example'),

+ 88 - 0
spine-flutter/example/lib/physics.dart

@@ -0,0 +1,88 @@
+///
+/// Spine Runtimes License Agreement
+/// Last updated July 28, 2023. Replaces all prior versions.
+///
+/// Copyright (c) 2013-2023, Esoteric Software LLC
+///
+/// Integration of the Spine Runtimes into software or otherwise creating
+/// derivative works of the Spine Runtimes is permitted under the terms and
+/// conditions of Section 2 of the Spine Editor License Agreement:
+/// http://esotericsoftware.com/spine-editor-license
+///
+/// Otherwise, it is permitted to integrate the Spine Runtimes into software or
+/// otherwise create derivative works of the Spine Runtimes (collectively,
+/// "Products"), provided that each user of the Products must obtain their own
+/// Spine Editor license and redistribution of the Products in any form must
+/// include this license and copyright notice.
+///
+/// THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+/// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+/// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+/// DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+/// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+/// BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+/// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
+/// SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+///
+
+import 'package:spine_flutter/spine_flutter.dart';
+import 'package:flutter/material.dart';
+
+class PhysicsTest extends StatefulWidget {
+  const PhysicsTest({Key? key}) : super(key: key);
+
+  @override
+  PhysicsState createState() => PhysicsState();
+}
+
+class PhysicsState extends State<PhysicsTest> {
+  late SpineWidgetController controller;
+  Offset? mousePosition;
+  Offset? lastMousePosition;
+  Offset? delta;
+
+  @override
+  void initState() {
+    super.initState();
+
+    controller = SpineWidgetController(onInitialized: (controller) {
+      controller.animationState.setAnimationByName(0, "eyeblink-long", true);
+      controller.animationState.setAnimationByName(1, "wings-and-feet", true);
+    }, onAfterUpdateWorldTransforms: (controller) {
+      if (lastMousePosition == null) {
+        lastMousePosition = mousePosition;
+        return;
+      }
+      if (mousePosition == null) {
+        return;
+      }
+
+      final dx = mousePosition!.dx - lastMousePosition!.dx;
+      final dy = mousePosition!.dy - lastMousePosition!.dy;
+      final position = controller.skeleton.getPosition();
+      position.x += dx;
+      position.y += dy;
+      controller.skeleton.setPosition(position.x, position.y);
+      lastMousePosition = mousePosition;
+    });
+  }
+
+  void _updateBonePosition(Offset position) {
+    mousePosition = controller.toSkeletonCoordinates(position);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    reportLeaks();
+
+    return Scaffold(
+        appBar: AppBar(title: const Text('Physics (drag anywhere)')),
+        body: GestureDetector(
+          onPanDown: (drag) => _updateBonePosition(drag.localPosition),
+          onPanUpdate: (drag) => _updateBonePosition(drag.localPosition),
+          child: SpineWidget.fromAsset("assets/celestial-circus.atlas", "assets/celestial-circus-pro.skel", controller),
+        ));
+  }
+}

+ 6 - 0
spine-flutter/lib/spine_flutter.dart

@@ -3008,6 +3008,12 @@ class Skeleton {
     _bindings.spine_skeleton_set_position(_skeleton, x, y);
   }
 
+  Vec2 getPosition() {
+    final x = _bindings.spine_skeleton_get_x(_skeleton);
+    final y = _bindings.spine_skeleton_get_y(_skeleton);
+    return Vec2(x, y);
+  }
+
   /// Sets the skeleton X position, which is added to the root bone worldX position.
   ///
   /// Bones that do not inherit translation are still affected by this property.