mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-28 20:51:38 +08:00
Add Animation State Events sample
This commit is contained in:
parent
32e4ea138a
commit
e7a075eeb6
@ -0,0 +1,148 @@
|
|||||||
|
package com.esotericsoftware.spine
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.ArrowBack
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.esotericsoftware.spine.android.SpineController
|
||||||
|
import com.esotericsoftware.spine.android.SpineView
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun AnimationState(nav: NavHostController) {
|
||||||
|
|
||||||
|
val TAG = "AnimationState"
|
||||||
|
|
||||||
|
val controller = remember {
|
||||||
|
SpineController.Builder()
|
||||||
|
.setOnInitialized { controller ->
|
||||||
|
controller.skeleton.setScaleX(0.5f)
|
||||||
|
controller.skeleton.setScaleY(0.5f)
|
||||||
|
|
||||||
|
controller.skeleton.findSlot("gun")?.color = Color(1f, 0f, 0f, 1f)
|
||||||
|
|
||||||
|
controller.animationStateData.setDefaultMix(0.2f)
|
||||||
|
controller.animationState.setAnimation(0, "walk", true).setListener(object : AnimationState.AnimationStateListener {
|
||||||
|
override fun start(entry: AnimationState.TrackEntry?) {
|
||||||
|
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} }")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Log.d(TAG, "Current: ${controller.animationState.getCurrent(0)?.getAnimation()?.getName()}");
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopAppBar(
|
||||||
|
title = { Text(text = Destination.SimpleAnimation.title) },
|
||||||
|
navigationIcon = {
|
||||||
|
IconButton({ nav.navigateUp() }) {
|
||||||
|
Icon(
|
||||||
|
Icons.Rounded.ArrowBack,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(paddingValues),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
Text("See output in console!")
|
||||||
|
AndroidView(
|
||||||
|
factory = { ctx ->
|
||||||
|
SpineView(ctx).apply {
|
||||||
|
loadFromAsset(
|
||||||
|
"spineboy.atlas",
|
||||||
|
"spineboy-pro.json",
|
||||||
|
controller
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -60,6 +60,7 @@ fun AppContent() {
|
|||||||
listOf(
|
listOf(
|
||||||
Destination.SimpleAnimation,
|
Destination.SimpleAnimation,
|
||||||
Destination.PlayPause,
|
Destination.PlayPause,
|
||||||
|
Destination.AnimationStateEvents,
|
||||||
Destination.IKFollowing
|
Destination.IKFollowing
|
||||||
),
|
),
|
||||||
paddingValues
|
paddingValues
|
||||||
@ -79,6 +80,12 @@ fun AppContent() {
|
|||||||
PlayPause(navController)
|
PlayPause(navController)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
composable(
|
||||||
|
Destination.AnimationStateEvents.route
|
||||||
|
) {
|
||||||
|
AnimationState(navController)
|
||||||
|
}
|
||||||
|
|
||||||
composable(
|
composable(
|
||||||
Destination.IKFollowing.route
|
Destination.IKFollowing.route
|
||||||
) {
|
) {
|
||||||
@ -120,5 +127,6 @@ sealed class Destination(val route: String, val title: String) {
|
|||||||
data object Samples: Destination("samples", "Spine Android Examples")
|
data object Samples: Destination("samples", "Spine Android Examples")
|
||||||
data object SimpleAnimation : Destination("simpleAnimation", "Simple Animation")
|
data object SimpleAnimation : Destination("simpleAnimation", "Simple Animation")
|
||||||
data object PlayPause : Destination("playPause", "Play/Pause")
|
data object PlayPause : Destination("playPause", "Play/Pause")
|
||||||
|
data object AnimationStateEvents : Destination("animationStateEvents", "Animation State Listener")
|
||||||
data object IKFollowing : Destination("ikFollowing", "IK Following")
|
data object IKFollowing : Destination("ikFollowing", "IK Following")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,7 @@ import com.esotericsoftware.spine.attachments.VertexAttachment;
|
|||||||
public class Slot {
|
public class Slot {
|
||||||
final SlotData data;
|
final SlotData data;
|
||||||
final Bone bone;
|
final Bone bone;
|
||||||
final Color color = new Color();
|
Color color = new Color();
|
||||||
@Null final Color darkColor;
|
@Null final Color darkColor;
|
||||||
@Null Attachment attachment;
|
@Null Attachment attachment;
|
||||||
int sequenceIndex;
|
int sequenceIndex;
|
||||||
@ -95,6 +95,10 @@ public class Slot {
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setColor(Color color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
/** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark
|
/** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark
|
||||||
* color's alpha is not used. */
|
* color's alpha is not used. */
|
||||||
public @Null Color getDarkColor () {
|
public @Null Color getDarkColor () {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user