mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Update SpineController and SpineController.Builder API
This commit is contained in:
parent
fc4716f749
commit
77778a0e3a
@ -29,86 +29,84 @@ fun AnimationState(nav: NavHostController) {
|
|||||||
val TAG = "AnimationState"
|
val TAG = "AnimationState"
|
||||||
|
|
||||||
val controller = remember {
|
val controller = remember {
|
||||||
SpineController.Builder()
|
SpineController { controller ->
|
||||||
.setOnInitialized { controller ->
|
controller.skeleton.setScaleX(0.5f)
|
||||||
controller.skeleton.setScaleX(0.5f)
|
controller.skeleton.setScaleY(0.5f)
|
||||||
controller.skeleton.setScaleY(0.5f)
|
|
||||||
|
|
||||||
controller.skeleton.findSlot("gun")?.color = Color(1f, 0f, 0f, 1f)
|
controller.skeleton.findSlot("gun")?.color = Color(1f, 0f, 0f, 1f)
|
||||||
|
|
||||||
controller.animationStateData.setDefaultMix(0.2f)
|
controller.animationStateData.setDefaultMix(0.2f)
|
||||||
controller.animationState.setAnimation(0, "walk", true).setListener(object : AnimationState.AnimationStateListener {
|
controller.animationState.setAnimation(0, "walk", true).setListener(object : AnimationState.AnimationStateListener {
|
||||||
override fun start(entry: AnimationState.TrackEntry?) {
|
override fun start(entry: AnimationState.TrackEntry?) {
|
||||||
Log.d(TAG, "Walk animation event start")
|
Log.d(TAG, "Walk animation event start")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun interrupt(entry: AnimationState.TrackEntry?) {
|
||||||
|
Log.d(TAG, "Walk animation event interrupt")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun end(entry: AnimationState.TrackEntry?) {
|
||||||
|
Log.d(TAG, "Walk animation event end")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose(entry: AnimationState.TrackEntry?) {
|
||||||
|
Log.d(TAG, "Walk animation event dispose")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun complete(entry: AnimationState.TrackEntry?) {
|
||||||
|
Log.d(TAG, "Walk animation event complete")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun event(entry: AnimationState.TrackEntry?, event: Event?) {
|
||||||
|
Log.d(TAG, "Walk animation event event")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
controller.animationState.addAnimation(0, "jump", false, 2f)
|
||||||
|
controller.animationState.addAnimation(0, "run", true, 0f).setListener(object : AnimationState.AnimationStateListener {
|
||||||
|
override fun start(entry: AnimationState.TrackEntry?) {
|
||||||
|
Log.d(TAG, "Run animation event start")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun interrupt(entry: AnimationState.TrackEntry?) {
|
||||||
|
Log.d(TAG, "Run animation event interrupt")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun end(entry: AnimationState.TrackEntry?) {
|
||||||
|
Log.d(TAG, "Run animation event end")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose(entry: AnimationState.TrackEntry?) {
|
||||||
|
Log.d(TAG, "Run animation event dispose")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun complete(entry: AnimationState.TrackEntry?) {
|
||||||
|
Log.d(TAG, "Run animation event complete")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun event(entry: AnimationState.TrackEntry?, event: Event?) {
|
||||||
|
Log.d(TAG, "Run animation event event")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
controller.animationState.addListener(object : AnimationState.AnimationStateListener {
|
||||||
|
override fun start(entry: AnimationState.TrackEntry?) {}
|
||||||
|
|
||||||
|
override fun interrupt(entry: AnimationState.TrackEntry?) {}
|
||||||
|
|
||||||
|
override fun end(entry: AnimationState.TrackEntry?) {}
|
||||||
|
|
||||||
|
override fun dispose(entry: AnimationState.TrackEntry?) {}
|
||||||
|
|
||||||
|
override fun complete(entry: AnimationState.TrackEntry?) {}
|
||||||
|
|
||||||
|
override fun event(entry: AnimationState.TrackEntry?, event: Event?) {
|
||||||
|
if (event != null) {
|
||||||
|
Log.d(TAG, "User event: { name: ${event.data.name}, intValue: ${event.int}, floatValue: ${event.float}, stringValue: ${event.string} }")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
override fun interrupt(entry: AnimationState.TrackEntry?) {
|
})
|
||||||
Log.d(TAG, "Walk animation event interrupt")
|
Log.d(TAG, "Current: ${controller.animationState.getCurrent(0)?.getAnimation()?.getName()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun end(entry: AnimationState.TrackEntry?) {
|
|
||||||
Log.d(TAG, "Walk animation event end")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispose(entry: AnimationState.TrackEntry?) {
|
|
||||||
Log.d(TAG, "Walk animation event dispose")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun complete(entry: AnimationState.TrackEntry?) {
|
|
||||||
Log.d(TAG, "Walk animation event complete")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun event(entry: AnimationState.TrackEntry?, event: Event?) {
|
|
||||||
Log.d(TAG, "Walk animation event event")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
controller.animationState.addAnimation(0, "jump", false, 2f)
|
|
||||||
controller.animationState.addAnimation(0, "run", true, 0f).setListener(object : AnimationState.AnimationStateListener {
|
|
||||||
override fun start(entry: AnimationState.TrackEntry?) {
|
|
||||||
Log.d(TAG, "Run animation event start")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun interrupt(entry: AnimationState.TrackEntry?) {
|
|
||||||
Log.d(TAG, "Run animation event interrupt")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun end(entry: AnimationState.TrackEntry?) {
|
|
||||||
Log.d(TAG, "Run animation event end")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispose(entry: AnimationState.TrackEntry?) {
|
|
||||||
Log.d(TAG, "Run animation event dispose")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun complete(entry: AnimationState.TrackEntry?) {
|
|
||||||
Log.d(TAG, "Run animation event complete")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun event(entry: AnimationState.TrackEntry?, event: Event?) {
|
|
||||||
Log.d(TAG, "Run animation event event")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
controller.animationState.addListener(object : AnimationState.AnimationStateListener {
|
|
||||||
override fun start(entry: AnimationState.TrackEntry?) {}
|
|
||||||
|
|
||||||
override fun interrupt(entry: AnimationState.TrackEntry?) {}
|
|
||||||
|
|
||||||
override fun end(entry: AnimationState.TrackEntry?) {}
|
|
||||||
|
|
||||||
override fun dispose(entry: AnimationState.TrackEntry?) {}
|
|
||||||
|
|
||||||
override fun complete(entry: AnimationState.TrackEntry?) {}
|
|
||||||
|
|
||||||
override fun event(entry: AnimationState.TrackEntry?, event: Event?) {
|
|
||||||
if (event != null) {
|
|
||||||
Log.d(TAG, "User event: { name: ${event.data.name}, intValue: ${event.int}, floatValue: ${event.float}, stringValue: ${event.string} }")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
Log.d(TAG, "Current: ${controller.animationState.getCurrent(0)?.getAnimation()?.getName()}");
|
|
||||||
}
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
|
|||||||
@ -47,14 +47,13 @@ fun DebugRendering(nav: NavHostController) {
|
|||||||
"spineboy.atlas",
|
"spineboy.atlas",
|
||||||
"spineboy-pro.json",
|
"spineboy-pro.json",
|
||||||
context,
|
context,
|
||||||
SpineController.Builder()
|
SpineController.Builder { controller ->
|
||||||
.setOnInitialized {
|
controller.animationState.setAnimation(0, "walk", true)
|
||||||
it.animationState.setAnimation(0, "walk", true)
|
}
|
||||||
}
|
.setOnAfterPaint { controller, canvas, commands ->
|
||||||
.setOnAfterPaint { controller, canvas, commands ->
|
debugRenderer.render(controller.drawable, canvas, commands)
|
||||||
debugRenderer.render(controller.drawable, canvas, commands)
|
}
|
||||||
}
|
.build()
|
||||||
.build()
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.padding(paddingValues)
|
modifier = Modifier.padding(paddingValues)
|
||||||
|
|||||||
@ -75,11 +75,9 @@ fun DressUp(nav: NavHostController) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val controller = remember {
|
val controller = remember {
|
||||||
SpineController.Builder()
|
SpineController { controller ->
|
||||||
.setOnInitialized {
|
controller.animationState.setAnimation(0, "dance", true)
|
||||||
it.animationState.setAnimation(0, "dance", true)
|
}
|
||||||
}
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleSkin(skinName: String) {
|
fun toggleSkin(skinName: String) {
|
||||||
|
|||||||
@ -35,21 +35,20 @@ fun IKFollowing(nav: NavHostController) {
|
|||||||
val crossHairPosition = remember { mutableStateOf<Point?>(null) }
|
val crossHairPosition = remember { mutableStateOf<Point?>(null) }
|
||||||
|
|
||||||
val controller = remember {
|
val controller = remember {
|
||||||
SpineController.Builder()
|
SpineController.Builder { controller ->
|
||||||
.setOnInitialized {
|
controller.animationState.setAnimation(0, "walk", true)
|
||||||
it.animationState.setAnimation(0, "walk", true)
|
controller.animationState.setAnimation(1, "aim", true)
|
||||||
it.animationState.setAnimation(1, "aim", true)
|
}
|
||||||
}
|
.setOnAfterUpdateWorldTransforms {
|
||||||
.setOnAfterUpdateWorldTransforms {
|
val worldPosition = crossHairPosition.value ?: return@setOnAfterUpdateWorldTransforms
|
||||||
val worldPosition = crossHairPosition.value ?: return@setOnAfterUpdateWorldTransforms
|
val skeleton = it.skeleton
|
||||||
val skeleton = it.skeleton
|
val bone = skeleton.findBone("crosshair") ?: return@setOnAfterUpdateWorldTransforms
|
||||||
val bone = skeleton.findBone("crosshair") ?: return@setOnAfterUpdateWorldTransforms
|
val parent = bone.parent ?: return@setOnAfterUpdateWorldTransforms
|
||||||
val parent = bone.parent ?: return@setOnAfterUpdateWorldTransforms
|
val position = parent.worldToLocal(Vector2(worldPosition.x.toFloat(), worldPosition.y.toFloat()))
|
||||||
val position = parent.worldToLocal(Vector2(worldPosition.x.toFloat(), worldPosition.y.toFloat()))
|
bone.x = position.x
|
||||||
bone.x = position.x
|
bone.y = position.y
|
||||||
bone.y = position.y
|
}
|
||||||
}
|
.build()
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
|
|||||||
@ -36,31 +36,30 @@ fun Physics(nav: NavHostController) {
|
|||||||
val lastMousePosition = remember { mutableStateOf<Point?>(null) }
|
val lastMousePosition = remember { mutableStateOf<Point?>(null) }
|
||||||
|
|
||||||
val controller = remember {
|
val controller = remember {
|
||||||
SpineController.Builder()
|
SpineController.Builder { controller ->
|
||||||
.setOnInitialized { controller ->
|
controller.animationState.setAnimation(0, "eyeblink-long", true)
|
||||||
controller.animationState.setAnimation(0, "eyeblink-long", true)
|
controller.animationState.setAnimation(1, "wings-and-feet", true)
|
||||||
controller.animationState.setAnimation(1, "wings-and-feet", true)
|
}
|
||||||
|
.setOnAfterUpdateWorldTransforms { controller ->
|
||||||
|
val lastMousePositionValue = lastMousePosition.value
|
||||||
|
if (lastMousePositionValue == null) {
|
||||||
|
lastMousePosition.value = mousePosition.value
|
||||||
|
return@setOnAfterUpdateWorldTransforms
|
||||||
}
|
}
|
||||||
.setOnAfterUpdateWorldTransforms { controller ->
|
val mousePositionValue = mousePosition.value ?: return@setOnAfterUpdateWorldTransforms
|
||||||
val lastMousePositionValue = lastMousePosition.value
|
|
||||||
if (lastMousePositionValue == null) {
|
|
||||||
lastMousePosition.value = mousePosition.value
|
|
||||||
return@setOnAfterUpdateWorldTransforms
|
|
||||||
}
|
|
||||||
val mousePositionValue = mousePosition.value ?: return@setOnAfterUpdateWorldTransforms
|
|
||||||
|
|
||||||
val dx = mousePositionValue.x - lastMousePositionValue.x
|
val dx = mousePositionValue.x - lastMousePositionValue.x
|
||||||
val dy = mousePositionValue.y - lastMousePositionValue.y
|
val dy = mousePositionValue.y - lastMousePositionValue.y
|
||||||
val position = Point(
|
val position = Point(
|
||||||
controller.skeleton.x.toInt(),
|
controller.skeleton.x.toInt(),
|
||||||
controller.skeleton.y.toInt()
|
controller.skeleton.y.toInt()
|
||||||
)
|
)
|
||||||
position.x += dx
|
position.x += dx
|
||||||
position.y += dy
|
position.y += dy
|
||||||
controller.skeleton.setPosition(position.x.toFloat(), position.y.toFloat());
|
controller.skeleton.setPosition(position.x.toFloat(), position.y.toFloat());
|
||||||
lastMousePosition.value = mousePositionValue
|
lastMousePosition.value = mousePositionValue
|
||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
|
|||||||
@ -26,12 +26,9 @@ fun PlayPause(
|
|||||||
nav: NavHostController
|
nav: NavHostController
|
||||||
) {
|
) {
|
||||||
val controller = remember {
|
val controller = remember {
|
||||||
SpineController.Builder()
|
SpineController { controller ->
|
||||||
.setOnInitialized {
|
controller.animationState.setAnimation(0, "flying", true)
|
||||||
it.animationState.setAnimation(0, "flying", true)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val isPlaying = remember { mutableStateOf(controller.isPlaying) }
|
val isPlaying = remember { mutableStateOf(controller.isPlaying) }
|
||||||
|
|||||||
@ -40,11 +40,9 @@ fun SimpleAnimation(nav: NavHostController) {
|
|||||||
"spineboy.atlas",
|
"spineboy.atlas",
|
||||||
"spineboy-pro.json",
|
"spineboy-pro.json",
|
||||||
context,
|
context,
|
||||||
SpineController.Builder()
|
SpineController {
|
||||||
.setOnInitialized {
|
it.animationState.setAnimation(0, "walk", true)
|
||||||
it.animationState.setAnimation(0, "walk", true)
|
}
|
||||||
}
|
|
||||||
.build()
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.padding(paddingValues)
|
modifier = Modifier.padding(paddingValues)
|
||||||
|
|||||||
@ -17,15 +17,14 @@ import com.esotericsoftware.spine.android.utils.SpineControllerCallback;
|
|||||||
public class SpineController {
|
public class SpineController {
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private SpineControllerCallback onInitialized;
|
private final SpineControllerCallback onInitialized;
|
||||||
private SpineControllerCallback onBeforeUpdateWorldTransforms;
|
private SpineControllerCallback onBeforeUpdateWorldTransforms;
|
||||||
private SpineControllerCallback onAfterUpdateWorldTransforms;
|
private SpineControllerCallback onAfterUpdateWorldTransforms;
|
||||||
private SpineControllerBeforePaintCallback onBeforePaint;
|
private SpineControllerBeforePaintCallback onBeforePaint;
|
||||||
private SpineControllerAfterPaintCallback onAfterPaint;
|
private SpineControllerAfterPaintCallback onAfterPaint;
|
||||||
|
|
||||||
public Builder setOnInitialized(SpineControllerCallback onInitialized) {
|
public Builder(SpineControllerCallback onInitialized) {
|
||||||
this.onInitialized = onInitialized;
|
this.onInitialized = onInitialized;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setOnBeforeUpdateWorldTransforms(SpineControllerCallback onBeforeUpdateWorldTransforms) {
|
public Builder setOnBeforeUpdateWorldTransforms(SpineControllerCallback onBeforeUpdateWorldTransforms) {
|
||||||
@ -49,8 +48,7 @@ public class SpineController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SpineController build() {
|
public SpineController build() {
|
||||||
SpineController spineController = new SpineController();
|
SpineController spineController = new SpineController(onInitialized);
|
||||||
spineController.onInitialized = onInitialized;
|
|
||||||
spineController.onBeforeUpdateWorldTransforms = onBeforeUpdateWorldTransforms;
|
spineController.onBeforeUpdateWorldTransforms = onBeforeUpdateWorldTransforms;
|
||||||
spineController.onAfterUpdateWorldTransforms = onAfterUpdateWorldTransforms;
|
spineController.onAfterUpdateWorldTransforms = onAfterUpdateWorldTransforms;
|
||||||
spineController.onBeforePaint = onBeforePaint;
|
spineController.onBeforePaint = onBeforePaint;
|
||||||
@ -59,7 +57,7 @@ public class SpineController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable SpineControllerCallback onInitialized;
|
private final SpineControllerCallback onInitialized;
|
||||||
private @Nullable SpineControllerCallback onBeforeUpdateWorldTransforms;
|
private @Nullable SpineControllerCallback onBeforeUpdateWorldTransforms;
|
||||||
private @Nullable SpineControllerCallback onAfterUpdateWorldTransforms;
|
private @Nullable SpineControllerCallback onAfterUpdateWorldTransforms;
|
||||||
private @Nullable SpineControllerBeforePaintCallback onBeforePaint;
|
private @Nullable SpineControllerBeforePaintCallback onBeforePaint;
|
||||||
@ -71,6 +69,10 @@ public class SpineController {
|
|||||||
private double scaleX = 1;
|
private double scaleX = 1;
|
||||||
private double scaleY = 1;
|
private double scaleY = 1;
|
||||||
|
|
||||||
|
public SpineController(SpineControllerCallback onInitialized) {
|
||||||
|
this.onInitialized = onInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
protected void init(AndroidSkeletonDrawable drawable) {
|
protected void init(AndroidSkeletonDrawable drawable) {
|
||||||
this.drawable = drawable;
|
this.drawable = drawable;
|
||||||
if (onInitialized != null) {
|
if (onInitialized != null) {
|
||||||
|
|||||||
@ -120,12 +120,12 @@ public class SpineView extends View implements Choreographer.FrameCallback {
|
|||||||
|
|
||||||
public SpineView (Context context, AttributeSet attrs) {
|
public SpineView (Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
this.controller = new SpineController();
|
// TODO Load controller & assets fro attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpineView (Context context, AttributeSet attrs, int defStyle) {
|
public SpineView (Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
this.controller = new SpineController();
|
// TODO Load controller & assets fro attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SpineView loadFromAssets(String atlasFileName, String skeletonFileName, Context context, SpineController controller) {
|
public static SpineView loadFromAssets(String atlasFileName, String skeletonFileName, Context context, SpineController controller) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user