mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 15:24:55 +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(
|
||||
Destination.SimpleAnimation,
|
||||
Destination.PlayPause,
|
||||
Destination.AnimationStateEvents,
|
||||
Destination.IKFollowing
|
||||
),
|
||||
paddingValues
|
||||
@ -79,6 +80,12 @@ fun AppContent() {
|
||||
PlayPause(navController)
|
||||
}
|
||||
|
||||
composable(
|
||||
Destination.AnimationStateEvents.route
|
||||
) {
|
||||
AnimationState(navController)
|
||||
}
|
||||
|
||||
composable(
|
||||
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 SimpleAnimation : Destination("simpleAnimation", "Simple Animation")
|
||||
data object PlayPause : Destination("playPause", "Play/Pause")
|
||||
data object AnimationStateEvents : Destination("animationStateEvents", "Animation State Listener")
|
||||
data object IKFollowing : Destination("ikFollowing", "IK Following")
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||
public class Slot {
|
||||
final SlotData data;
|
||||
final Bone bone;
|
||||
final Color color = new Color();
|
||||
Color color = new Color();
|
||||
@Null final Color darkColor;
|
||||
@Null Attachment attachment;
|
||||
int sequenceIndex;
|
||||
@ -95,6 +95,10 @@ public class Slot {
|
||||
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
|
||||
* color's alpha is not used. */
|
||||
public @Null Color getDarkColor () {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user