animation.html 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="Asciidoctor 1.5.4"><title>Animation in jME3</title><link rel="stylesheet" href="./asciidoctor.css">
  2. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
  3. <link rel="stylesheet" href="./coderay-asciidoctor.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css"><link rel="stylesheet" href="/home/travis/build/jMonkeyEngine/wiki/build/asciidoc/html5/jme3/advanced/twemoji-awesome.css"></head><body class="article toc2 toc-left"><div id="header"><div id="toolbar"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/src/docs/asciidoc/jme3/advanced/animation.adoc"><i class="fa fa-pencil-square" aria-hidden="true"></i></a><a href="https://github.com/jMonkeyEngine/wiki/new/master/src/docs/asciidoc/jme3/advanced/"><i class="fa fa-plus-square" aria-hidden="true"></i></a><input dir="auto" style="position: relative; vertical-align: top;" spellcheck="false" autocomplete="off" class="searchbox__input aa-input" id="doc-search" name="search" placeholder="Search in the doc" required="required" type="search"></div><h1>Animation in jME3</h1><div class="details"><span class="author" id="author"></span><br><span id="revnumber">version ,</span> <span id="revdate">2016/03/17 20:48</span></div><div id="toc" class="toc2"><div id="toctitle">Table of Contents</div><ul class="sectlevel1"><li><a href="#requirements">Requirements</a></li><li><a href="#code-samples">Code Samples</a></li><li><a href="#controlling-animations">Controlling Animations</a><ul class="sectlevel2"><li><a href="#the-animation-control">The Animation Control</a></li><li><a href="#animation-channels">Animation Channels</a></li><li><a href="#skeleton-control">Skeleton Control</a></li></ul></li><li><a href="#animation-control-properties">Animation Control Properties</a></li><li><a href="#skeleton-control-properties">Skeleton Control Properties</a></li><li><a href="#animation-channel-properties">Animation Channel Properties</a></li><li><a href="#playing-animations">Playing Animations</a><ul class="sectlevel2"><li><a href="#usage-example">Usage Example</a></li></ul></li><li><a href="#animation-event-listener">Animation Event Listener</a><ul class="sectlevel2"><li><a href="#responding-to-animation-end">Responding to Animation End</a></li><li><a href="#responding-to-animation-start">Responding to Animation Start</a></li></ul></li></ul></div></div><div id="content"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>In 3D games, you do not only load static 3D models, you also want to be able to trigger animations in the model from the Java code.</p></div></div></div>
  4. <div class="sect1"><h2 id="requirements">Requirements</h2><div class="sectionbody"><div class="paragraph"><p>JME3 only loads and plays animated models, it does not create them.</p></div>
  5. <div class="paragraph"><p>What is required for an animated model? (<a href="../../jme3/terminology.html#Animation">See also: Animation terminology</a>)</p></div>
  6. <div class="olist arabic"><ol class="arabic"><li><p>For each model, you have to segment the model into a skeleton (<strong>bone rigging</strong>).</p></li><li><p>For each motion, you have to specify how the animation distorts parts of the model (<strong>skinning</strong>).</p></li><li><p>For each animation, you have to specify a series of snapshots of how the bones are positioned (<strong>keyframes</strong>).</p></li><li><p>One model can contain several animations. You give every animation a name when you save it in the mesh editor.</p></li></ol></div>
  7. <div class="paragraph"><p>Unless you download free models, or buy them from a 3D artist, you must create your animated models in an <strong>external mesh editor</strong> (for example, Blender) yourself.</p></div>
  8. <div class="ulist"><ul><li><p><a href="../../jme3/features.html#supported-external-file-types">Supported External File Types</a></p></li><li><p><a href="../../jme3/external/blender.html">Creating assets in Blender3D</a></p></li><li><p><a href="http://www.youtube.com/watch?v=IDHMWsu_PqA">Video: Creating Worlds with Instances in Blender</a></p></li></ul></div>
  9. <div class="paragraph"><p>What is required in your JME3-based Java class?</p></div>
  10. <div class="ulist"><ul><li><p>One Animation Control per animated model.</p></li><li><p>As many Animation Channels per Control as you need to play your animations. In simple cases one channel is enough, sometimes you need two or more Channels per model to play gestures and motions in parallel.</p></li></ul></div></div></div>
  11. <div class="sect1"><h2 id="code-samples">Code Samples</h2><div class="sectionbody"><div class="ulist"><ul><li><p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java">TestSpatialAnim.java</a></p></li><li><p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestBlenderAnim.java">TestBlenderAnim.java</a></p></li><li><p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestBlenderObjectAnim.java">TestBlenderObjectAnim.java</a></p></li><li><p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java">TestOgreAnim.java</a></p></li><li><p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java">TestOgreComplexAnim.java</a></p></li><li><p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java">TestCustomAnim.java</a></p></li></ul></div></div></div>
  12. <div class="sect2"><h3 id="controlling-animations">Controlling Animations</h3><div class="sect2"><h3 id="the-animation-control">The Animation Control</h3><div class="paragraph"><p>Create one <code>com.jme3.animation.AnimControl</code> object in your JME3 application for each animated model that you want to control. You have to register each animated model to one of these Animation Controls. The control object gives you access to the available animation sequences in the model.</p></div>
  13. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> AnimControl playerControl; <span class="comment">// you need one Control per model</span>
  14. Node player = (Node) assetManager.loadModel(<span class="string"><span class="delimiter">&quot;</span><span class="content">Models/Oto/Oto.mesh.xml</span><span class="delimiter">&quot;</span></span>); <span class="comment">// load a model</span>
  15. playerControl = player.getControl(AnimControl.class); <span class="comment">// get control over this model</span>
  16. playerControl.addListener(<span class="local-variable">this</span>); <span class="comment">// add listener</span></code></pre></div></div></div>
  17. <div class="sect2"><h3 id="animation-channels">Animation Channels</h3><div class="paragraph"><p>An Animation Control has several Animation Channels (<code>com.jme3.animation.AnimChannel</code>). Each channel can play one animation sequence at a time.</p></div>
  18. <div class="paragraph"><p>There often are situations where you want to run several animation sequences at the same time, e.g. &#8220;shooting&#8221; while walking or &#8220;boxing&#8221; while jumping. In this case, you create several channels, assign an animation to each, and play them in parallel.</p></div>
  19. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> AnimChannel channel_walk = playerControl.createChannel();
  20. AnimChannel channel_jump = playerControl.createChannel();
  21. ...</code></pre></div></div>
  22. <div class="paragraph"><p>To reset a Control, call <code>control.clearChannels()</code>.</p></div></div>
  23. <div class="sect2"><h3 id="skeleton-control">Skeleton Control</h3><div class="paragraph"><p>The Skeleton control deforms a model according to a skeleton. Use it to attach other geometries to your model such as clothing, weapons, accessories or a particle emitter effect. You access the control the same way as you would the AnimControl.</p></div>
  24. <div class="listingblock"><div class="title">Control resides in the main node of your model</div>
  25. <div class="content"><pre class="CodeRay highlight"><code data-lang="java">SkeletonControl skeletonControl;
  26. skeletonControl = player.getControl(SkeletonControl.class);</code></pre></div></div>
  27. <div class="listingblock"><div class="title">Control rsides somewhere other than main node</div>
  28. <div class="content"><pre class="CodeRay highlight"><code data-lang="java">player.depthFirstTraversal(<span class="keyword">new</span> SceneGraphVisitorAdapter() {
  29. <span class="annotation">@Override</span>
  30. <span class="directive">public</span> <span class="type">void</span> visit(Node node) {
  31. <span class="keyword">if</span> (node.getControl(SkeletonControl.class) != <span class="predefined-constant">null</span>) {
  32. skeletonControl = node.getControl(SkeletonControl.class);
  33. }
  34. }
  35. });</code></pre></div></div></div></div>
  36. <div class="sect1"><h2 id="animation-control-properties">Animation Control Properties</h2><div class="sectionbody"><div class="paragraph"><p>The following information is available for an AnimControl.</p></div>
  37. <table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 50%;"><col style="width: 50%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">AnimControl Property</th><th class="tableblock halign-left valign-top">Usage</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>createChannel()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Returns a new channel, controlling all bones by default.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getNumChannels()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The number of channels registered to this Control.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getChannel(0)</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Gets individual channels by index number. At most <code>getNumChannels()</code>.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>clearChannels()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Clear all channels in this control.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>addListener(animEventListener)<br>
  38. removeListener(animEventListener)<br>
  39. clearListeners()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Adds or removes listeners to receive animation related events.</p></div></div></td></tr></tbody></table>
  40. <table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 50%;"><col style="width: 50%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">AnimControl Property</th><th class="tableblock halign-left valign-top">Usage</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>setAnimations(aniHashMap)</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Sets the animations that this AnimControl is capable of playing. The animations must be compatible with the skeleton given in the constructor.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>addAnim(boneAnim)<br>
  41. removeAnim(boneAnim)</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Adds or removes an animation from this Control.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getAnimationNames()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>A String Collection of names of all animations that this Control can play for this model.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getAnim(&#8220;anim&#8221;)</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Retrieve an animation from the list of animations.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getAnimationLength(&#8220;anim&#8221;)</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Returns the length of the given named animation in seconds</p></div></div></td></tr></tbody></table>
  42. <table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 50%;"><col style="width: 50%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">AnimControl Property</th><th class="tableblock halign-left valign-top">Usage</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getSkeleton()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The Skeleton object controlled by this Control.</p></div></div></td></tr></tbody></table></div></div>
  43. <div class="sect1"><h2 id="skeleton-control-properties">Skeleton Control Properties</h2><div class="sectionbody"><div class="paragraph"><p>The following information is available for an SkeletonControl.</p></div>
  44. <table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 50%;"><col style="width: 50%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">SkeletonControl Property</th><th class="tableblock halign-left valign-top">Usage</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getSkeleton()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The Skeleton object controlled by this Control.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getTargets()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The Skin objects controlled by this Control, as Mesh array.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getAttachmentsNode(&#8220;bone&#8221;)</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Returns the attachment node of a bone. Attach models and effects to this node to make them follow this bone&#8217;s motions.</p></div></div></td></tr></tbody></table></div></div>
  45. <div class="sect1"><h2 id="animation-channel-properties">Animation Channel Properties</h2><div class="sectionbody"><div class="paragraph"><p>The following properties are set per AnimChannel.</p></div>
  46. <table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 50%;"><col style="width: 50%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">AnimChannel Property</th><th class="tableblock halign-left valign-top">Usage</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>setLoopMode(LoopMode.Loop);</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>From now on, the animation on this channel will repeat from the beginning when it ends.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>setLoopMode(LoopMode.DontLoop);</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>From now on, the animation on this channel will play once, and the freeze at the last keyframe.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>setLoopMode(LoopMode.Cycle);</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>From now on, the animation on this channel will play forward, then backward, then again forward, and so on.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>setSpeed(1f);</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>From now on, play this animation slower (&lt;1f) or faster (&gt;1f), or with default speed (1f).</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>setTime(1.3f);</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Fast-forward or rewind to a certain moment in time of this animation.</p></div></div></td></tr></tbody></table>
  47. <div class="paragraph"><p>The following information is available for a channel.</p></div>
  48. <table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 50%;"><col style="width: 50%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">AnimChannel Property</th><th class="tableblock halign-left valign-top">Usage</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getAnimationName()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The name of the animation playing on this channel. Returns <code>null</code> when no animation is playing.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getLoopMode()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The current loop mode on this channel. The returned com.jme3.animation enum can be LoopMode.Loop, LoopMode.DontLoop, or LoopMode.Cycle.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getAnimMaxTime()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The total length of the animation on this channel. Or <code>0f</code> if nothing is playing.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getTime()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>How long the animation on this channel has been playing. It returns <code>0f</code> if the channel has not started playing yet, or a value up to getAnimMaxTime().</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>getControl()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>The AnimControl that belongs to this AnimChannel.</p></div></div></td></tr></tbody></table>
  49. <div class="paragraph"><p>Use the following methods to add or remove individual bones to an AnimChannel. This is useful when you play two animations in parallel on two channels, and each controls a subset of the bones (e.g. one the arms, and the other the legs).</p></div>
  50. <table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 50%;"><col style="width: 50%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">AnimChannel Methods</th><th class="tableblock halign-left valign-top">Usage</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>addAllBones()</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Add all the bones of the model&#8217;s skeleton to be influenced by this animation channel. (default)</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>addBone(&#8220;bone1&#8221;)<br>
  51. addBone(bone1)</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Add a single bone to be influenced by this animation channel.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>addToRootBone(&#8220;bone1&#8221;)<br>
  52. addToRootBone(bone1)</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Add a series of bones to be influenced by this animation channel: Add all bones, starting from the given bone, to the root bone.</p></div></div></td></tr><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>addFromRootBone(&#8220;bone1&#8221;)<br>
  53. addFromRootBone(bone1)</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Add a series of bones to be influenced by this animation channel: Add all bones, starting from the given root bone, going towards the children bones.</p></div></div></td></tr></tbody></table></div></div>
  54. <div class="sect2"><h3 id="playing-animations">Playing Animations</h3><div class="paragraph"><p>Animations are played by channel.</p></div>
  55. <div class="admonitionblock note"><table><tr><td class="icon"><i class="fa icon-note" title="Note"></i></td><td class="content">Whether the animation channel plays continuously or only once, depends on the Loop properties you have set.</td></tr></table></div>
  56. <table class="tableblock frame-all grid-all spread"><colgroup><col style="width: 50%;"><col style="width: 50%;"></colgroup><thead><tr><th class="tableblock halign-left valign-top">Channel Method</th><th class="tableblock halign-left valign-top">Usage</th></tr></thead><tbody><tr><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>channel_walk.setAnim(&#8220;Walk&#8221;,0.50f);</p></div></div></td><td class="tableblock halign-left valign-top"><div><div class="paragraph"><p>Start the animation named &#8220;Walk&#8221; on channel channel_walk.<br>
  57. The float value specifies the time how long the animation should overlap with the previous one on this channel. If set to 0f, then no blending will occur and the new animation will be applied instantly.</p></div></div></td></tr></tbody></table>
  58. <div class="admonitionblock tip"><table><tr><td class="icon"><i class="fa icon-tip" title="Tip"></i></td><td class="content"><div class="paragraph"><p>Use the AnimEventLister below to react at the end or start of an animation cycle.</p></div></td></tr></table></div>
  59. <div class="sect2"><h3 id="usage-example">Usage Example</h3><div class="paragraph"><p>In this short example, we define the space key to trigger playing the &#8220;Walk&#8221; animation on channel2.</p></div>
  60. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> <span class="directive">public</span> <span class="type">void</span> simpleInitApp() {
  61. ...
  62. inputManager.addMapping(<span class="string"><span class="delimiter">&quot;</span><span class="content">Walk</span><span class="delimiter">&quot;</span></span>, <span class="keyword">new</span> KeyTrigger(KeyInput.KEY_SPACE));
  63. inputManager.addListener(actionListener, <span class="string"><span class="delimiter">&quot;</span><span class="content">Walk</span><span class="delimiter">&quot;</span></span>);
  64. ...
  65. }
  66. <span class="directive">private</span> <span class="predefined-type">ActionListener</span> actionListener = <span class="keyword">new</span> <span class="predefined-type">ActionListener</span>() {
  67. <span class="directive">public</span> <span class="type">void</span> onAction(<span class="predefined-type">String</span> name, <span class="type">boolean</span> keyPressed, <span class="type">float</span> tpf) {
  68. <span class="keyword">if</span> (name.equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">Walk</span><span class="delimiter">&quot;</span></span>) &amp;&amp; !keyPressed) {
  69. <span class="keyword">if</span> (!channel2.getAnimationName().equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">Walk</span><span class="delimiter">&quot;</span></span>)) {
  70. channel2.setLoopMode(LoopMode.Loop);
  71. channel2.setAnim(<span class="string"><span class="delimiter">&quot;</span><span class="content">Walk</span><span class="delimiter">&quot;</span></span>, <span class="float">0.50f</span>);
  72. }
  73. }
  74. }
  75. };</code></pre></div></div></div></div>
  76. <div class="sect2"><h3 id="animation-event-listener">Animation Event Listener</h3><div class="paragraph"><p>A jME3 application that contains animations can implement the <code>com.jme3.animation.AnimEventListener</code> interface.</p></div>
  77. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">HelloAnimation</span> <span class="directive">extends</span> SimpleApplication
  78. <span class="directive">implements</span> AnimEventListener { ... }</code></pre></div></div>
  79. <div class="paragraph"><p>This optional Listener enables you to respond to animation start and end events, <code>onAnimChange()</code> and <code>onAnimCycleDone()</code>.</p></div>
  80. <div class="sect2"><h3 id="responding-to-animation-end">Responding to Animation End</h3><div class="paragraph"><p>The <code>onAnimCycleDone()</code> event is invoked when an animation cycle has ended. For non-looping animations, this event is invoked when the animation is finished playing. For looping animations, this event is invoked each time the animation loop is restarted.</p></div>
  81. <div class="paragraph"><p>You have access to the following objects:</p></div>
  82. <div class="ulist"><ul><li><p>The Control to which the listener is assigned.</p></li><li><p>The animation channel being played.</p></li><li><p>The name of the animation that has just finished playing.</p></li></ul></div>
  83. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> <span class="directive">public</span> <span class="type">void</span> onAnimCycleDone(AnimControl control, AnimChannel channel, <span class="predefined-type">String</span> animName) {
  84. <span class="comment">// test for a condition you are interested in, e.g. ...</span>
  85. <span class="keyword">if</span> (animName.equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">Walk</span><span class="delimiter">&quot;</span></span>)) {
  86. <span class="comment">// respond to the event here, e.g. ...</span>
  87. channel.setAnim(<span class="string"><span class="delimiter">&quot;</span><span class="content">Stand</span><span class="delimiter">&quot;</span></span>, <span class="float">0.50f</span>);
  88. }
  89. }</code></pre></div></div></div>
  90. <div class="sect2"><h3 id="responding-to-animation-start">Responding to Animation Start</h3><div class="paragraph"><p>The <code>onAnimChange()</code> event is invoked every time before an animation is set by the user to be played on a given channel (<code>channel.setAnim()</code>).</p></div>
  91. <div class="paragraph"><p>You have access to the following objects:</p></div>
  92. <div class="ulist"><ul><li><p>The Control to which the listener is assigned.</p></li><li><p>The animation channel being played.</p></li><li><p>The name of the animation that will start playing.</p></li></ul></div>
  93. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"> <span class="directive">public</span> <span class="type">void</span> onAnimChange(AnimControl control, AnimChannel channel, <span class="predefined-type">String</span> animName) {
  94. <span class="comment">// test for a condition you are interested in, e.g. ...</span>
  95. <span class="keyword">if</span> (animName.equals(<span class="string"><span class="delimiter">&quot;</span><span class="content">Walk</span><span class="delimiter">&quot;</span></span>)) {
  96. <span class="comment">// respond to the event here, e.g. ...</span>
  97. channel.setAnim(<span class="string"><span class="delimiter">&quot;</span><span class="content">Reset</span><span class="delimiter">&quot;</span></span>, <span class="float">0.50f</span>);
  98. }
  99. }</code></pre></div></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2019-12-20 23:30:51 +00:00</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
  100. apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
  101. indexName: 'jmonkeyengine',
  102. inputSelector: '#doc-search',
  103. debug: false // Set debug to true if you want to inspect the dropdown
  104. });</script></body></html>