Physics.swift 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import SwiftUI
  2. import Spine
  3. struct Physics: View {
  4. @StateObject
  5. var model = PhysicsModel()
  6. var body: some View {
  7. ZStack {
  8. Color(red: 51 / 255, green: 51 / 255, blue: 51 / 255).ignoresSafeArea()
  9. SpineView(
  10. from: .bundle(atlasFileName: "celestial-circus-pma.atlas", skeletonFileName: "celestial-circus-pro.skel"),
  11. controller: model.controller
  12. )
  13. .gesture(
  14. DragGesture(minimumDistance: 0)
  15. .onChanged { gesture in
  16. model.updateBonePosition(position: gesture.location)
  17. }
  18. )
  19. }
  20. .navigationTitle("Physics (drag anywhere)")
  21. .navigationBarTitleDisplayMode(.inline)
  22. }
  23. }
  24. #Preview {
  25. Physics()
  26. }
  27. final class PhysicsModel: ObservableObject {
  28. @Published
  29. var controller: SpineController!
  30. @Published
  31. var mousePosition: CGPoint?
  32. @Published
  33. var lastMousePosition: CGPoint?
  34. init() {
  35. controller = SpineController(
  36. onInitialized: { controller in
  37. controller.animationState.setAnimationByName(
  38. trackIndex: 0,
  39. animationName: "eyeblink",
  40. loop: true
  41. )
  42. controller.animationState.setAnimationByName(
  43. trackIndex: 1,
  44. animationName: "wings-and-feet",
  45. loop: true
  46. )
  47. },
  48. onAfterUpdateWorldTransforms: {
  49. [weak self] controller in guard let self else { return }
  50. guard let lastMousePosition else {
  51. self.lastMousePosition = mousePosition
  52. return
  53. }
  54. guard let mousePosition else {
  55. return
  56. }
  57. let dx = mousePosition.x - lastMousePosition.x
  58. let dy = mousePosition.y - lastMousePosition.y
  59. let positionX = controller.skeleton.x + Float(dx)
  60. let positionY = controller.skeleton.y + Float(dy)
  61. controller.skeleton.setPosition(x: positionX, y: positionY)
  62. self.lastMousePosition = mousePosition
  63. }
  64. )
  65. }
  66. func updateBonePosition(position: CGPoint) {
  67. mousePosition = controller.toSkeletonCoordinates(position: position)
  68. }
  69. }