Browse Source

Merge branch 'spriter-animation'

aster2013 11 years ago
parent
commit
fe3af57199
44 changed files with 3232 additions and 437 deletions
  1. 3 5
      Bin/Data/LuaScripts/24_Urho2DSprite.lua
  2. 167 0
      Bin/Data/LuaScripts/33_Urho2DSpriterAnimation.lua
  3. 3 5
      Bin/Data/Scripts/24_Urho2DSprite.as
  4. 171 0
      Bin/Data/Scripts/33_Urho2DSpriterAnimation.as
  5. 2 2
      Bin/Data/Scripts/Editor/AttributeEditor.as
  6. 0 8
      Bin/Data/Urho2D/GoldIcon.anm
  7. BIN
      Bin/Data/Urho2D/GoldIcon.png
  8. 57 0
      Bin/Data/Urho2D/GoldIcon.scml
  9. 0 10
      Bin/Data/Urho2D/GoldIcon.xml
  10. BIN
      Bin/Data/Urho2D/GoldIcon/1.png
  11. BIN
      Bin/Data/Urho2D/GoldIcon/2.png
  12. BIN
      Bin/Data/Urho2D/GoldIcon/3.png
  13. BIN
      Bin/Data/Urho2D/GoldIcon/4.png
  14. BIN
      Bin/Data/Urho2D/GoldIcon/5.png
  15. 1312 0
      Bin/Data/Urho2D/imp/imp.scml
  16. BIN
      Bin/Data/Urho2D/imp/imp_blood.png
  17. BIN
      Bin/Data/Urho2D/imp/imp_body.png
  18. BIN
      Bin/Data/Urho2D/imp/imp_footbig.png
  19. BIN
      Bin/Data/Urho2D/imp/imp_footsmall.png
  20. BIN
      Bin/Data/Urho2D/imp/imp_handbig.png
  21. BIN
      Bin/Data/Urho2D/imp/imp_handsmall.png
  22. BIN
      Bin/Data/Urho2D/imp/imp_handthrow.png
  23. BIN
      Bin/Data/Urho2D/imp/imp_head.png
  24. BIN
      Bin/Data/Urho2D/imp/imp_headangry.png
  25. BIN
      Bin/Data/Urho2D/imp/imp_headblink.png
  26. 17 14
      Source/Engine/LuaScript/pkgs/Urho2D/AnimatedSprite2D.pkg
  27. 12 12
      Source/Engine/LuaScript/pkgs/Urho2D/Animation2D.pkg
  28. 10 0
      Source/Engine/LuaScript/pkgs/Urho2D/AnimationSet2D.pkg
  29. 3 0
      Source/Engine/LuaScript/pkgs/Urho2DLuaAPI.pkg
  30. 30 17
      Source/Engine/Script/Urho2DAPI.cpp
  31. 264 67
      Source/Engine/Urho2D/AnimatedSprite2D.cpp
  32. 68 34
      Source/Engine/Urho2D/AnimatedSprite2D.h
  33. 184 181
      Source/Engine/Urho2D/Animation2D.cpp
  34. 187 66
      Source/Engine/Urho2D/Animation2D.h
  35. 286 0
      Source/Engine/Urho2D/AnimationSet2D.cpp
  36. 72 0
      Source/Engine/Urho2D/AnimationSet2D.h
  37. 41 4
      Source/Engine/Urho2D/StaticSprite2D.cpp
  38. 12 0
      Source/Engine/Urho2D/StaticSprite2D.h
  39. 7 5
      Source/Engine/Urho2D/Urho2D.cpp
  40. 5 7
      Source/Samples/24_Urho2DSprite/Urho2DSprite.cpp
  41. 33 0
      Source/Samples/33_Urho2DSpriterAnimation/CMakeLists.txt
  42. 193 0
      Source/Samples/33_Urho2DSpriterAnimation/Urho2DSpriterAnimation.cpp
  43. 92 0
      Source/Samples/33_Urho2DSpriterAnimation/Urho2DSpriterAnimation.h
  44. 1 0
      Source/Samples/CMakeLists.txt

+ 3 - 5
Bin/Data/LuaScripts/24_Urho2DSprite.lua

@@ -92,8 +92,8 @@ function CreateScene()
         end
         end
     end
     end
 
 
-    local animation = cache:GetResource("Animation2D", "Urho2D/GoldIcon.anm")
-    if animation == nil then
+    local animationSet = cache:GetResource("AnimationSet2D", "Urho2D/GoldIcon.scml")
+    if animationSet == nil then
         return
         return
     end
     end
 
 
@@ -102,9 +102,7 @@ function CreateScene()
 
 
     local animatedSprite = spriteNode:CreateComponent("AnimatedSprite2D")
     local animatedSprite = spriteNode:CreateComponent("AnimatedSprite2D")
     -- Set animation
     -- Set animation
-    animatedSprite.animation = animation
-    -- Set blend mode
-    animatedSprite.blendMode = BLEND_ALPHA
+    animatedSprite:SetAnimation(animationSet, "idle")
 end
 end
 
 
 function CreateInstructions()
 function CreateInstructions()

+ 167 - 0
Bin/Data/LuaScripts/33_Urho2DSpriterAnimation.lua

@@ -0,0 +1,167 @@
+-- Urho2D sprite example.
+-- This sample demonstrates:
+--     - Creating a 2D scene with spriter animation
+--     - Displaying the scene using the Renderer subsystem
+--     - Handling keyboard to move and zoom 2D camera
+
+require "LuaScripts/Utilities/Sample"
+
+local spriteNode = nil
+local animationIndex = 0
+local animationNames = 
+{
+    "idle",
+    "run",
+    "attack",
+    "hit",
+    "dead",
+    "dead2",
+    "dead3",
+}
+
+function Start()
+    -- Execute the common startup for samples
+    SampleStart()
+
+    -- Create the scene content
+    CreateScene()
+
+    -- Create the UI content
+    CreateInstructions()
+
+    -- Setup the viewport for displaying the scene
+    SetupViewport()
+
+    -- Hook up to the frame update events
+    SubscribeToEvents()
+end
+
+function CreateScene()
+    scene_ = Scene()
+
+    -- Create the Octree component to the scene. This is required before adding any drawable components, or else nothing will
+    -- show up. The default octree volume will be from (-1000, -1000, -1000) to (1000, 1000, 1000) in world coordinates it
+    -- is also legal to place objects outside the volume but their visibility can then not be checked in a hierarchically
+    -- optimizing manner
+    scene_:CreateComponent("Octree")
+
+    -- Create a scene node for the camera, which we will move around
+    -- The camera will use default settings (1000 far clip distance, 45 degrees FOV, set aspect ratio automatically)
+    cameraNode = scene_:CreateChild("Camera")
+    -- Set an initial position for the camera scene node above the plane
+    cameraNode.position = Vector3(0.0, 0.0, -10.0)
+    local camera = cameraNode:CreateComponent("Camera")
+    camera.orthographic = true
+    camera.orthoSize = graphics.height * PIXEL_SIZE
+
+    local animationSet = cache:GetResource("AnimationSet2D", "Urho2D/imp/imp.scml")
+    if animationSet == nil then
+        return
+    end
+
+    spriteNode = scene_:CreateChild("SpriterAnimation")
+    spriteNode.position = Vector3(-1.4, 2.0, 0.0)
+
+    local animatedSprite = spriteNode:CreateComponent("AnimatedSprite2D")
+    animatedSprite:SetAnimation(animationSet, animationNames[animationIndex + 1])
+end
+
+function CreateInstructions()
+    -- Construct new Text object, set string to display and font to use
+    local instructionText = ui.root:CreateChild("Text")
+    instructionText:SetText("Click mouse to play next animation, \nUse WASD keys and mouse to move, Use PageUp PageDown to zoom.")
+    instructionText:SetFont(cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15)
+
+    -- Position the text relative to the screen center
+    instructionText.horizontalAlignment = HA_CENTER
+    instructionText.verticalAlignment = VA_CENTER
+    instructionText:SetPosition(0, ui.root.height / 4)
+end
+
+function SetupViewport()
+    -- Set up a viewport to the Renderer subsystem so that the 3D scene can be seen. We need to define the scene and the camera
+    -- at minimum. Additionally we could configure the viewport screen size and the rendering path (eg. forward / deferred) to
+    -- use, but now we just use full screen and default render path configured in the engine command line options
+    local viewport = Viewport:new(scene_, cameraNode:GetComponent("Camera"))
+    renderer:SetViewport(0, viewport)
+end
+
+function MoveCamera(timeStep)
+    -- Do not move if the UI has a focused element (the console)
+    if ui.focusElement ~= nil then
+        return
+    end
+
+    -- Movement speed as world units per second
+    local MOVE_SPEED = 4.0
+
+    -- Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
+    if input:GetKeyDown(KEY_W) then
+        cameraNode:Translate(Vector3(0.0, 1.0, 0.0) * MOVE_SPEED * timeStep)
+    end
+    if input:GetKeyDown(KEY_S) then
+        cameraNode:Translate(Vector3(0.0, -1.0, 0.0) * MOVE_SPEED * timeStep)
+    end
+    if input:GetKeyDown(KEY_A) then
+        cameraNode:Translate(Vector3(-1.0, 0.0, 0.0) * MOVE_SPEED * timeStep)
+    end
+    if input:GetKeyDown(KEY_D) then
+        cameraNode:Translate(Vector3(1.0, 0.0, 0.0) * MOVE_SPEED * timeStep)
+    end
+
+    if input:GetKeyDown(KEY_PAGEUP) then
+        local camera = cameraNode:GetComponent("Camera")
+        camera.zoom = camera.zoom * 1.01
+    end
+
+    if input:GetKeyDown(KEY_PAGEDOWN) then
+        local camera = cameraNode:GetComponent("Camera")
+        camera.zoom = camera.zoom * 0.99
+    end
+end
+
+function SubscribeToEvents()
+    -- Subscribe HandleUpdate() function for processing update events
+    SubscribeToEvent("Update", "HandleUpdate")
+    SubscribeToEvent("MouseButtonDown", "HandleMouseButtonDown")
+
+    -- Unsubscribe the SceneUpdate event from base class to prevent camera pitch and yaw in 2D sample
+    UnsubscribeFromEvent("SceneUpdate")
+end
+
+function HandleUpdate(eventType, eventData)
+    -- Take the frame time step, which is stored as a float
+    local timeStep = eventData:GetFloat("TimeStep")
+
+    -- Move the camera, scale movement with time step
+    MoveCamera(timeStep)
+end
+
+function HandleMouseButtonDown(eventType, eventData)
+    local animatedSprite = spriteNode:GetComponent("AnimatedSprite2D")
+    animationIndex = (animationIndex + 1) % 7
+    animatedSprite.animation = animationNames[animationIndex + 1]
+end
+
+-- Create XML patch instructions for screen joystick layout specific to this sample app
+function GetScreenJoystickPatchString()
+    return
+        "<patch>" ..
+        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/attribute[@name='Is Visible']\" />" ..
+        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Zoom In</replace>" ..
+        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]\">" ..
+        "        <element type=\"Text\">" ..
+        "            <attribute name=\"Name\" value=\"KeyBinding\" />" ..
+        "            <attribute name=\"Text\" value=\"PAGEUP\" />" ..
+        "        </element>" ..
+        "    </add>" ..
+        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/attribute[@name='Is Visible']\" />" ..
+        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Zoom Out</replace>" ..
+        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]\">" ..
+        "        <element type=\"Text\">" ..
+        "            <attribute name=\"Name\" value=\"KeyBinding\" />" ..
+        "            <attribute name=\"Text\" value=\"PAGEDOWN\" />" ..
+        "        </element>" ..
+        "    </add>" ..
+        "</patch>"
+end

+ 3 - 5
Bin/Data/Scripts/24_Urho2DSprite.as

@@ -78,17 +78,15 @@ void CreateScene()
         spriteNodes.Push(spriteNode);
         spriteNodes.Push(spriteNode);
     }
     }
 
 
-    Animation2D@ animation = cache.GetResource("Animation2D", "Urho2D/GoldIcon.anm");
-    if (animation is null)
+    AnimationSet2D@ animationSet = cache.GetResource("AnimationSet2D", "Urho2D/GoldIcon.scml");
+    if (animationSet is null)
         return;
         return;
     Node@ spriteNode = scene_.CreateChild("AnimatedSprite2D");
     Node@ spriteNode = scene_.CreateChild("AnimatedSprite2D");
     spriteNode.position = Vector3(0.0f, 0.0f, -1.0f);
     spriteNode.position = Vector3(0.0f, 0.0f, -1.0f);
 
 
     AnimatedSprite2D@ animatedSprite = spriteNode.CreateComponent("AnimatedSprite2D");
     AnimatedSprite2D@ animatedSprite = spriteNode.CreateComponent("AnimatedSprite2D");
     // Set animation
     // Set animation
-    animatedSprite.animation = animation;
-    // Set blend mode
-    animatedSprite.blendMode = BLEND_ALPHA;
+    animatedSprite.SetAnimation(animationSet, "idle");
 }
 }
 
 
 void CreateInstructions()
 void CreateInstructions()

+ 171 - 0
Bin/Data/Scripts/33_Urho2DSpriterAnimation.as

@@ -0,0 +1,171 @@
+// Urho2D sprite example.
+// This sample demonstrates:
+//     - Creating a 2D scene with spriter animation
+//     - Displaying the scene using the Renderer subsystem
+//     - Handling keyboard to move and zoom 2D camera
+
+#include "Scripts/Utilities/Sample.as"
+
+Node@ spriteNode;
+int animationIndex = 0;
+
+Array<String> animationNames = 
+{
+    "idle",
+    "run",
+    "attack",
+    "hit",
+    "dead",
+    "dead2",
+    "dead3",
+};
+
+void Start()
+{
+    // Execute the common startup for samples
+    SampleStart();
+
+    // Create the scene content
+    CreateScene();
+
+    // Create the UI content
+    CreateInstructions();
+
+    // Setup the viewport for displaying the scene
+    SetupViewport();
+
+    // Hook up to the frame update events
+    SubscribeToEvents();
+}
+
+void CreateScene()
+{
+    scene_ = Scene();
+
+    // Create the Octree component to the scene. This is required before adding any drawable components, or else nothing will
+    // show up. The default octree volume will be from (-1000, -1000, -1000) to (1000, 1000, 1000) in world coordinates; it
+    // is also legal to place objects outside the volume but their visibility can then not be checked in a hierarchically
+    // optimizing manner
+    scene_.CreateComponent("Octree");
+
+    // Create a scene node for the camera, which we will move around
+    // The camera will use default settings (1000 far clip distance, 45 degrees FOV, set aspect ratio automatically)
+    cameraNode = scene_.CreateChild("Camera");
+    // Set an initial position for the camera scene node above the plane
+    cameraNode.position = Vector3(0.0f, 0.0f, -10.0f);
+
+    Camera@ camera = cameraNode.CreateComponent("Camera");
+    camera.orthographic = true;
+    camera.orthoSize = graphics.height * PIXEL_SIZE;
+
+    AnimationSet2D@ animationSet = cache.GetResource("AnimationSet2D", "Urho2D/imp/imp.scml");
+    if (animationSet is null)
+        return;
+
+    spriteNode = scene_.CreateChild("SpriterAnimation");
+    spriteNode.position = Vector3(-1.4f, 2.0f, 0.0f);
+
+    AnimatedSprite2D@ animatedSprite = spriteNode.CreateComponent("AnimatedSprite2D");
+    animatedSprite.SetAnimation(animationSet, animationNames[animationIndex]);
+}
+
+void CreateInstructions()
+{
+    // Construct new Text object, set string to display and font to use
+    Text@ instructionText = ui.root.CreateChild("Text");
+    instructionText.text = "Mouse click to play next animation, \nUse WASD keys to move, use PageUp PageDown keys to zoom.";
+    instructionText.SetFont(cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15);
+
+    // Position the text relative to the screen center
+    instructionText.horizontalAlignment = HA_CENTER;
+    instructionText.verticalAlignment = VA_CENTER;
+    instructionText.SetPosition(0, ui.root.height / 4);
+}
+
+void SetupViewport()
+{
+    // Set up a viewport to the Renderer subsystem so that the 3D scene can be seen. We need to define the scene and the camera
+    // at minimum. Additionally we could configure the viewport screen size and the rendering path (eg. forward / deferred) to
+    // use, but now we just use full screen and default render path configured in the engine command line options
+    Viewport@ viewport = Viewport(scene_, cameraNode.GetComponent("Camera"));
+    renderer.viewports[0] = viewport;
+}
+
+void MoveCamera(float timeStep)
+{
+    // Do not move if the UI has a focused element (the console)
+    if (ui.focusElement !is null)
+        return;
+
+    // Movement speed as world units per second
+    const float MOVE_SPEED = 4.0f;
+
+    // Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
+    if (input.keyDown['W'])
+        cameraNode.Translate(Vector3(0.0f, 1.0f, 0.0f) * MOVE_SPEED * timeStep);
+    if (input.keyDown['S'])
+        cameraNode.Translate(Vector3(0.0f, -1.0f, 0.0f) * MOVE_SPEED * timeStep);
+    if (input.keyDown['A'])
+        cameraNode.Translate(Vector3(-1.0f, 0.0f, 0.0f) * MOVE_SPEED * timeStep);
+    if (input.keyDown['D'])
+        cameraNode.Translate(Vector3(1.0f, 0.0f, 0.0f) * MOVE_SPEED * timeStep);
+
+    if (input.keyDown[KEY_PAGEUP])
+    {
+        Camera@ camera = cameraNode.GetComponent("Camera");
+        camera.zoom = camera.zoom * 1.01f;
+    }
+
+    if (input.keyDown[KEY_PAGEDOWN])
+    {
+        Camera@ camera = cameraNode.GetComponent("Camera");
+        camera.zoom = camera.zoom * 0.99f;
+    }
+}
+
+void SubscribeToEvents()
+{
+    // Subscribe HandleUpdate() function for processing update events
+    SubscribeToEvent("Update", "HandleUpdate");
+    SubscribeToEvent("MouseButtonDown", "HandleMouseButtonDown");
+
+    // Unsubscribe the SceneUpdate event from base class to prevent camera pitch and yaw in 2D sample
+    UnsubscribeFromEvent("SceneUpdate");
+}
+
+void HandleUpdate(StringHash eventType, VariantMap& eventData)
+{
+    // Take the frame time step, which is stored as a float
+    float timeStep = eventData["TimeStep"].GetFloat();
+
+    // Move the camera, scale movement with time step
+    MoveCamera(timeStep);
+}
+
+void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
+{
+    AnimatedSprite2D@ animatedSprite = spriteNode.GetComponent("AnimatedSprite2D");
+    animationIndex = (animationIndex + 1) % 7;
+    animatedSprite.animation = animationNames[animationIndex];
+}
+
+// Create XML patch instructions for screen joystick layout specific to this sample app
+String patchInstructions =
+        "<patch>" +
+        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/attribute[@name='Is Visible']\" />" +
+        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Zoom In</replace>" +
+        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]\">" +
+        "        <element type=\"Text\">" +
+        "            <attribute name=\"Name\" value=\"KeyBinding\" />" +
+        "            <attribute name=\"Text\" value=\"PAGEUP\" />" +
+        "        </element>" +
+        "    </add>" +
+        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/attribute[@name='Is Visible']\" />" +
+        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Zoom Out</replace>" +
+        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]\">" +
+        "        <element type=\"Text\">" +
+        "            <attribute name=\"Name\" value=\"KeyBinding\" />" +
+        "            <attribute name=\"Text\" value=\"PAGEDOWN\" />" +
+        "        </element>" +
+        "    </add>" +
+        "</patch>";

+ 2 - 2
Bin/Data/Scripts/Editor/AttributeEditor.as

@@ -883,8 +883,8 @@ void InitResourcePicker()
     Array<String> soundFilters = {"*.wav","*.ogg"};
     Array<String> soundFilters = {"*.wav","*.ogg"};
     Array<String> textureFilters = {"*.dds", "*.png", "*.jpg", "*.bmp", "*.tga", "*.ktx", "*.pvr"};
     Array<String> textureFilters = {"*.dds", "*.png", "*.jpg", "*.bmp", "*.tga", "*.ktx", "*.pvr"};
     Array<String> materialFilters = {"*.xml", "*.material"};
     Array<String> materialFilters = {"*.xml", "*.material"};
+    Array<String> anmSetFilters = {"*.scml"};
     Array<String> pexFilters = {"*.pex"};
     Array<String> pexFilters = {"*.pex"};
-    Array<String> anmFilters = {"*.anm"};
     resourcePickers.Push(ResourcePicker("Animation", "*.ani", ACTION_PICK | ACTION_TEST));
     resourcePickers.Push(ResourcePicker("Animation", "*.ani", ACTION_PICK | ACTION_TEST));
     resourcePickers.Push(ResourcePicker("Font", fontFilters));
     resourcePickers.Push(ResourcePicker("Font", fontFilters));
     resourcePickers.Push(ResourcePicker("Image", imageFilters));
     resourcePickers.Push(ResourcePicker("Image", imageFilters));
@@ -898,7 +898,7 @@ void InitResourcePicker()
     resourcePickers.Push(ResourcePicker("TextureCube", "*.xml"));
     resourcePickers.Push(ResourcePicker("TextureCube", "*.xml"));
     resourcePickers.Push(ResourcePicker("XMLFile", "*.xml"));
     resourcePickers.Push(ResourcePicker("XMLFile", "*.xml"));
     resourcePickers.Push(ResourcePicker("Sprite2D", textureFilters, ACTION_PICK | ACTION_OPEN));
     resourcePickers.Push(ResourcePicker("Sprite2D", textureFilters, ACTION_PICK | ACTION_OPEN));
-    resourcePickers.Push(ResourcePicker("Animation2D", anmFilters, ACTION_PICK | ACTION_OPEN));
+    resourcePickers.Push(ResourcePicker("AnimationSet2D", anmSetFilters, ACTION_PICK | ACTION_OPEN));
     resourcePickers.Push(ResourcePicker("ParticleEffect2D", pexFilters, ACTION_PICK | ACTION_OPEN));
     resourcePickers.Push(ResourcePicker("ParticleEffect2D", pexFilters, ACTION_PICK | ACTION_OPEN));
 }
 }
 
 

+ 0 - 8
Bin/Data/Urho2D/GoldIcon.anm

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<animation >
-    <frame duration="0.1" sprite="Urho2D/GoldIcon.xml@0" />
-    <frame duration="0.1" sprite="Urho2D/GoldIcon.xml@1" />
-    <frame duration="0.1" sprite="Urho2D/GoldIcon.xml@2" />
-    <frame duration="0.1" sprite="Urho2D/GoldIcon.xml@3" />
-    <frame duration="0.1" sprite="Urho2D/GoldIcon.xml@4" />
-</animation>

BIN
Bin/Data/Urho2D/GoldIcon.png


+ 57 - 0
Bin/Data/Urho2D/GoldIcon.scml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<spriter_data scml_version="1.0" generator="BrashMonkey Spriter" generator_version="b8_1">
+    <folder id="0" name="GoldIcon">
+        <file id="0" name="GoldIcon/2.png" width="64" height="64" pivot_x="0.5" pivot_y="0.5"/>
+        <file id="1" name="GoldIcon/1.png" width="64" height="64" pivot_x="0.5" pivot_y="0.5"/>
+        <file id="2" name="GoldIcon/3.png" width="17" height="60" pivot_x="0.5" pivot_y="0.5"/>
+        <file id="3" name="GoldIcon/4.png" width="64" height="64" pivot_x="0.5" pivot_y="0.5"/>
+        <file id="4" name="GoldIcon/5.png" width="64" height="64" pivot_x="0.5" pivot_y="0.5"/>
+    </folder>
+    <entity id="0" name="entity_000">
+        <animation id="0" name="idle" length="500">
+            <mainline>
+                <key id="0">
+                    <object_ref id="0" timeline="0" key="0" z_index="0"/>
+                </key>
+                <key id="1" time="99">
+                    <object_ref id="0" timeline="1" key="0" z_index="0"/>
+                </key>
+                <key id="2" time="199">
+                    <object_ref id="0" timeline="2" key="0" z_index="0"/>
+                </key>
+                <key id="3" time="300">
+                    <object_ref id="0" timeline="3" key="0" z_index="0"/>
+                </key>
+                <key id="4" time="400">
+                    <object_ref id="0" timeline="4" key="0" z_index="0"/>
+                </key>
+                <key id="5" time="500"/>
+            </mainline>
+            <timeline id="0" name="1">
+                <key id="0" spin="0">
+                    <object folder="0" file="1" angle="0"/>
+                </key>
+            </timeline>
+            <timeline id="1" name="2">
+                <key id="0" time="99" spin="0">
+                    <object folder="0" file="0" angle="0"/>
+                </key>
+            </timeline>
+            <timeline id="2" name="3">
+                <key id="0" time="199" spin="0">
+                    <object folder="0" file="2" angle="0"/>
+                </key>
+            </timeline>
+            <timeline id="3" name="4">
+                <key id="0" time="300" spin="0">
+                    <object folder="0" file="3" angle="0"/>
+                </key>
+            </timeline>
+            <timeline id="4" name="5">
+                <key id="0" time="400" spin="0">
+                    <object folder="0" file="4" angle="0"/>
+                </key>
+            </timeline>
+        </animation>
+    </entity>
+</spriter_data>

+ 0 - 10
Bin/Data/Urho2D/GoldIcon.xml

@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Created with TexturePacker http://texturepacker.com-->
-<!-- $TexturePacker:SmartUpdate:97bda036b40e92e88fe7433e328fa1b7$ -->
-<TextureAtlas imagePath="Urho2D/GoldIcon.png">
-    <SubTexture name="0" x="2" y="2" width="60" height="60"/>
-    <SubTexture name="1" x="64" y="2" width="42" height="60" frameX="-9" frameY="0" frameWidth="60" frameHeight="60"/>
-    <SubTexture name="2" x="108" y="2" width="18" height="60" frameX="-20" frameY="0" frameWidth="60" frameHeight="60"/>
-    <SubTexture name="3" x="62" y="64" width="42" height="60" frameX="-9" frameY="0" frameWidth="60" frameHeight="60"/>
-    <SubTexture name="4" x="2" y="64" width="58" height="60" frameX="-1" frameY="0" frameWidth="60" frameHeight="60"/>
-</TextureAtlas>

BIN
Bin/Data/Urho2D/GoldIcon/1.png


BIN
Bin/Data/Urho2D/GoldIcon/2.png


BIN
Bin/Data/Urho2D/GoldIcon/3.png


BIN
Bin/Data/Urho2D/GoldIcon/4.png


BIN
Bin/Data/Urho2D/GoldIcon/5.png


+ 1312 - 0
Bin/Data/Urho2D/imp/imp.scml

@@ -0,0 +1,1312 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<spriter_data scml_version="1.0" generator="BrashMonkey Spriter" generator_version="b0">
+    <folder id="0">
+        <file id="0" name="imp_head.png" width="238" height="149"/>
+    </folder>
+    <folder id="1">
+        <file id="0" name="imp_body.png" width="124" height="131"/>
+    </folder>
+    <folder id="2">
+        <file id="0" name="imp_footbig.png" width="65" height="49"/>
+    </folder>
+    <folder id="3">
+        <file id="0" name="imp_footsmall.png" width="59" height="45"/>
+    </folder>
+    <folder id="4">
+        <file id="0" name="imp_handbig.png" width="66" height="102"/>
+    </folder>
+    <folder id="5">
+        <file id="0" name="imp_handsmall.png" width="63" height="83"/>
+    </folder>
+    <folder id="6">
+        <file id="0" name="/imp_handsmall.png" width="63" height="83"/>
+        <file id="1" name="/imp_handthrow.png" width="75" height="120"/>
+        <file id="2" name="/imp_head.png" width="238" height="149"/>
+        <file id="3" name="/imp_headblink.png" width="238" height="149"/>
+        <file id="4" name="/imp_handbig.png" width="66" height="102"/>
+        <file id="5" name="/imp_blood.png" width="226" height="73"/>
+        <file id="6" name="/imp_headangry.png" width="238" height="149"/>
+    </folder>
+    <folder id="7">
+        <file id="0" name="imp_handbig.png" width="66" height="102"/>
+    </folder>
+    <folder id="8">
+        <file id="0" name="imp_handbig.png" width="66" height="102"/>
+    </folder>
+    <entity id="0" name="Imp">
+        <animation id="0" name="idle" length="1600">
+            <mainline>
+                <key id="0">
+                    <object_ref id="0" timeline="5" key="0" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="0" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="0" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="0" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="0" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="0" z_index="5"/>
+                </key>
+                <key id="1" time="490">
+                    <object_ref id="0" timeline="5" key="1" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="1" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="1" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="1" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="1" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="1" z_index="5"/>
+                </key>
+                <key id="2" time="684">
+                    <object_ref id="0" timeline="5" key="2" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="1" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="2" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="2" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="1" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="2" z_index="5"/>
+                </key>
+                <key id="3" time="1272">
+                    <object_ref id="0" timeline="5" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="1" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="3" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="1" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+            </mainline>
+            <timeline id="0" name="imp_head">
+                <key id="0" spin="-1">
+                    <object folder="0" file="0" x="166" y="-148.676667" pivot_x="0.5" pivot_y="0.176667" angle="0"/>
+                </key>
+                <key id="1" time="490" spin="-1">
+                    <object folder="0" file="0" x="167" y="-140.676667" pivot_x="0.5" pivot_y="0.176667" angle="357.485641"/>
+                </key>
+                <key id="2" time="684">
+                    <object folder="0" file="0" x="167" y="-138.676667" pivot_x="0.5" pivot_y="0.176667" angle="357.206724"/>
+                </key>
+                <key id="3" time="1272" spin="-1">
+                    <object folder="0" file="0" x="165.004082" y="-154.644014" pivot_x="0.5" pivot_y="0.176667" angle="3.11303"/>
+                </key>
+            </timeline>
+            <timeline id="1" name="imp_body">
+                <key id="0" spin="0">
+                    <object folder="1" file="0" x="165.032" y="-217.693182" pivot_x="0.468" pivot_y="0.193182" angle="0"/>
+                </key>
+                <key id="1" time="490" spin="0">
+                    <object folder="1" file="0" x="164.405024" y="-204.877454" pivot_x="0.468" pivot_y="0.193182" angle="0" scale_x="1.032" scale_y="0.973485"/>
+                </key>
+                <key id="2" time="684" spin="0">
+                    <object folder="1" file="0" x="163.835187" y="-202.877454" pivot_x="0.468" pivot_y="0.193182" angle="0" scale_x="1.0496" scale_y="0.973485"/>
+                </key>
+                <key id="3" time="1272" spin="0">
+                    <object folder="1" file="0" x="164.717696" y="-219.640873" pivot_x="0.468" pivot_y="0.193182" angle="0" scale_x="0.928" scale_y="0.999892"/>
+                </key>
+            </timeline>
+            <timeline id="2" name="imp_footbig">
+                <key id="0" spin="0">
+                    <object folder="2" file="0" x="214.840909" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+                <key id="1" time="1272" spin="0">
+                    <object folder="2" file="0" x="214.840909" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+            </timeline>
+            <timeline id="3" name="imp_footsmall">
+                <key id="0" spin="0">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+                <key id="1" time="1272" spin="0">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+            </timeline>
+            <timeline id="4" name="imp_handbig">
+                <key id="0">
+                    <object folder="4" file="0" x="245.895522" y="-202.07767" pivot_x="0.604478" pivot_y="0.57767" angle="0"/>
+                </key>
+                <key id="1" time="490" spin="0">
+                    <object folder="4" file="0" x="249.895522" y="-194.07767" pivot_x="0.604478" pivot_y="0.57767" angle="4.899282"/>
+                </key>
+                <key id="2" time="684" spin="-1">
+                    <object folder="4" file="0" x="250.895522" y="-192.07767" pivot_x="0.604478" pivot_y="0.57767" angle="4.899282"/>
+                </key>
+                <key id="3" time="1272">
+                    <object folder="4" file="0" x="243.911849" y="-205.045017" pivot_x="0.604478" pivot_y="0.57767" angle="357.904022"/>
+                </key>
+            </timeline>
+            <timeline id="5" name="imp_handsmall">
+                <key id="0" spin="-1">
+                    <object folder="5" file="0" x="98.023438" y="-201.10119" pivot_x="0.476562" pivot_y="0.60119" angle="0"/>
+                </key>
+                <key id="1" time="490" spin="0">
+                    <object folder="5" file="0" x="96.023438" y="-193.10119" pivot_x="0.476562" pivot_y="0.60119" angle="355.198451"/>
+                </key>
+                <key id="2" time="684">
+                    <object folder="5" file="0" x="95.023438" y="-191.10119" pivot_x="0.476562" pivot_y="0.60119" angle="355.198451"/>
+                </key>
+                <key id="3" time="1272" spin="-1">
+                    <object folder="5" file="0" x="100.015274" y="-204.068537" pivot_x="0.476562" pivot_y="0.60119" angle="2.577962"/>
+                </key>
+            </timeline>
+        </animation>
+        <animation id="1" name="attack" length="880" looping="false">
+            <mainline>
+                <key id="0">
+                    <object_ref id="0" timeline="5" key="0" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="0" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="0" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="0" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="0" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="0" z_index="5"/>
+                </key>
+                <key id="1" time="98">
+                    <object_ref id="0" timeline="5" key="1" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="4" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="1" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="1" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="1" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="1" z_index="5"/>
+                </key>
+                <key id="2" time="244">
+                    <object_ref id="0" timeline="5" key="2" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="1" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="2" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="2" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="2" z_index="5"/>
+                </key>
+                <key id="3" time="490">
+                    <object_ref id="0" timeline="5" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="2" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="3" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="4" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+                <key id="4" time="636">
+                    <object_ref id="0" timeline="5" key="5" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="4" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="5" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="5" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="4" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="4" z_index="5"/>
+                </key>
+                <key id="5" time="733">
+                    <object_ref id="0" timeline="5" key="4" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="4" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="4" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="3" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="5" z_index="5"/>
+                </key>
+                <key id="6" time="770">
+                    <object_ref id="0" timeline="5" key="5" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="4" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="5" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="5" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="4" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="6" z_index="5"/>
+                </key>
+                <key id="7" time="878">
+                    <object_ref id="0" timeline="5" key="5" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="4" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="5" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="5" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="4" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="7" z_index="5"/>
+                </key>
+            </mainline>
+            <timeline id="0" name="imp_head">
+                <key id="0">
+                    <object folder="6" file="6" x="166" y="-148.676667" pivot_x="0.5" pivot_y="0.176667" angle="0"/>
+                </key>
+                <key id="1" time="98">
+                    <object folder="6" file="6" x="179.487172" y="-158.311957" pivot_x="0.5" pivot_y="0.176667" angle="8.856673"/>
+                </key>
+                <key id="2" time="244" spin="-1">
+                    <object folder="6" file="6" x="179.668637" y="-161.365929" pivot_x="0.5" pivot_y="0.176667" angle="12.368404"/>
+                </key>
+                <key id="3" time="490">
+                    <object folder="6" file="6" x="238.214646" y="-149.318774" pivot_x="0.5" pivot_y="0.176667" angle="347.591476"/>
+                </key>
+                <key id="4" time="733">
+                    <object folder="6" file="6" x="117.969105" y="-170.793089" pivot_x="0.5" pivot_y="0.176667" angle="358.132363"/>
+                </key>
+                <key id="5" time="878" spin="-1">
+                    <object folder="6" file="2" x="166.222928" y="-148.835928" pivot_x="0.5" pivot_y="0.176667" angle="0.146391"/>
+                </key>
+            </timeline>
+            <timeline id="1" name="imp_body">
+                <key id="0">
+                    <object folder="1" file="0" x="165.032" y="-217.693182" pivot_x="0.468" pivot_y="0.193182" angle="0"/>
+                </key>
+                <key id="1" time="98">
+                    <object folder="1" file="0" x="181.270095" y="-221.597944" pivot_x="0.468" pivot_y="0.193182" angle="2.283714"/>
+                </key>
+                <key id="2" time="244" spin="-1">
+                    <object folder="1" file="0" x="185.313295" y="-223.506424" pivot_x="0.468" pivot_y="0.193182" angle="4.877115"/>
+                </key>
+                <key id="3" time="490">
+                    <object folder="1" file="0" x="212.932342" y="-206.363567" pivot_x="0.468" pivot_y="0.193182" angle="335.783818"/>
+                </key>
+                <key id="4" time="733" spin="-1">
+                    <object folder="1" file="0" x="133.884723" y="-231.125471" pivot_x="0.468" pivot_y="0.193182" angle="14.464689"/>
+                </key>
+                <key id="5" time="878" spin="-1">
+                    <object folder="1" file="0" x="165.300398" y="-217.757723" pivot_x="0.468" pivot_y="0.193182" angle="0.037747"/>
+                </key>
+            </timeline>
+            <timeline id="2" name="imp_footbig">
+                <key id="0" spin="0">
+                    <object folder="2" file="0" x="214.840909" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+                <key id="1" time="98">
+                    <object folder="2" file="0" x="232.936147" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+                <key id="2" time="244">
+                    <object folder="2" file="0" x="237.936147" y="-255.31" pivot_x="0.659091" pivot_y="0.81" angle="5.507584"/>
+                </key>
+                <key id="3" time="733" spin="-1">
+                    <object folder="2" file="0" x="218.888528" y="-241.976667" pivot_x="0.659091" pivot_y="0.81" angle="53.681898"/>
+                </key>
+                <key id="4" time="878" spin="0">
+                    <object folder="2" file="0" x="215.140004" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+            </timeline>
+            <timeline id="3" name="imp_footsmall">
+                <key id="0" spin="0">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+                <key id="1" time="244" spin="-1">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+                <key id="2" time="490">
+                    <object folder="3" file="0" x="146.058672" y="-223.075775" pivot_x="0.691667" pivot_y="0.836957" angle="314.876802"/>
+                </key>
+                <key id="3" time="733">
+                    <object folder="3" file="0" x="89.268209" y="-254.537948" pivot_x="0.691667" pivot_y="0.836957" angle="353.557674"/>
+                </key>
+                <key id="4" time="878" spin="0">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+            </timeline>
+            <timeline id="4" name="imp_handbig">
+                <key id="0" spin="-1">
+                    <object folder="4" file="0" x="245.895522" y="-202.07767" pivot_x="0.604478" pivot_y="0.57767" angle="0"/>
+                </key>
+                <key id="1" time="98" spin="-1">
+                    <object folder="4" file="0" x="263.351911" y="-192.296412" pivot_x="0.604478" pivot_y="0.57767" angle="338.773389"/>
+                </key>
+                <key id="2" time="244" spin="-1">
+                    <object folder="4" file="0" x="263.985208" y="-190.520871" pivot_x="0.604478" pivot_y="0.57767" angle="338.601978"/>
+                </key>
+                <key id="3" time="490" spin="-1">
+                    <object folder="6" file="4" x="400.790413" y="-182.45939" pivot_x="0.604478" pivot_y="0.57767" angle="271.287703"/>
+                </key>
+                <key id="4" time="636" spin="-1">
+                    <object folder="6" file="1" x="221.703611" y="-192.922017" pivot_x="0.604478" pivot_y="0.57767" angle="268.954221" scale_y="1.901051"/>
+                </key>
+                <key id="5" time="733">
+                    <object folder="6" file="1" x="-28.949847" y="-200.554628" pivot_x="0.604478" pivot_y="0.57767" angle="262.682559"/>
+                </key>
+                <key id="6" time="770">
+                    <object folder="8" file="0" x="41.256736" y="-200.902012" pivot_x="0.604478" pivot_y="0.57767" angle="287.425757"/>
+                </key>
+                <key id="7" time="878">
+                    <object folder="6" file="4" x="246.184058" y="-201.915996" pivot_x="0.604478" pivot_y="0.57767" angle="359.649147"/>
+                </key>
+            </timeline>
+            <timeline id="5" name="imp_handsmall">
+                <key id="0" spin="-1">
+                    <object folder="5" file="0" x="98.023438" y="-201.10119" pivot_x="0.476562" pivot_y="0.60119" angle="0"/>
+                </key>
+                <key id="1" time="98" spin="-1">
+                    <object folder="5" file="0" x="126.986933" y="-190.546416" pivot_x="0.476562" pivot_y="0.60119" angle="343.757792"/>
+                </key>
+                <key id="2" time="244" spin="-1">
+                    <object folder="5" file="0" x="129.680712" y="-193.038138" pivot_x="0.476562" pivot_y="0.60119" angle="342.211709"/>
+                </key>
+                <key id="3" time="490">
+                    <object folder="5" file="0" x="161.990806" y="-152.689085" pivot_x="0.476562" pivot_y="0.60119" angle="293.90908"/>
+                </key>
+                <key id="4" time="733">
+                    <object folder="5" file="0" x="72.953132" y="-179.157857" pivot_x="0.476562" pivot_y="0.60119" angle="303.96351"/>
+                </key>
+                <key id="5" time="878">
+                    <object folder="5" file="0" x="98.502173" y="-200.926731" pivot_x="0.476562" pivot_y="0.60119" angle="359.731534"/>
+                </key>
+            </timeline>
+        </animation>
+        <animation id="2" name="run" length="700">
+            <mainline>
+                <key id="0">
+                    <object_ref id="0" timeline="5" key="0" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="0" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="0" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="0" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="0" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="0" z_index="5"/>
+                </key>
+                <key id="1" time="36">
+                    <object_ref id="0" timeline="5" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="4" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="1" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="4" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+                <key id="2" time="195">
+                    <object_ref id="0" timeline="3" key="1" z_index="0"/>
+                    <object_ref id="1" timeline="5" key="1" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="1" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="2" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="1" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="1" z_index="5"/>
+                </key>
+                <key id="3" time="225">
+                    <object_ref id="0" timeline="3" key="2" z_index="0"/>
+                    <object_ref id="1" timeline="5" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="5" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+                <key id="4" time="344">
+                    <object_ref id="0" timeline="3" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="5" key="2" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="2" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="3" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="3" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="2" z_index="5"/>
+                </key>
+                <key id="5" time="410">
+                    <object_ref id="0" timeline="3" key="4" z_index="0"/>
+                    <object_ref id="1" timeline="5" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="4" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="4" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+                <key id="6" time="552">
+                    <object_ref id="0" timeline="3" key="4" z_index="0"/>
+                    <object_ref id="1" timeline="5" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="5" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="4" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+            </mainline>
+            <timeline id="0" name="imp_head">
+                <key id="0" spin="-1">
+                    <object folder="0" file="0" x="166" y="-148.676667" pivot_x="0.5" pivot_y="0.176667" angle="0"/>
+                </key>
+                <key id="1" time="36" spin="-1">
+                    <object folder="0" file="0" x="165.824176" y="-151.909634" pivot_x="0.5" pivot_y="0.176667" angle="359.712091"/>
+                </key>
+                <key id="2" time="195">
+                    <object folder="0" file="0" x="165.047619" y="-135.105238" pivot_x="0.5" pivot_y="0.176667" angle="358.440491"/>
+                </key>
+                <key id="3" time="344">
+                    <object folder="0" file="0" x="165.989775" y="-148.584642" pivot_x="0.5" pivot_y="0.176667" angle="0"/>
+                </key>
+                <key id="4" time="410" spin="-1">
+                    <object folder="0" file="0" x="165.774562" y="-150.647723" pivot_x="0.5" pivot_y="0.176667" angle="1.599173"/>
+                </key>
+                <key id="5" time="552">
+                    <object folder="0" file="0" x="165.057184" y="-135.191323" pivot_x="0.5" pivot_y="0.176667" angle="358.902266"/>
+                </key>
+            </timeline>
+            <timeline id="1" name="imp_body">
+                <key id="0" spin="0">
+                    <object folder="1" file="0" x="165.032" y="-217.693182" pivot_x="0.468" pivot_y="0.193182" angle="0"/>
+                </key>
+                <key id="1" time="195" spin="0">
+                    <object folder="1" file="0" x="163.567909" y="-205.121753" pivot_x="0.468" pivot_y="0.193182" angle="0" scale_x="1.020952"/>
+                </key>
+                <key id="2" time="344" spin="0">
+                    <object folder="1" file="0" x="165.021775" y="-217.601157" pivot_x="0.468" pivot_y="0.193182" angle="0"/>
+                </key>
+                <key id="3" time="552" spin="0">
+                    <object folder="1" file="0" x="163.061486" y="-203.633289" pivot_x="0.468" pivot_y="0.193182" angle="0" scale_x="1.028571" scale_y="0.966339"/>
+                </key>
+            </timeline>
+            <timeline id="2" name="imp_footbig">
+                <key id="0">
+                    <object folder="2" file="0" x="214.840909" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+                <key id="1" time="195">
+                    <object folder="2" file="0" x="247.221861" y="-224.881429" pivot_x="0.659091" pivot_y="0.81" angle="19.157468"/>
+                </key>
+                <key id="2" time="225" spin="-1">
+                    <object folder="2" file="0" x="248.398721" y="-221.627875" pivot_x="0.659091" pivot_y="0.81" angle="26.128319"/>
+                </key>
+                <key id="3" time="344" spin="-1">
+                    <object folder="2" file="0" x="201.035183" y="-256.023702" pivot_x="0.659091" pivot_y="0.81" angle="0.133403"/>
+                </key>
+                <key id="4" time="552">
+                    <object folder="2" file="0" x="139.230602" y="-231.673059" pivot_x="0.659091" pivot_y="0.81" angle="317.599415"/>
+                </key>
+            </timeline>
+            <timeline id="3" name="imp_footsmall">
+                <key id="0" spin="-1">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+                <key id="1" time="195" spin="-1">
+                    <object folder="3" file="0" x="110.95119" y="-227.384576" pivot_x="0.691667" pivot_y="0.836957" angle="328.639199"/>
+                </key>
+                <key id="2" time="225">
+                    <object folder="3" file="0" x="111.346777" y="-228.161338" pivot_x="0.691667" pivot_y="0.836957" angle="317.393841"/>
+                </key>
+                <key id="3" time="344">
+                    <object folder="3" file="0" x="150.757209" y="-250.163133" pivot_x="0.691667" pivot_y="0.836957" angle="359.753655"/>
+                </key>
+                <key id="4" time="552" spin="-1">
+                    <object folder="3" file="0" x="230.141873" y="-222.785276" pivot_x="0.691667" pivot_y="0.836957" angle="5.752919"/>
+                </key>
+            </timeline>
+            <timeline id="4" name="imp_handbig">
+                <key id="0" spin="-1">
+                    <object folder="4" file="0" x="245.895522" y="-202.07767" pivot_x="0.604478" pivot_y="0.57767" angle="0"/>
+                </key>
+                <key id="1" time="195">
+                    <object folder="4" file="0" x="178.276475" y="-192.55386" pivot_x="0.604478" pivot_y="0.57767" angle="314.993545"/>
+                </key>
+                <key id="2" time="344">
+                    <object folder="4" file="0" x="229.931457" y="-203.880183" pivot_x="0.604478" pivot_y="0.57767" angle="359.516803"/>
+                </key>
+                <key id="3" time="552" spin="-1">
+                    <object folder="4" file="0" x="261.907973" y="-172.411415" pivot_x="0.604478" pivot_y="0.57767" angle="27.593506"/>
+                </key>
+            </timeline>
+            <timeline id="5" name="imp_handsmall">
+                <key id="0">
+                    <object folder="5" file="0" x="98.023438" y="-201.10119" pivot_x="0.476562" pivot_y="0.60119" angle="0"/>
+                </key>
+                <key id="1" time="195" spin="-1">
+                    <object folder="5" file="0" x="173.261533" y="-188.720238" pivot_x="0.476562" pivot_y="0.60119" angle="17.360937"/>
+                </key>
+                <key id="2" time="344" spin="-1">
+                    <object folder="5" file="0" x="110.749407" y="-197.661519" pivot_x="0.476562" pivot_y="0.60119" angle="0.18639"/>
+                </key>
+                <key id="3" time="552">
+                    <object folder="5" file="0" x="88.487177" y="-173.988677" pivot_x="0.476562" pivot_y="0.60119" angle="316.911749"/>
+                </key>
+            </timeline>
+        </animation>
+        <animation id="3" name="hit" length="450" looping="false">
+            <mainline>
+                <key id="0">
+                    <object_ref id="0" timeline="5" key="0" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="0" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="0" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="0" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="0" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="0" z_index="5"/>
+                </key>
+                <key id="1" time="80">
+                    <object_ref id="0" timeline="5" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="1" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+                <key id="2" time="159">
+                    <object_ref id="0" timeline="5" key="1" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="1" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="1" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="2" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="1" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="1" z_index="5"/>
+                </key>
+                <key id="3" time="280">
+                    <object_ref id="0" timeline="5" key="2" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="2" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="2" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="3" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="2" z_index="5"/>
+                </key>
+                <key id="4" time="449">
+                    <object_ref id="0" timeline="5" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="4" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+            </mainline>
+            <timeline id="0" name="imp_head">
+                <key id="0">
+                    <object folder="0" file="0" x="166" y="-148.676667" pivot_x="0.5" pivot_y="0.176667" angle="0"/>
+                </key>
+                <key id="1" time="80">
+                    <object folder="6" file="3" x="175.831029" y="-154.82106" pivot_x="0.5" pivot_y="0.176667" angle="5.033717"/>
+                </key>
+                <key id="2" time="159">
+                    <object folder="6" file="3" x="188.857143" y="-162.962381" pivot_x="0.5" pivot_y="0.176667" angle="11.703393"/>
+                </key>
+                <key id="3" time="280" spin="-1">
+                    <object folder="6" file="3" x="189.271869" y="-165.042853" pivot_x="0.5" pivot_y="0.176667" angle="16.546127"/>
+                </key>
+                <key id="4" time="449" spin="-1">
+                    <object folder="6" file="3" x="166.122888" y="-148.753472" pivot_x="0.5" pivot_y="0.176667" angle="0.062921"/>
+                </key>
+            </timeline>
+            <timeline id="1" name="imp_body">
+                <key id="0">
+                    <object folder="1" file="0" x="165.032" y="-217.693182" pivot_x="0.468" pivot_y="0.193182" angle="0"/>
+                </key>
+                <key id="1" time="159">
+                    <object folder="1" file="0" x="190.219989" y="-216.187449" pivot_x="0.468" pivot_y="0.193182" angle="0.855349" scale_x="1.051429" scale_y="0.92298"/>
+                </key>
+                <key id="2" time="280" spin="-1">
+                    <object folder="1" file="0" x="195.218808" y="-217.138868" pivot_x="0.468" pivot_y="0.193182" angle="3.639904" scale_x="1.051429" scale_y="0.92298"/>
+                </key>
+                <key id="3" time="449" spin="-1">
+                    <object folder="1" file="0" x="165.190415" y="-217.683712" pivot_x="0.468" pivot_y="0.193182" angle="0.00538" scale_x="1.000323" scale_y="0.999516"/>
+                </key>
+            </timeline>
+            <timeline id="2" name="imp_footbig">
+                <key id="0" spin="-1">
+                    <object folder="2" file="0" x="214.840909" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+                <key id="1" time="159">
+                    <object folder="2" file="0" x="225.3171" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="356.212163"/>
+                </key>
+                <key id="2" time="449">
+                    <object folder="2" file="0" x="214.906797" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="359.976177"/>
+                </key>
+            </timeline>
+            <timeline id="3" name="imp_footsmall">
+                <key id="0" spin="-1">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+                <key id="1" time="159" spin="-1">
+                    <object folder="3" file="0" x="134.808333" y="-247.241718" pivot_x="0.691667" pivot_y="0.836957" angle="333.818975"/>
+                </key>
+                <key id="2" time="280">
+                    <object folder="3" file="0" x="137.903571" y="-240.479814" pivot_x="0.691667" pivot_y="0.836957" angle="324.843328"/>
+                </key>
+                <key id="3" time="449">
+                    <object folder="3" file="0" x="133.814623" y="-250.31749" pivot_x="0.691667" pivot_y="0.836957" angle="359.835339"/>
+                </key>
+            </timeline>
+            <timeline id="4" name="imp_handbig">
+                <key id="0" spin="-1">
+                    <object folder="4" file="0" x="245.895522" y="-202.07767" pivot_x="0.604478" pivot_y="0.57767" angle="0"/>
+                </key>
+                <key id="1" time="159" spin="-1">
+                    <object folder="4" file="0" x="220.725163" y="-206.085659" pivot_x="0.604478" pivot_y="0.57767" angle="307.382744"/>
+                </key>
+                <key id="2" time="280">
+                    <object folder="4" file="0" x="219.482928" y="-201.757525" pivot_x="0.604478" pivot_y="0.57767" angle="302.918468"/>
+                </key>
+                <key id="3" time="449">
+                    <object folder="4" file="0" x="245.737218" y="-202.102877" pivot_x="0.604478" pivot_y="0.57767" angle="359.669074"/>
+                </key>
+            </timeline>
+            <timeline id="5" name="imp_handsmall">
+                <key id="0" spin="-1">
+                    <object folder="5" file="0" x="98.023438" y="-201.10119" pivot_x="0.476562" pivot_y="0.60119" angle="0"/>
+                </key>
+                <key id="1" time="159">
+                    <object folder="5" file="0" x="142.123086" y="-186.595164" pivot_x="0.476562" pivot_y="0.60119" angle="311.84967"/>
+                </key>
+                <key id="2" time="280">
+                    <object folder="5" file="0" x="152.407752" y="-185.156193" pivot_x="0.476562" pivot_y="0.60119" angle="314.634226"/>
+                </key>
+                <key id="3" time="449">
+                    <object folder="5" file="0" x="98.300794" y="-201.009958" pivot_x="0.476562" pivot_y="0.60119" angle="359.697168"/>
+                </key>
+            </timeline>
+        </animation>
+        <animation id="4" name="dead3" length="1200" looping="false">
+            <mainline>
+                <key id="0">
+                    <object_ref id="0" timeline="5" key="0" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="0" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="0" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="0" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="0" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="0" z_index="5"/>
+                </key>
+                <key id="1" time="160">
+                    <object_ref id="0" timeline="5" key="1" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="1" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="1" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="1" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="1" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="1" z_index="5"/>
+                </key>
+                <key id="2" time="278">
+                    <object_ref id="0" timeline="5" key="2" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="2" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="2" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="2" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="2" z_index="5"/>
+                </key>
+                <key id="3" time="404">
+                    <object_ref id="0" timeline="5" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="3" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+                <key id="4" time="560">
+                    <object_ref id="0" timeline="5" key="4" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="4" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="4" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="4" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="4" z_index="5"/>
+                </key>
+                <key id="5" time="616">
+                    <object_ref id="0" timeline="5" key="9" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="8" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="5" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="8" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="8" z_index="5"/>
+                </key>
+                <key id="6" time="720">
+                    <object_ref id="0" timeline="5" key="5" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="5" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="6" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="5" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="5" z_index="5"/>
+                </key>
+                <key id="7" time="772">
+                    <object_ref id="0" timeline="5" key="9" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="6" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="9" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="8" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="8" z_index="5"/>
+                </key>
+                <key id="8" time="840">
+                    <object_ref id="0" timeline="5" key="6" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="7" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="7" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="6" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="6" z_index="5"/>
+                </key>
+                <key id="9" time="882">
+                    <object_ref id="0" timeline="5" key="9" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="8" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="9" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="8" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="7" z_index="5"/>
+                </key>
+                <key id="10" time="909">
+                    <object_ref id="0" timeline="5" key="7" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="8" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="9" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="8" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="8" z_index="5"/>
+                </key>
+                <key id="11" time="960">
+                    <object_ref id="0" timeline="5" key="8" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="8" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="8" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="7" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="8" z_index="5"/>
+                </key>
+                <key id="12" time="1002">
+                    <object_ref id="0" timeline="5" key="9" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="8" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="9" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="8" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="8" z_index="5"/>
+                </key>
+            </mainline>
+            <timeline id="0" name="imp_head">
+                <key id="0" spin="-1">
+                    <object folder="0" file="0" x="166" y="-148.676667" pivot_x="0.5" pivot_y="0.176667" angle="0"/>
+                </key>
+                <key id="1" time="160" spin="-1">
+                    <object folder="0" file="0" x="339.025115" y="-125.094571" pivot_x="0.5" pivot_y="0.176667" angle="319.032491"/>
+                </key>
+                <key id="2" time="278" spin="-1">
+                    <object folder="0" file="0" x="581.130378" y="-153.515624" pivot_x="0.5" pivot_y="0.176667" angle="276.157523"/>
+                </key>
+                <key id="3" time="404" spin="-1">
+                    <object folder="0" file="0" x="732.709325" y="-210.357729" pivot_x="0.5" pivot_y="0.176667" angle="247.181839"/>
+                </key>
+                <key id="4" time="560" spin="-1">
+                    <object folder="0" file="0" x="842.183009" y="-192.462992" pivot_x="0.5" pivot_y="0.176667" angle="216.837225"/>
+                </key>
+                <key id="5" time="720" spin="-1">
+                    <object folder="0" file="0" x="1027.446167" y="-198.778782" pivot_x="0.5" pivot_y="0.176667" angle="180.587844"/>
+                </key>
+                <key id="6" time="840">
+                    <object folder="0" file="0" x="1093.761957" y="-198.778782" pivot_x="0.5" pivot_y="0.176667" angle="166.544122"/>
+                </key>
+                <key id="7" time="960" spin="0">
+                    <object folder="0" file="0" x="1106.393536" y="-198.778782" pivot_x="0.5" pivot_y="0.176667" angle="174.550555"/>
+                </key>
+                <key id="8" time="1002" spin="-1">
+                    <object folder="0" file="0" x="1109.393536" y="-198.778782" pivot_x="0.5" pivot_y="0.176667" angle="174.550555"/>
+                </key>
+            </timeline>
+            <timeline id="1" name="imp_body">
+                <key id="0" spin="-1">
+                    <object folder="1" file="0" x="165.032" y="-217.693182" pivot_x="0.468" pivot_y="0.193182" angle="0"/>
+                </key>
+                <key id="1" time="160" spin="-1">
+                    <object folder="1" file="0" x="177.663579" y="-209.272129" pivot_x="0.468" pivot_y="0.193182" angle="335.555632"/>
+                </key>
+                <key id="2" time="278" spin="-1">
+                    <object folder="1" file="0" x="243.979368" y="-197.693182" pivot_x="0.468" pivot_y="0.193182" angle="315.827533"/>
+                </key>
+                <key id="3" time="404" spin="-1">
+                    <object folder="1" file="0" x="287.137263" y="-205.061603" pivot_x="0.468" pivot_y="0.193182" angle="298.51399"/>
+                </key>
+                <key id="4" time="560" spin="-1">
+                    <object folder="1" file="0" x="347.137263" y="-245.061603" pivot_x="0.468" pivot_y="0.193182" angle="267.772522"/>
+                </key>
+                <key id="5" time="616" spin="-1">
+                    <object folder="1" file="0" x="380.295158" y="-225.377392" pivot_x="0.468" pivot_y="0.193182" angle="257.541367"/>
+                </key>
+                <key id="6" time="720" spin="-1">
+                    <object folder="1" file="0" x="441.874105" y="-234.535287" pivot_x="0.468" pivot_y="0.193182" angle="238.540649"/>
+                </key>
+                <key id="7" time="840" spin="-1">
+                    <object folder="1" file="0" x="492.400421" y="-231.377392" pivot_x="0.468" pivot_y="0.193182" angle="232.540824"/>
+                </key>
+                <key id="8" time="960">
+                    <object folder="1" file="0" x="520.821474" y="-229.272129" pivot_x="0.468" pivot_y="0.193182" angle="230.408094"/>
+                </key>
+                <key id="9" time="1002">
+                    <object folder="1" file="0" x="524.821474" y="-231.272129" pivot_x="0.468" pivot_y="0.193182" angle="237.618282"/>
+                </key>
+            </timeline>
+            <timeline id="2" name="imp_footbig">
+                <key id="0" spin="-1">
+                    <object folder="2" file="0" x="214.840909" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+                <key id="1" time="160" spin="0">
+                    <object folder="2" file="0" x="215.432787" y="-259.726792" pivot_x="0.659091" pivot_y="0.81" angle="344.604088"/>
+                </key>
+                <key id="2" time="404">
+                    <object folder="2" file="0" x="212.274893" y="-259.726792" pivot_x="0.659091" pivot_y="0.81" angle="344.604088"/>
+                </key>
+            </timeline>
+            <timeline id="3" name="imp_footsmall">
+                <key id="0" spin="-1">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+                <key id="1" time="160" spin="-1">
+                    <object folder="3" file="0" x="105.209675" y="-213.507605" pivot_x="0.691667" pivot_y="0.836957" angle="328.892047"/>
+                </key>
+                <key id="2" time="278" spin="-1">
+                    <object folder="3" file="0" x="27.314938" y="-199.823394" pivot_x="0.691667" pivot_y="0.836957" angle="300.532734"/>
+                </key>
+                <key id="3" time="404" spin="-1">
+                    <object folder="3" file="0" x="-37.94822" y="-192.454973" pivot_x="0.691667" pivot_y="0.836957" angle="258.793005"/>
+                </key>
+                <key id="4" time="560" spin="-1">
+                    <object folder="3" file="0" x="-174.790325" y="-233.507605" pivot_x="0.691667" pivot_y="0.836957" angle="215.98011"/>
+                </key>
+                <key id="5" time="720" spin="-1">
+                    <object folder="3" file="0" x="-281.106115" y="-288.244447" pivot_x="0.691667" pivot_y="0.836957" angle="183.982757"/>
+                </key>
+                <key id="6" time="772" spin="-1">
+                    <object folder="3" file="0" x="-327.63243" y="-280.911114" pivot_x="0.691667" pivot_y="0.836957" angle="181.327982"/>
+                </key>
+                <key id="7" time="840" spin="-1">
+                    <object folder="3" file="0" x="-388.474536" y="-295.612868" pivot_x="0.691667" pivot_y="0.836957" angle="177.856354"/>
+                </key>
+                <key id="8" time="960" spin="-1">
+                    <object folder="3" file="0" x="-459.000851" y="-293.507605" pivot_x="0.691667" pivot_y="0.836957" angle="160.089084"/>
+                </key>
+            </timeline>
+            <timeline id="4" name="imp_handbig">
+                <key id="0" spin="-1">
+                    <object folder="4" file="0" x="245.895522" y="-202.07767" pivot_x="0.604478" pivot_y="0.57767" angle="0"/>
+                </key>
+                <key id="1" time="160" spin="-1">
+                    <object folder="4" file="0" x="253.455192" y="-99.895756" pivot_x="0.604478" pivot_y="0.57767" angle="317.669984"/>
+                </key>
+                <key id="2" time="278" spin="-1">
+                    <object folder="4" file="0" x="245.03414" y="23.262138" pivot_x="0.604478" pivot_y="0.57767" angle="255.568253"/>
+                </key>
+                <key id="3" time="404" spin="-1">
+                    <object folder="4" file="0" x="252.402561" y="45.367402" pivot_x="0.604478" pivot_y="0.57767" angle="230.799573"/>
+                </key>
+                <key id="4" time="560" spin="-1">
+                    <object folder="4" file="0" x="256.613087" y="-35.68523" pivot_x="0.604478" pivot_y="0.57767" angle="204.307629"/>
+                </key>
+                <key id="5" time="720" spin="-1">
+                    <object folder="4" file="0" x="266.086771" y="-187.264177" pivot_x="0.604478" pivot_y="0.57767" angle="177.836299"/>
+                </key>
+                <key id="6" time="840" spin="-1">
+                    <object folder="4" file="0" x="262.928877" y="-259.895756" pivot_x="0.604478" pivot_y="0.57767" angle="124.074582"/>
+                </key>
+                <key id="7" time="882" spin="-1">
+                    <object folder="4" file="0" x="262.928877" y="-251.895756" pivot_x="0.604478" pivot_y="0.57767" angle="118.248752"/>
+                </key>
+                <key id="8" time="960" spin="-1">
+                    <object folder="4" file="0" x="262.928877" y="-264.106283" pivot_x="0.604478" pivot_y="0.57767" angle="107.429353"/>
+                </key>
+            </timeline>
+            <timeline id="5" name="imp_handsmall">
+                <key id="0" spin="-1">
+                    <object folder="5" file="0" x="98.023438" y="-201.10119" pivot_x="0.476562" pivot_y="0.60119" angle="0"/>
+                </key>
+                <key id="1" time="160" spin="-1">
+                    <object folder="5" file="0" x="110.096204" y="-134.432997" pivot_x="0.476562" pivot_y="0.60119" angle="313.188743"/>
+                </key>
+                <key id="2" time="278" spin="-1">
+                    <object folder="5" file="0" x="96.411994" y="-83.906681" pivot_x="0.476562" pivot_y="0.60119" angle="287.682713"/>
+                </key>
+                <key id="3" time="404" spin="-1">
+                    <object folder="5" file="0" x="101.675152" y="-56.53826" pivot_x="0.476562" pivot_y="0.60119" angle="263.83577"/>
+                </key>
+                <key id="4" time="560" spin="-1">
+                    <object folder="5" file="0" x="97.464626" y="-24.959313" pivot_x="0.476562" pivot_y="0.60119" angle="239.161373"/>
+                </key>
+                <key id="5" time="720" spin="-1">
+                    <object folder="5" file="0" x="97.464626" y="-54.643523" pivot_x="0.476562" pivot_y="0.60119" angle="228.394486"/>
+                </key>
+                <key id="6" time="840">
+                    <object folder="5" file="0" x="96.411994" y="-189.380365" pivot_x="0.476562" pivot_y="0.60119" angle="215.59603"/>
+                </key>
+                <key id="7" time="909">
+                    <object folder="5" file="0" x="97.017257" y="-264.687383" pivot_x="0.476562" pivot_y="0.60119" angle="247.96995"/>
+                </key>
+                <key id="8" time="960">
+                    <object folder="5" file="0" x="96.131292" y="-248.450541" pivot_x="0.476562" pivot_y="0.60119" angle="247.97827"/>
+                </key>
+                <key id="9" time="1002">
+                    <object folder="5" file="0" x="96.131292" y="-264.117207" pivot_x="0.476562" pivot_y="0.60119" angle="254.822305"/>
+                </key>
+            </timeline>
+        </animation>
+        <animation id="5" name="dead2" length="1800" looping="false">
+            <mainline>
+                <key id="0">
+                    <object_ref id="0" timeline="5" key="0" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="0" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="0" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="0" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="0" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="0" z_index="5"/>
+                </key>
+                <key id="1" time="158">
+                    <object_ref id="0" timeline="5" key="1" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="6" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="1" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="1" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="1" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="1" z_index="5"/>
+                </key>
+                <key id="2" time="319">
+                    <object_ref id="0" timeline="5" key="2" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="1" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="2" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="2" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="2" z_index="5"/>
+                </key>
+                <key id="3" time="440">
+                    <object_ref id="0" timeline="5" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="2" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="3" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="3" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+                <key id="4" time="519">
+                    <object_ref id="0" timeline="5" key="4" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="4" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="4" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="4" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="4" z_index="5"/>
+                </key>
+                <key id="5" time="561">
+                    <object_ref id="0" timeline="5" key="5" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="4" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="5" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="5" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="5" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="5" z_index="5"/>
+                </key>
+                <key id="6" time="598">
+                    <object_ref id="0" timeline="6" key="0" z_index="0"/>
+                    <object_ref id="1" timeline="5" key="6" z_index="1"/>
+                    <object_ref id="2" timeline="3" key="5" z_index="2"/>
+                    <object_ref id="3" timeline="1" key="6" z_index="3"/>
+                    <object_ref id="4" timeline="0" key="6" z_index="4"/>
+                    <object_ref id="5" timeline="2" key="6" z_index="5"/>
+                    <object_ref id="6" timeline="4" key="6" z_index="6"/>
+                </key>
+                <key id="7" time="1800">
+                    <object_ref id="0" timeline="6" key="1" z_index="0"/>
+                    <object_ref id="1" timeline="5" key="7" z_index="1"/>
+                    <object_ref id="2" timeline="3" key="6" z_index="2"/>
+                    <object_ref id="3" timeline="1" key="7" z_index="3"/>
+                    <object_ref id="4" timeline="0" key="7" z_index="4"/>
+                    <object_ref id="5" timeline="2" key="7" z_index="5"/>
+                    <object_ref id="6" timeline="4" key="7" z_index="6"/>
+                </key>
+            </mainline>
+            <timeline id="0" name="imp_head">
+                <key id="0">
+                    <object folder="6" file="3" x="166" y="-148.676667" pivot_x="0.5" pivot_y="0.176667" angle="0"/>
+                </key>
+                <key id="1" time="158">
+                    <object folder="6" file="3" x="116.911268" y="-143.233997" pivot_x="0.5" pivot_y="0.176667" angle="14.586258"/>
+                </key>
+                <key id="2" time="319">
+                    <object folder="6" file="3" x="99.459675" y="-156.268268" pivot_x="0.5" pivot_y="0.176667" angle="33.582941"/>
+                </key>
+                <key id="3" time="440" spin="-1">
+                    <object folder="6" file="3" x="82.589706" y="-188.142944" pivot_x="0.5" pivot_y="0.176667" angle="65.294618"/>
+                </key>
+                <key id="4" time="519">
+                    <object folder="6" file="3" x="80.162949" y="-237.709813" pivot_x="0.5" pivot_y="0.176667" angle="64.526316"/>
+                </key>
+                <key id="5" time="561" spin="-1">
+                    <object folder="6" file="3" x="80.162949" y="-229.709813" pivot_x="0.5" pivot_y="0.176667" angle="68.826374"/>
+                </key>
+                <key id="6" time="598" spin="0">
+                    <object folder="6" file="3" x="80.162949" y="-238.519337" pivot_x="0.5" pivot_y="0.176667" angle="64.628698"/>
+                </key>
+                <key id="7" time="1800" spin="-1">
+                    <object folder="6" file="3" x="80.162949" y="-238.519337" pivot_x="0.5" pivot_y="0.176667" angle="64.628698"/>
+                </key>
+            </timeline>
+            <timeline id="1" name="imp_body">
+                <key id="0">
+                    <object folder="1" file="0" x="165.032" y="-217.693182" pivot_x="0.468" pivot_y="0.193182" angle="0"/>
+                </key>
+                <key id="1" time="158">
+                    <object folder="1" file="0" x="147.137263" y="-201.903708" pivot_x="0.468" pivot_y="0.193182" angle="22.945875"/>
+                </key>
+                <key id="2" time="319">
+                    <object folder="1" file="0" x="147.137263" y="-201.903708" pivot_x="0.468" pivot_y="0.193182" angle="41.942559"/>
+                </key>
+                <key id="3" time="440">
+                    <object folder="1" file="0" x="147.137263" y="-201.903708" pivot_x="0.468" pivot_y="0.193182" angle="73.654235"/>
+                </key>
+                <key id="4" time="519" spin="-1">
+                    <object folder="1" file="0" x="146.084632" y="-234.535287" pivot_x="0.468" pivot_y="0.193182" angle="88.445852"/>
+                </key>
+                <key id="5" time="561">
+                    <object folder="1" file="0" x="146.084632" y="-227.535287" pivot_x="0.468" pivot_y="0.193182" angle="82.042376"/>
+                </key>
+                <key id="6" time="598" spin="0">
+                    <object folder="1" file="0" x="146.084632" y="-235.36862" pivot_x="0.468" pivot_y="0.193182" angle="88.293389"/>
+                </key>
+                <key id="7" time="1800" spin="-1">
+                    <object folder="1" file="0" x="146.084632" y="-235.36862" pivot_x="0.468" pivot_y="0.193182" angle="88.293389"/>
+                </key>
+            </timeline>
+            <timeline id="2" name="imp_footbig">
+                <key id="0">
+                    <object folder="2" file="0" x="214.840909" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+                <key id="1" time="158">
+                    <object folder="2" file="0" x="223.261962" y="-217.362632" pivot_x="0.659091" pivot_y="0.81" angle="58.843067"/>
+                </key>
+                <key id="2" time="319">
+                    <object folder="2" file="0" x="226.419856" y="-199.467895" pivot_x="0.659091" pivot_y="0.81" angle="70.871161"/>
+                </key>
+                <key id="3" time="440">
+                    <object folder="2" file="0" x="207.472488" y="-168.941579" pivot_x="0.659091" pivot_y="0.81" angle="90.127307"/>
+                </key>
+                <key id="4" time="519" spin="-1">
+                    <object folder="2" file="0" x="163.261962" y="-180.520526" pivot_x="0.659091" pivot_y="0.81" angle="105.197785"/>
+                </key>
+                <key id="5" time="561" spin="-1">
+                    <object folder="2" file="0" x="163.261962" y="-182.520526" pivot_x="0.659091" pivot_y="0.81" angle="88.720452"/>
+                </key>
+                <key id="6" time="598" spin="0">
+                    <object folder="2" file="0" x="164.314593" y="-202.620777" pivot_x="0.659091" pivot_y="0.81" angle="87.311735"/>
+                </key>
+                <key id="7" time="1800" spin="-1">
+                    <object folder="2" file="0" x="164.314593" y="-202.620777" pivot_x="0.659091" pivot_y="0.81" angle="87.311735"/>
+                </key>
+            </timeline>
+            <timeline id="3" name="imp_footsmall">
+                <key id="0" spin="0">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+                <key id="1" time="319">
+                    <object folder="3" file="0" x="159.071491" y="-249.284325" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+                <key id="2" time="440">
+                    <object folder="3" file="0" x="193.808333" y="-245.073799" pivot_x="0.691667" pivot_y="0.836957" angle="36.764567"/>
+                </key>
+                <key id="3" time="519" spin="-1">
+                    <object folder="3" file="0" x="175.913596" y="-255.600114" pivot_x="0.691667" pivot_y="0.836957" angle="91.900705"/>
+                </key>
+                <key id="4" time="561">
+                    <object folder="3" file="0" x="171.913596" y="-257.600114" pivot_x="0.691667" pivot_y="0.836957" angle="86.403333"/>
+                </key>
+                <key id="5" time="598" spin="0">
+                    <object folder="3" file="0" x="171.607832" y="-258.752997" pivot_x="0.691667" pivot_y="0.836957" angle="95.775992"/>
+                </key>
+                <key id="6" time="1800" spin="-1">
+                    <object folder="3" file="0" x="171.607832" y="-258.752997" pivot_x="0.691667" pivot_y="0.836957" angle="95.775992"/>
+                </key>
+            </timeline>
+            <timeline id="4" name="imp_handbig">
+                <key id="0" spin="-1">
+                    <object folder="4" file="0" x="245.895522" y="-202.07767" pivot_x="0.604478" pivot_y="0.57767" angle="0"/>
+                </key>
+                <key id="1" time="158" spin="-1">
+                    <object folder="4" file="0" x="187.093404" y="-166.524546" pivot_x="0.604478" pivot_y="0.57767" angle="302.023838"/>
+                </key>
+                <key id="2" time="319">
+                    <object folder="4" file="0" x="147.085108" y="-192.287232" pivot_x="0.604478" pivot_y="0.57767" angle="293.630445"/>
+                </key>
+                <key id="3" time="440">
+                    <object folder="4" file="0" x="143.090673" y="-207.434559" pivot_x="0.604478" pivot_y="0.57767" angle="310.897396"/>
+                </key>
+                <key id="4" time="519" spin="0">
+                    <object folder="4" file="0" x="143.584193" y="-249.915961" pivot_x="0.604478" pivot_y="0.57767" angle="325.689014"/>
+                </key>
+                <key id="5" time="561" spin="0">
+                    <object folder="4" file="0" x="143.584193" y="-242.915961" pivot_x="0.604478" pivot_y="0.57767" angle="325.689014"/>
+                </key>
+                <key id="6" time="598" spin="0">
+                    <object folder="4" file="0" x="143.584193" y="-250.749295" pivot_x="0.604478" pivot_y="0.57767" angle="325.689014"/>
+                </key>
+                <key id="7" time="1800">
+                    <object folder="4" file="0" x="143.584193" y="-250.749295" pivot_x="0.604478" pivot_y="0.57767" angle="325.689014"/>
+                </key>
+            </timeline>
+            <timeline id="5" name="imp_handsmall">
+                <key id="0" spin="-1">
+                    <object folder="5" file="0" x="98.023438" y="-201.10119" pivot_x="0.476562" pivot_y="0.60119" angle="0"/>
+                </key>
+                <key id="1" time="158" spin="-1">
+                    <object folder="5" file="0" x="93.699116" y="-176.95916" pivot_x="0.476562" pivot_y="0.60119" angle="317.248585"/>
+                </key>
+                <key id="2" time="319">
+                    <object folder="5" file="0" x="42.17392" y="-174.659907" pivot_x="0.476562" pivot_y="0.60119" angle="250.684687"/>
+                </key>
+                <key id="3" time="440">
+                    <object folder="5" file="0" x="15.102906" y="-224.427072" pivot_x="0.476562" pivot_y="0.60119" angle="252.482809"/>
+                </key>
+                <key id="4" time="519" spin="0">
+                    <object folder="5" file="0" x="-14.771263" y="-255.284342" pivot_x="0.476562" pivot_y="0.60119" angle="267.274427"/>
+                </key>
+                <key id="5" time="561" spin="0">
+                    <object folder="5" file="0" x="-12.771263" y="-256.284342" pivot_x="0.476562" pivot_y="0.60119" angle="267.274427"/>
+                </key>
+                <key id="6" time="598" spin="0">
+                    <object folder="5" file="0" x="-14.723644" y="-256.308151" pivot_x="0.476562" pivot_y="0.60119" angle="267.274427"/>
+                </key>
+                <key id="7" time="1800">
+                    <object folder="5" file="0" x="-14.723644" y="-256.308151" pivot_x="0.476562" pivot_y="0.60119" angle="267.274427"/>
+                </key>
+            </timeline>
+            <timeline id="6" name="imp_blood_000">
+                <key id="0" time="598" spin="0">
+                    <object folder="6" file="5" x="-14.345003" y="-247.028272" angle="0" scale_x="0.783677" scale_y="0.319701"/>
+                </key>
+                <key id="1" time="1800" spin="0">
+                    <object folder="6" file="5" x="-30.526316" y="-247.368421" angle="0"/>
+                </key>
+            </timeline>
+        </animation>
+        <animation id="6" name="dead" length="1400" looping="false">
+            <mainline>
+                <key id="0">
+                    <object_ref id="0" timeline="5" key="0" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="0" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="0" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="0" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="0" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="0" z_index="5"/>
+                </key>
+                <key id="1" time="140">
+                    <object_ref id="0" timeline="5" key="1" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="1" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="1" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="1" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="1" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="1" z_index="5"/>
+                </key>
+                <key id="2" time="217">
+                    <object_ref id="0" timeline="5" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="2" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="5" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="2" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="2" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="5" z_index="5"/>
+                </key>
+                <key id="3" time="299">
+                    <object_ref id="0" timeline="5" key="2" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="2" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="3" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="3" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="2" z_index="5"/>
+                </key>
+                <key id="4" time="421">
+                    <object_ref id="0" timeline="5" key="3" z_index="0"/>
+                    <object_ref id="1" timeline="3" key="4" z_index="1"/>
+                    <object_ref id="2" timeline="1" key="3" z_index="2"/>
+                    <object_ref id="3" timeline="0" key="4" z_index="3"/>
+                    <object_ref id="4" timeline="2" key="4" z_index="4"/>
+                    <object_ref id="5" timeline="4" key="3" z_index="5"/>
+                </key>
+                <key id="5" time="606">
+                    <object_ref id="0" timeline="6" key="0" z_index="0"/>
+                    <object_ref id="1" timeline="5" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="3" key="5" z_index="2"/>
+                    <object_ref id="3" timeline="1" key="4" z_index="3"/>
+                    <object_ref id="4" timeline="0" key="5" z_index="4"/>
+                    <object_ref id="5" timeline="2" key="5" z_index="5"/>
+                    <object_ref id="6" timeline="4" key="4" z_index="6"/>
+                </key>
+                <key id="6" time="1398">
+                    <object_ref id="0" timeline="6" key="1" z_index="0"/>
+                    <object_ref id="1" timeline="5" key="3" z_index="1"/>
+                    <object_ref id="2" timeline="3" key="6" z_index="2"/>
+                    <object_ref id="3" timeline="1" key="5" z_index="3"/>
+                    <object_ref id="4" timeline="0" key="6" z_index="4"/>
+                    <object_ref id="5" timeline="2" key="6" z_index="5"/>
+                    <object_ref id="6" timeline="4" key="5" z_index="6"/>
+                </key>
+            </mainline>
+            <timeline id="0" name="imp_head">
+                <key id="0" spin="-1">
+                    <object folder="0" file="0" x="166" y="-148.676667" pivot_x="0.5" pivot_y="0.176667" angle="0"/>
+                </key>
+                <key id="1" time="140" spin="-1">
+                    <object folder="6" file="3" x="251.926053" y="-141.582135" pivot_x="0.5" pivot_y="0.176667" angle="319.199339"/>
+                </key>
+                <key id="2" time="217" spin="-1">
+                    <object folder="6" file="3" x="264.616667" y="-170.025503" pivot_x="0.5" pivot_y="0.176667" angle="286.008631"/>
+                </key>
+                <key id="3" time="299">
+                    <object folder="6" file="3" x="266.221121" y="-193.423659" pivot_x="0.5" pivot_y="0.176667" angle="253.53946"/>
+                </key>
+                <key id="4" time="421">
+                    <object folder="6" file="3" x="266.221121" y="-193.423659" pivot_x="0.5" pivot_y="0.176667" angle="257.588275"/>
+                </key>
+                <key id="5" time="606" spin="0">
+                    <object folder="6" file="3" x="266.221121" y="-193.423659" pivot_x="0.5" pivot_y="0.176667" angle="261.996093"/>
+                </key>
+                <key id="6" time="1398">
+                    <object folder="6" file="3" x="266.221121" y="-193.423659" pivot_x="0.5" pivot_y="0.176667" angle="261.996093"/>
+                </key>
+            </timeline>
+            <timeline id="1" name="imp_body">
+                <key id="0" spin="-1">
+                    <object folder="1" file="0" x="165.032" y="-217.693182" pivot_x="0.468" pivot_y="0.193182" angle="0"/>
+                </key>
+                <key id="1" time="140" spin="-1">
+                    <object folder="1" file="0" x="211.395636" y="-189.511364" pivot_x="0.468" pivot_y="0.193182" angle="313.742703"/>
+                </key>
+                <key id="2" time="299" spin="-1">
+                    <object folder="1" file="0" x="241.644438" y="-112.79773" pivot_x="0.468" pivot_y="0.193182" angle="209.594434"/>
+                </key>
+                <key id="3" time="421">
+                    <object folder="1" file="0" x="238.008075" y="-103.706821" pivot_x="0.468" pivot_y="0.193182" angle="197.453725"/>
+                </key>
+                <key id="4" time="606" spin="0">
+                    <object folder="1" file="0" x="192.553529" y="-182.79773" pivot_x="0.468" pivot_y="0.193182" angle="258.931108"/>
+                </key>
+                <key id="5" time="1398">
+                    <object folder="1" file="0" x="192.553529" y="-182.79773" pivot_x="0.468" pivot_y="0.193182" angle="258.931108"/>
+                </key>
+            </timeline>
+            <timeline id="2" name="imp_footbig">
+                <key id="0" spin="-1">
+                    <object folder="2" file="0" x="214.840909" y="-256.31" pivot_x="0.659091" pivot_y="0.81" angle="0"/>
+                </key>
+                <key id="1" time="140" spin="-1">
+                    <object folder="2" file="0" x="190.663039" y="-242.196392" pivot_x="0.659091" pivot_y="0.81" angle="343.109859"/>
+                </key>
+                <key id="2" time="217" spin="-1">
+                    <object folder="2" file="0" x="178.100028" y="-199.11873" pivot_x="0.659091" pivot_y="0.81" angle="286.75212"/>
+                </key>
+                <key id="3" time="299" spin="-1">
+                    <object folder="2" file="0" x="225.138189" y="-93.202835" pivot_x="0.659091" pivot_y="0.81" angle="231.619548"/>
+                </key>
+                <key id="4" time="421">
+                    <object folder="2" file="0" x="246.04728" y="-85.930108" pivot_x="0.659091" pivot_y="0.81" angle="212.44877"/>
+                </key>
+                <key id="5" time="606" spin="0">
+                    <object folder="2" file="0" x="142.410916" y="-229.566472" pivot_x="0.659091" pivot_y="0.81" angle="312.995448"/>
+                </key>
+                <key id="6" time="1398">
+                    <object folder="2" file="0" x="142.410916" y="-229.566472" pivot_x="0.659091" pivot_y="0.81" angle="312.995448"/>
+                </key>
+            </timeline>
+            <timeline id="3" name="imp_footsmall">
+                <key id="0" spin="-1">
+                    <object folder="3" file="0" x="133.808333" y="-250.336957" pivot_x="0.691667" pivot_y="0.836957" angle="0"/>
+                </key>
+                <key id="1" time="140" spin="-1">
+                    <object folder="3" file="0" x="156.223375" y="-172.251628" pivot_x="0.691667" pivot_y="0.836957" angle="322.603043"/>
+                </key>
+                <key id="2" time="217" spin="-1">
+                    <object folder="3" file="0" x="197.093408" y="-132.039673" pivot_x="0.691667" pivot_y="0.836957" angle="261.921073"/>
+                </key>
+                <key id="3" time="299" spin="-1">
+                    <object folder="3" file="0" x="294.604607" y="-77.484499" pivot_x="0.691667" pivot_y="0.836957" angle="202.558277"/>
+                </key>
+                <key id="4" time="421">
+                    <object folder="3" file="0" x="308.24097" y="-98.39359" pivot_x="0.691667" pivot_y="0.836957" angle="175.900857"/>
+                </key>
+                <key id="5" time="606" spin="0">
+                    <object folder="3" file="0" x="167.33188" y="-179.302681" pivot_x="0.691667" pivot_y="0.836957" angle="295.845827"/>
+                </key>
+                <key id="6" time="1398">
+                    <object folder="3" file="0" x="167.33188" y="-179.302681" pivot_x="0.691667" pivot_y="0.836957" angle="295.845827"/>
+                </key>
+            </timeline>
+            <timeline id="4" name="imp_handbig">
+                <key id="0" spin="-1">
+                    <object folder="4" file="0" x="245.895522" y="-202.07767" pivot_x="0.604478" pivot_y="0.57767" angle="0"/>
+                </key>
+                <key id="1" time="140" spin="-1">
+                    <object folder="4" file="0" x="244.042382" y="-210.770849" pivot_x="0.604478" pivot_y="0.57767" angle="279.048256"/>
+                </key>
+                <key id="2" time="299">
+                    <object folder="4" file="0" x="195.735668" y="-211.364697" pivot_x="0.604478" pivot_y="0.57767" angle="252.400005"/>
+                </key>
+                <key id="3" time="421" spin="-1">
+                    <object folder="4" file="0" x="195.735668" y="-220.455606" pivot_x="0.604478" pivot_y="0.57767" angle="278.365591"/>
+                </key>
+                <key id="4" time="606" spin="0">
+                    <object folder="4" file="0" x="194.826577" y="-236.819242" pivot_x="0.604478" pivot_y="0.57767" angle="272.87931"/>
+                </key>
+                <key id="5" time="1398">
+                    <object folder="4" file="0" x="194.826577" y="-236.819242" pivot_x="0.604478" pivot_y="0.57767" angle="272.87931"/>
+                </key>
+            </timeline>
+            <timeline id="5" name="imp_handsmall">
+                <key id="0" spin="-1">
+                    <object folder="5" file="0" x="98.023438" y="-201.10119" pivot_x="0.476562" pivot_y="0.60119" angle="0"/>
+                </key>
+                <key id="1" time="140" spin="-1">
+                    <object folder="5" file="0" x="177.051423" y="-115.083385" pivot_x="0.476562" pivot_y="0.60119" angle="271.994889"/>
+                </key>
+                <key id="2" time="299" spin="0">
+                    <object folder="5" file="0" x="359.516591" y="-177.042584" pivot_x="0.476562" pivot_y="0.60119" angle="104.51498"/>
+                </key>
+                <key id="3" time="1398" spin="-1">
+                    <object folder="5" file="0" x="359.516591" y="-177.042584" pivot_x="0.476562" pivot_y="0.60119" angle="104.51498"/>
+                </key>
+            </timeline>
+            <timeline id="6" name="imp_blood">
+                <key id="0" time="606" spin="0">
+                    <object folder="6" file="5" x="170.402483" y="-229.511364" angle="0" scale_x="0.804966" scale_y="0.204545"/>
+                </key>
+                <key id="1" time="1398" spin="0">
+                    <object folder="6" file="5" x="151.818182" y="-230.909091" angle="0"/>
+                </key>
+            </timeline>
+        </animation>
+    </entity>
+</spriter_data>

BIN
Bin/Data/Urho2D/imp/imp_blood.png


BIN
Bin/Data/Urho2D/imp/imp_body.png


BIN
Bin/Data/Urho2D/imp/imp_footbig.png


BIN
Bin/Data/Urho2D/imp/imp_footsmall.png


BIN
Bin/Data/Urho2D/imp/imp_handbig.png


BIN
Bin/Data/Urho2D/imp/imp_handsmall.png


BIN
Bin/Data/Urho2D/imp/imp_handthrow.png


BIN
Bin/Data/Urho2D/imp/imp_head.png


BIN
Bin/Data/Urho2D/imp/imp_headangry.png


BIN
Bin/Data/Urho2D/imp/imp_headblink.png


+ 17 - 14
Source/Engine/LuaScript/pkgs/Urho2D/AnimatedSprite2D.pkg

@@ -1,23 +1,26 @@
 $#include "AnimatedSprite2D.h"
 $#include "AnimatedSprite2D.h"
 
 
-enum CycleMode
-{
-    CM_LOOP = 0,
-    CM_CLAMP,
-    CM_PINGPONG,
-};
-
-class AnimatedSprite2D : public StaticSprite2D
+class AnimatedSprite2D : Drawable
 {
 {
+    void SetLayer(int layer);
+    void SetOrderInLayer(int orderInLayer);
+    void SetBlendMode(BlendMode mode);
     void SetSpeed(float speed);
     void SetSpeed(float speed);
-    void SetCycleMode(CycleMode cycleMode);
-    void SetAnimation(Animation2D* animation);
+    void SetAnimation(const String name);
+    void SetAnimation(AnimationSet2D* animationSet, const String name);
+    void SetAnimationSet(AnimationSet2D* animationSet);
 
 
+    int GetLayer() const;
+    int GetOrderInLayer() const;
+    BlendMode GetBlendMode() const;
     float GetSpeed() const;
     float GetSpeed() const;
-    CycleMode GetCycleMode() const;
-    Animation2D* GetAnimation() const;
+    AnimationSet2D* GetAnimationSet() const;
+    const String GetAnimation() const;
 
 
+    tolua_property__get_set int layer;
+    tolua_property__get_set int orderInLayer;
+    tolua_property__get_set BlendMode blendMode;
     tolua_property__get_set float speed;
     tolua_property__get_set float speed;
-    tolua_property__get_set CycleMode cycleMode;
-    tolua_property__get_set Animation2D* animation;
+    tolua_property__get_set AnimationSet2D* animationSet;
+    tolua_property__get_set String animation;
 };
 };

+ 12 - 12
Source/Engine/LuaScript/pkgs/Urho2D/Animation2D.pkg

@@ -1,12 +1,12 @@
-$#include "Animation2D.h"
-
-class Animation2D : public Resource
-{
-    float GetTotalTime() const;
-    unsigned GetNumFrames() const;
-    Sprite2D* GetFrameSprite(unsigned index) const;
-    Sprite2D* GetFrameSpriteByTime(float time) const;
-    
-    tolua_readonly tolua_property__get_set float totalTime;
-    tolua_readonly tolua_property__get_set unsigned numFrames;
-};
+$#include "Animation2D.h"
+
+class Animation2D : RefCounted
+{
+    const String GetName() const;
+    float GetLength() const;
+    bool IsLooped() const;
+
+    tolua_readonly tolua_property__get_set String name;
+    tolua_readonly tolua_property__get_set float length;
+    tolua_readonly tolua_property__is_set bool looped;
+};

+ 10 - 0
Source/Engine/LuaScript/pkgs/Urho2D/AnimationSet2D.pkg

@@ -0,0 +1,10 @@
+$#include "AnimationSet2D.h"
+
+class AnimationSet2D : Resource
+{
+    unsigned GetNumAnimations() const;
+    Animation2D* GetAnimation(unsigned index) const;
+    Animation2D* GetAnimation(const String name) const;
+
+    tolua_readonly tolua_property__get_set unsigned numAnimations;
+};

+ 3 - 0
Source/Engine/LuaScript/pkgs/Urho2DLuaAPI.pkg

@@ -2,8 +2,11 @@ $pfile "Urho2D/Sprite2D.pkg"
 $pfile "Urho2D/SpriteSheet2D.pkg"
 $pfile "Urho2D/SpriteSheet2D.pkg"
 $pfile "Urho2D/Drawable2D.pkg"
 $pfile "Urho2D/Drawable2D.pkg"
 $pfile "Urho2D/StaticSprite2D.pkg"
 $pfile "Urho2D/StaticSprite2D.pkg"
+
 $pfile "Urho2D/Animation2D.pkg"
 $pfile "Urho2D/Animation2D.pkg"
+$pfile "Urho2D/AnimationSet2D.pkg"
 $pfile "Urho2D/AnimatedSprite2D.pkg"
 $pfile "Urho2D/AnimatedSprite2D.pkg"
+
 $pfile "Urho2D/ParticleEffect2D.pkg"
 $pfile "Urho2D/ParticleEffect2D.pkg"
 $pfile "Urho2D/ParticleEmitter2D.pkg"
 $pfile "Urho2D/ParticleEmitter2D.pkg"
 
 

+ 30 - 17
Source/Engine/Script/Urho2DAPI.cpp

@@ -21,9 +21,10 @@
 //
 //
 
 
 #include "Precompiled.h"
 #include "Precompiled.h"
-#include "APITemplates.h"
-#include "AnimatedSprite2D.h"
 #include "Animation2D.h"
 #include "Animation2D.h"
+#include "AnimationSet2D.h"
+#include "AnimatedSprite2D.h"
+#include "APITemplates.h"
 #include "CollisionBox2D.h"
 #include "CollisionBox2D.h"
 #include "CollisionChain2D.h"
 #include "CollisionChain2D.h"
 #include "CollisionCircle2D.h"
 #include "CollisionCircle2D.h"
@@ -124,27 +125,36 @@ static void RegisterStaticSprite2D(asIScriptEngine* engine)
 
 
 static void RegisterAnimation2D(asIScriptEngine* engine)
 static void RegisterAnimation2D(asIScriptEngine* engine)
 {
 {
-    RegisterResource<Animation2D>(engine, "Animation2D");
-    engine->RegisterObjectMethod("Animation2D", "float get_totalTime() const", asMETHOD(Animation2D, GetTotalTime), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Animation2D", "uint get_numFrames() const", asMETHOD(Animation2D, GetNumFrames), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Animation2D", "Sprite@+ GetFrameSprite(uint) const", asMETHOD(Animation2D, GetFrameSprite), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Animation2D", "Sprite@+ GetFrameSpriteByTime(float) const", asMETHOD(Animation2D, GetFrameSpriteByTime), asCALL_THISCALL);
+    RegisterRefCounted<Animation2D>(engine, "Animation2D");
+    engine->RegisterObjectMethod("Animation2D", "const String& get_name() const", asMETHOD(Animation2D, GetName), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Animation2D", "float get_length() const", asMETHOD(Animation2D, GetLength), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Animation2D", "bool get_looped() const", asMETHOD(Animation2D, IsLooped), asCALL_THISCALL);
 }
 }
 
 
-static void RegisterAnimatedSprite2D(asIScriptEngine* engine)
+static void RegisterAnimationSet2D(asIScriptEngine* engine)
 {
 {
-    engine->RegisterEnum("CycleMode");
-    engine->RegisterEnumValue("CycleMode", "CM_LOOP", CM_LOOP);
-    engine->RegisterEnumValue("CycleMode", "CM_CLAMP", CM_CLAMP);
-    engine->RegisterEnumValue("CycleMode", "CM_PINGPONG", CM_PINGPONG);
+    RegisterResource<AnimationSet2D>(engine, "AnimationSet2D");
+    engine->RegisterObjectMethod("AnimationSet2D", "uint get_numAnimations() const", asMETHOD(AnimationSet2D, GetNumAnimations), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimationSet2D", "Animation2D@+ GetAnimation(uint) const", asMETHODPR(AnimationSet2D, GetAnimation, (unsigned) const, Animation2D*), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimationSet2D", "Animation2D@+ GetAnimation(const String&) const", asMETHODPR(AnimationSet2D, GetAnimation, (const String&) const, Animation2D*), asCALL_THISCALL);
+}
 
 
-    RegisterStaticSprite2D<AnimatedSprite2D>(engine, "AnimatedSprite2D");
+static void RegisterAnimatedSprite2D(asIScriptEngine* engine)
+{
+    RegisterDrawable<AnimatedSprite2D>(engine, "AnimatedSprite2D");
+    engine->RegisterObjectMethod("AnimatedSprite2D", "void set_layer(int)", asMETHOD(AnimatedSprite2D, SetLayer), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "int get_layer() const", asMETHOD(AnimatedSprite2D, GetLayer), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "void set_orderInLayer(int)", asMETHOD(AnimatedSprite2D, SetOrderInLayer), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "int get_orderInLayer() const", asMETHOD(AnimatedSprite2D, GetOrderInLayer), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "void set_blendMode(BlendMode)", asMETHOD(AnimatedSprite2D, SetBlendMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "BlendMode get_blendMode() const", asMETHOD(AnimatedSprite2D, GetBlendMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimatedSprite2D", "void set_speed(float)", asMETHOD(AnimatedSprite2D, SetSpeed), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimatedSprite2D", "void set_speed(float)", asMETHOD(AnimatedSprite2D, SetSpeed), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimatedSprite2D", "float get_speed() const", asMETHOD(AnimatedSprite2D, GetSpeed), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimatedSprite2D", "float get_speed() const", asMETHOD(AnimatedSprite2D, GetSpeed), asCALL_THISCALL);
-    engine->RegisterObjectMethod("AnimatedSprite2D", "void set_cycleMode(CycleMode)", asMETHOD(AnimatedSprite2D, SetCycleMode), asCALL_THISCALL);
-    engine->RegisterObjectMethod("AnimatedSprite2D", "CycleMode get_cycleMode() const", asMETHOD(AnimatedSprite2D, GetCycleMode), asCALL_THISCALL);
-    engine->RegisterObjectMethod("AnimatedSprite2D", "void set_animation(Animation2D@+)", asMETHOD(AnimatedSprite2D, SetAnimation), asCALL_THISCALL);
-    engine->RegisterObjectMethod("AnimatedSprite2D", "Animation2D@+ get_animation() const", asMETHOD(AnimatedSprite2D, GetAnimation), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "void SetAnimation(AnimationSet2D@+, const String&)", asMETHODPR(AnimatedSprite2D, SetAnimation, (AnimationSet2D*, const String&), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "void set_animationSet(AnimationSet2D@+)", asMETHOD(AnimatedSprite2D, SetAnimationSet), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "AnimationSet2D@+ get_animationSet() const", asMETHOD(AnimatedSprite2D, GetAnimationSet), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "void set_animation(const String&)", asMETHODPR(AnimatedSprite2D, SetAnimation, (const String&), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedSprite2D", "const String& get_animation() const", asMETHOD(AnimatedSprite2D, GetAnimation), asCALL_THISCALL);
 }
 }
 
 
 static void RegisterParticleEffect2D(asIScriptEngine* engine)
 static void RegisterParticleEffect2D(asIScriptEngine* engine)
@@ -592,8 +602,11 @@ void RegisterUrho2DAPI(asIScriptEngine* engine)
     RegisterSpriteSheet2D(engine);
     RegisterSpriteSheet2D(engine);
     RegisterDrawable2D(engine);
     RegisterDrawable2D(engine);
     RegisterStaticSprite2D(engine);
     RegisterStaticSprite2D(engine);
+
     RegisterAnimation2D(engine);
     RegisterAnimation2D(engine);
+    RegisterAnimationSet2D(engine);
     RegisterAnimatedSprite2D(engine);
     RegisterAnimatedSprite2D(engine);
+
     RegisterParticleEffect2D(engine);
     RegisterParticleEffect2D(engine);
     RegisterParticleEmitter2D(engine);
     RegisterParticleEmitter2D(engine);
 
 

+ 264 - 67
Source/Engine/Urho2D/AnimatedSprite2D.cpp

@@ -23,12 +23,13 @@
 #include "Precompiled.h"
 #include "Precompiled.h"
 #include "AnimatedSprite2D.h"
 #include "AnimatedSprite2D.h"
 #include "Animation2D.h"
 #include "Animation2D.h"
+#include "AnimationSet2D.h"
 #include "Context.h"
 #include "Context.h"
 #include "ResourceCache.h"
 #include "ResourceCache.h"
 #include "Scene.h"
 #include "Scene.h"
 #include "SceneEvents.h"
 #include "SceneEvents.h"
 #include "Sprite2D.h"
 #include "Sprite2D.h"
-#include "Texture2D.h"
+#include "StaticSprite2D.h"
 
 
 #include "DebugNew.h"
 #include "DebugNew.h"
 
 
@@ -36,26 +37,15 @@ namespace Urho3D
 {
 {
 
 
 extern const char* URHO2D_CATEGORY;
 extern const char* URHO2D_CATEGORY;
-
-const char* cycleModeNames[] =
-{
-    "Loop",
-    "Clamp",
-    "Pingpong",
-    0
-};
-
-template<> CycleMode Variant::Get<CycleMode>() const
-{
-    return (CycleMode)GetInt();
-}
+extern const char* blendModeNames[];
 
 
 AnimatedSprite2D::AnimatedSprite2D(Context* context) :
 AnimatedSprite2D::AnimatedSprite2D(Context* context) :
-    StaticSprite2D(context),
+    Drawable(context, DRAWABLE_GEOMETRY),
+    layer_(0),
+    orderInLayer_(0),
+    blendMode_(BLEND_ALPHA),
     speed_(1.0f),
     speed_(1.0f),
-    cycleMode_(CM_LOOP),
-    animationTime_(0.0f),
-    animationTotalTime_(1.0f)
+    currentTime_(0.0f)
 {
 {
 }
 }
 
 
@@ -66,15 +56,18 @@ AnimatedSprite2D::~AnimatedSprite2D()
 void AnimatedSprite2D::RegisterObject(Context* context)
 void AnimatedSprite2D::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<AnimatedSprite2D>(URHO2D_CATEGORY);
     context->RegisterFactory<AnimatedSprite2D>(URHO2D_CATEGORY);
+    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_INT, "Layer", GetLayer, SetLayer, int, 0, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_INT, "Order in Layer", GetOrderInLayer, SetOrderInLayer, int, 0, AM_DEFAULT);
+    ENUM_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, "Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, BLEND_ALPHA, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_FLOAT, "Speed", GetSpeed, SetSpeed, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_FLOAT, "Speed", GetSpeed, SetSpeed, float, 1.0f, AM_DEFAULT);
-    ENUM_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, "Cycle Mode", GetCycleMode, SetCycleMode, CycleMode, cycleModeNames, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_RESOURCEREF, "Animation", GetAnimationAttr, SetAnimationAttr, ResourceRef, ResourceRef(Animation2D::GetTypeStatic()), AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(AnimatedSprite2D, StaticSprite2D);
+    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_RESOURCEREF, "Animation Set", GetAnimationSetAttr, SetAnimationSetAttr, ResourceRef, ResourceRef(AnimatedSprite2D::GetTypeStatic()), AM_DEFAULT);
+    REF_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_STRING, "Animation", GetAnimation, SetAnimation, String, String::EMPTY, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Drawable2D, Drawable);
 }
 }
 
 
 void AnimatedSprite2D::OnSetEnabled()
 void AnimatedSprite2D::OnSetEnabled()
 {
 {
-    StaticSprite2D::OnSetEnabled();
+    Drawable::OnSetEnabled();
 
 
     Scene* scene = GetScene();
     Scene* scene = GetScene();
     if (scene)
     if (scene)
@@ -86,60 +79,97 @@ void AnimatedSprite2D::OnSetEnabled()
     }
     }
 }
 }
 
 
-void AnimatedSprite2D::SetSpeed(float speed)
+void AnimatedSprite2D::SetLayer(int layer)
 {
 {
-    speed_ = speed;
-    MarkNetworkUpdate();
+    if (layer == layer_)
+        return;
+
+    layer_ = layer;
+
+    for (unsigned i = 0; i < timelineNodes_.Size(); ++i)
+    {
+        StaticSprite2D* objectSprite = timelineNodes_[i]->GetComponent<StaticSprite2D>();
+        objectSprite->SetLayer(layer_);
+    }
 }
 }
 
 
-void AnimatedSprite2D::SetCycleMode(CycleMode cycleMode)
+void AnimatedSprite2D::SetOrderInLayer(int orderInLayer)
 {
 {
-    cycleMode_ = cycleMode;
-    MarkNetworkUpdate();
+    orderInLayer_ = orderInLayer;
 }
 }
 
 
-void AnimatedSprite2D::SetAnimation(Animation2D* animation)
+void AnimatedSprite2D::SetBlendMode(BlendMode blendMode)
 {
 {
-    animationTime_ = 0.0f;
-
-    if (animation_ == animation)
+    if (blendMode == blendMode_)
         return;
         return;
 
 
-    if (animation_)
-        SetSprite(0);
+    blendMode_ = blendMode;
 
 
-    animation_ = animation;
-
-    if (animation_)
+    for (unsigned i = 0; i < timelineNodes_.Size(); ++i)
     {
     {
-        SetSprite(animation_->GetFrameSprite(0));
-        animationTotalTime_ = animation_->GetTotalTime();
+        StaticSprite2D* objectSprite = timelineNodes_[i]->GetComponent<StaticSprite2D>();
+        objectSprite->SetBlendMode(blendMode_);
     }
     }
+}
 
 
+void AnimatedSprite2D::SetSpeed(float speed)
+{
+    speed_ = speed;
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
-Animation2D* AnimatedSprite2D::GetAnimation() const
+void AnimatedSprite2D::SetAnimation(AnimationSet2D* animationSet, const String& name)
+{
+    animationSet_ = animationSet;
+    animationName_ = name;
+    
+    if (animationSet)
+        SetAnimation(animationSet->GetAnimation(name));
+    else
+        SetAnimation(0);
+}
+
+void AnimatedSprite2D::SetAnimationSet(AnimationSet2D* animationSet)
+{
+    if (animationSet == animationSet_)
+        return;
+
+    animationSet_ = animationSet;
+
+    if (animationSet_)
+        SetAnimation(animationSet_->GetAnimation(animationName_));
+    else
+        SetAnimation(0);
+
+}
+void AnimatedSprite2D::SetAnimation(const String& name)
 {
 {
-    return animation_;
+    animationName_ = name;
+
+    if (animationSet_)
+        SetAnimation(animationSet_->GetAnimation(animationName_));
 }
 }
 
 
-void AnimatedSprite2D::SetAnimationAttr(ResourceRef value)
+AnimationSet2D* AnimatedSprite2D::GetAnimationSet() const
 {
 {
-    materialUpdatePending_ = true;
+    return animationSet_;
+}
 
 
+
+void AnimatedSprite2D::SetAnimationSetAttr(ResourceRef value)
+{
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
-    SetAnimation(cache->GetResource<Animation2D>(value.name_));
+    SetAnimationSet(cache->GetResource<AnimationSet2D>(value.name_));
 }
 }
 
 
-Urho3D::ResourceRef AnimatedSprite2D::GetAnimationAttr() const
+Urho3D::ResourceRef AnimatedSprite2D::GetAnimationSetAttr() const
 {
 {
-    return GetResourceRef(animation_, Animation2D::GetTypeStatic());
+    return GetResourceRef(animationSet_, AnimationSet2D::GetTypeStatic());
 }
 }
 
 
 void AnimatedSprite2D::OnNodeSet(Node* node)
 void AnimatedSprite2D::OnNodeSet(Node* node)
 {
 {
-    StaticSprite2D::OnNodeSet(node);
+    Drawable::OnNodeSet(node);
 
 
     if (node)
     if (node)
     {
     {
@@ -149,43 +179,210 @@ void AnimatedSprite2D::OnNodeSet(Node* node)
     }
     }
 }
 }
 
 
-void AnimatedSprite2D::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
+void AnimatedSprite2D::OnWorldBoundingBoxUpdate()
 {
 {
-    using namespace ScenePostUpdate;
-    float timeStep = eventData[P_TIMESTEP].GetFloat();
-    animationTime_ += timeStep * speed_;
+    boundingBox_.Clear();
+    worldBoundingBox_.Clear();
+
+    for (unsigned i = 0; i < timelineNodes_.Size(); ++i)
+    {
+        if (!timelineNodes_[i])
+            continue;
 
 
+        StaticSprite2D* staticSprite = timelineNodes_[i]->GetComponent<StaticSprite2D>();
+        worldBoundingBox_.Merge(staticSprite->GetWorldBoundingBox());
+    }
+
+    boundingBox_ = worldBoundingBox_.Transformed(node_->GetWorldTransform().Inverse());
+}
+
+void AnimatedSprite2D::SetAnimation(Animation2D* animation)
+{
+    if (animation == animation_)
+    {
+        // Reset time
+        currentTime_ = 0.0f;
+        return;
+    }
+
+    if (animation_)
+    {
+        for (unsigned i = 0; i < timelineNodes_.Size(); ++i)
+        {
+            if (timelineNodes_[i])
+                timelineNodes_[i]->Remove();
+        }
+
+        timelineNodes_.Clear();
+    }
+
+    animation_ = animation;
+
+    if (!animation_)
+        return;
+
+    currentTime_ = 0.0f;
+
+    timelineNodes_.Resize(animation_->GetNumTimelines());
+    timelineTransformInfos_.Resize(animation_->GetNumTimelines());
+
+    for (unsigned i = 0; i < animation_->GetNumTimelines(); ++i)
+    {
+        const Timeline2D& timeline = animation->GetTimeline(i);
+        // Just create sprite type node
+        if (timeline.type_ == OT_SPRITE)
+        {
+            SharedPtr<Node> timelineNode(GetNode()->CreateChild(timeline.name_));
+            
+            StaticSprite2D* staticSprite = timelineNode->CreateComponent<StaticSprite2D>();
+            staticSprite->SetLayer(layer_);
+            staticSprite->SetBlendMode(blendMode_);
+            staticSprite->SetUseHotSpot(true);
+
+            timelineNodes_[i] = timelineNode;
+        }
+
+        timelineTransformInfos_[i].parent_ = timeline.parent_;
+    }
+
+    UpdateAnimation(0.0f);
+
+    MarkNetworkUpdate();
+}
+
+void AnimatedSprite2D::UpdateAnimation(float timeStep)
+{
     if (!animation_)
     if (!animation_)
         return;
         return;
+    
+    currentTime_ += timeStep * speed_;
 
 
     float time;
     float time;
+    float animtationLength = animation_->GetLength();
 
 
-    switch (cycleMode_)
+    if (animation_->IsLooped())
     {
     {
-    case CM_LOOP:
-        time = fmodf(animationTime_, animationTotalTime_);
+        time = fmodf(currentTime_, animtationLength);
         if (time < 0.0f)
         if (time < 0.0f)
-            time += animationTotalTime_;
-        break;
+            time += animation_->GetLength();
+    }
+    else
+        time = Clamp(currentTime_, 0.0f, animtationLength);
 
 
-    case CM_CLAMP:
-        time = Clamp(animationTime_, 0.0f, animationTotalTime_);
-        break;
+    // Update timeline's local transform
+    for (unsigned i = 0; i < timelineTransformInfos_.Size(); ++i)
+    {
+        const Timeline2D& timeline = animation_->GetTimeline(i);
+        
+        const Vector<TimelineKey2D>& objectKeys = timeline.timelineKeys_;
+        for (unsigned j = 0; j < objectKeys.Size() - 1; ++j)
+        {
+            if (time <= objectKeys[j + 1].time_)
+            {
+                const TimelineKey2D& currKey = objectKeys[j];
+                const TimelineKey2D& nextKey = objectKeys[j + 1];
+                float t = (time - currKey.time_)  / (nextKey.time_ - currKey.time_);
+
+                timelineTransformInfos_[i].localTransform_ = currKey.transform_.Lerp(nextKey.transform_, t, currKey.spin_);
+                timelineTransformInfos_[i].worldTransformUpdated_ = false;
+
+                // Update sprite's sprite and hot spot and color
+                Node* timelineNode = timelineNodes_[i];
+                if (timelineNode)
+                {
+                    StaticSprite2D* staticSprite = timelineNode->GetComponent<StaticSprite2D>();
+                    staticSprite->SetSprite(currKey.sprite_);
+                    staticSprite->SetHotSpot(currKey.hotSpot_.Lerp(nextKey.hotSpot_, t));
+                    float alpha_ = Lerp(currKey.alpha_, nextKey.alpha_, t);
+                    staticSprite->SetColor(Color(1.0f, 1.0f, 1.0f, alpha_));
+                }
+
+                break;
+            }
+        }
+    }
+
+    // Update timeline's world transform
+    for (unsigned i = 0; i < timelineTransformInfos_.Size(); ++i)
+        UpateTimelineWorldTransform(i);
 
 
-    case CM_PINGPONG:
+    // Get mainline key
+    const Vector<MainlineKey2D>& mainlineKeys = animation_->GetMainlineKeys();
+    const MainlineKey2D* mainlineKey = 0;
+    for (unsigned i = 1; i < mainlineKeys.Size(); ++i)
+    {
+        if (time < mainlineKeys[i].time_)
         {
         {
-            float doubleTotalTime = animationTotalTime_ * 2.0f;
-            float fract = fmodf(animationTime_, doubleTotalTime);
-            time = (fract < animationTotalTime_) ? fract : doubleTotalTime - fract;
+            mainlineKey = &mainlineKeys[i - 1];
+            break;
         }
         }
-        break;
     }
     }
 
 
-    Sprite2D* sprite = animation_->GetFrameSpriteByTime(time);
-    if (GetSprite() != sprite)
-        SetSprite(sprite);
+    if (!mainlineKey)
+        mainlineKey = &mainlineKeys.Back();
+
+    // Update node's transform and sprite's z order
+    for (unsigned i = 0; i < timelineNodes_.Size(); ++i)
+    {
+        Node* timelineNode = timelineNodes_[i];
+        if (!timelineNode)
+            continue;
+
+        const Reference2D* ref = mainlineKey->GetReference(i);
+        if (!ref)
+        {
+            // Disable node
+            if (timelineNode->IsEnabled())
+                timelineNode->SetEnabled(false);
+        }
+        else
+        {
+            // Enable node
+            if (!timelineNode->IsEnabled())
+                timelineNode->SetEnabled(true);
+
+            // Update node's transform
+            const Transform2D& transform = timelineTransformInfos_[i].worldTransform_;
+            timelineNode->SetScale(transform.scale_);
+            timelineNode->SetRotation(transform.angle_);
+            timelineNode->SetPosition(transform.position_);
+
+            // Update sprite's z order
+            StaticSprite2D* staticSprite = timelineNode->GetComponent<StaticSprite2D>();
+            staticSprite->SetOrderInLayer(orderInLayer_ + ref->zIndex_);
+        }
+    }
 
 
     MarkForUpdate();
     MarkForUpdate();
 }
 }
 
 
+void AnimatedSprite2D::UpateTimelineWorldTransform(unsigned index)
+{
+    TransformInfo& info = timelineTransformInfos_[index];
+    if (info.worldTransformUpdated_)
+        return;
+
+    if (info.parent_ == -1)
+    {
+        info.worldTransform_ = info.localTransform_;
+        info.worldTransformUpdated_ = true;
+    }
+    else
+    {
+        UpateTimelineWorldTransform(info.parent_);
+
+        info.worldTransform_ = timelineTransformInfos_[info.parent_].worldTransform_ * info.localTransform_;
+        info.worldTransformUpdated_ = true;
+    }
 }
 }
+
+void AnimatedSprite2D::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
+{
+    using namespace ScenePostUpdate;
+    float timeStep = eventData[P_TIMESTEP].GetFloat();
+    UpdateAnimation(timeStep);
+}
+
+}
+
+

+ 68 - 34
Source/Engine/Urho2D/AnimatedSprite2D.h

@@ -22,26 +22,16 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "StaticSprite2D.h"
+#include "Animation2D.h"
+#include "Drawable.h"
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
 
 
-class Animation2D;
+class AnimationSet2D;
 
 
-/// Cycle mode.
-enum CycleMode
-{
-    /// Loop mode.
-    CM_LOOP = 0,
-    /// Clamp mode.
-    CM_CLAMP,
-    /// Pingpong Mode.
-    CM_PINGPONG,
-};
-
-/// Animated sprite component.
-class URHO3D_API AnimatedSprite2D : public StaticSprite2D
+/// Spriter animation component.
+class URHO3D_API AnimatedSprite2D : public Drawable
 {
 {
     OBJECT(AnimatedSprite2D);
     OBJECT(AnimatedSprite2D);
 
 
@@ -55,42 +45,86 @@ public:
 
 
     /// Handle enabled/disabled state change.
     /// Handle enabled/disabled state change.
     virtual void OnSetEnabled();
     virtual void OnSetEnabled();
-
+    
+    /// Set layer.
+    void SetLayer(int layer);
+    /// Set order in layer.
+    void SetOrderInLayer(int orderInLayer);
+    /// Set blend mode.
+    void SetBlendMode(BlendMode mode);
     /// Set speed.
     /// Set speed.
     void SetSpeed(float speed);
     void SetSpeed(float speed);
-    /// Set cycle mode.
-    void SetCycleMode(CycleMode cycleMode);
-    /// Set animation.
-    void SetAnimation(Animation2D* animation);
+    /// Set animation by animation set and name.
+    void SetAnimation(AnimationSet2D* animationSet, const String& name);
+    /// Set animation set.
+    void SetAnimationSet(AnimationSet2D* animationSet);
+    /// Set animation by name.
+    void SetAnimation(const String& name);
 
 
+    /// Return layer.
+    int GetLayer() const { return layer_; }
+    /// Return order in layer.
+    int GetOrderInLayer() const { return orderInLayer_; }
+    /// Return blend mode.
+    BlendMode GetBlendMode() const { return blendMode_; }
     /// Return speed.
     /// Return speed.
     float GetSpeed() const { return speed_; }
     float GetSpeed() const { return speed_; }
-    /// Return cycle mode.
-    CycleMode GetCycleMode() const { return cycleMode_; }
-    /// Return Animation.
-    Animation2D* GetAnimation() const;
+    /// Return animation.
+    AnimationSet2D* GetAnimationSet() const;
+    /// Return animation name.
+    const String& GetAnimation() const { return animationName_; }
 
 
-    /// Set animation attr.
-    void SetAnimationAttr(ResourceRef value);
-    /// Return animation attr.
-    ResourceRef GetAnimationAttr() const;
+    /// Set animation set attribute.
+    void SetAnimationSetAttr(ResourceRef value);
+    /// Return animation set attribute.
+    ResourceRef GetAnimationSetAttr() const;
 
 
 protected:
 protected:
     /// Handle node being assigned.
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
     virtual void OnNodeSet(Node* node);
+    /// Recalculate the world-space bounding box.
+    virtual void OnWorldBoundingBoxUpdate();
+    /// Set animation.
+    void SetAnimation(Animation2D* animation);
+    /// Update animation.
+    void UpdateAnimation(float timeStep);
+    /// Update timeline world transform.
+    void UpateTimelineWorldTransform(unsigned index);
     /// Handle scene post update.
     /// Handle scene post update.
     void HandleScenePostUpdate(StringHash eventType, VariantMap& eventData);
     void HandleScenePostUpdate(StringHash eventType, VariantMap& eventData);
 
 
+    /// Layer.
+    int layer_;
+    /// Order in layer.
+    int orderInLayer_;
+    /// Blend mode.
+    BlendMode blendMode_;
     /// Speed.
     /// Speed.
     float speed_;
     float speed_;
-    /// Cycle mode.
-    CycleMode cycleMode_;
+    /// Animation set.
+    SharedPtr<AnimationSet2D> animationSet_;
+    /// Animation name.
+    String animationName_;
     /// Animation.
     /// Animation.
     SharedPtr<Animation2D> animation_;
     SharedPtr<Animation2D> animation_;
-    /// Animation time.
-    float animationTime_;
-    /// Animation total time.
-    float animationTotalTime_;
+    /// Current time.
+    float currentTime_;
+    /// Timeline nodes.
+    Vector<SharedPtr<Node> > timelineNodes_;
+    /// Transform info.
+    struct TransformInfo
+    {
+        /// Parent.
+        int parent_;
+        /// Local transform.
+        Transform2D localTransform_;
+        /// World transform updated.
+        bool worldTransformUpdated_;
+        /// World transform.
+        Transform2D worldTransform_;
+    };
+    /// Timeline transform infos.
+    Vector<TransformInfo> timelineTransformInfos_;
 };
 };
 
 
 }
 }

+ 184 - 181
Source/Engine/Urho2D/Animation2D.cpp

@@ -1,181 +1,184 @@
-//
-// Copyright (c) 2008-2014 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#include "Precompiled.h"
-#include "Animation2D.h"
-#include "Context.h"
-#include "Deserializer.h"
-#include "FileSystem.h"
-#include "Log.h"
-#include "ResourceCache.h"
-#include "Serializer.h"
-#include "Sprite2D.h"
-#include "SpriteSheet2D.h"
-#include "XMLFile.h"
-
-#include "DebugNew.h"
-
-namespace Urho3D
-{
-
-Animation2D::Animation2D(Context* context) :
-    Resource(context)
-{
-
-}
-
-Animation2D::~Animation2D()
-{
-
-}
-
-void Animation2D::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Animation2D>();
-}
-
-bool Animation2D::Load(Deserializer& source)
-{
-    frameEndTimes_.Clear();
-    frameSprites_.Clear();
-
-    SharedPtr<XMLFile> xmlFile(new XMLFile(context_));
-    if(!xmlFile->Load(source))
-    {
-        LOGERROR("Could not load animation");
-        return false;
-    }
-
-    SetMemoryUse(source.GetSize());
-
-    XMLElement rootElem = xmlFile->GetRoot("animation");
-    if (!rootElem)
-    {
-        LOGERROR("Invalid animation");
-        return false;
-    }
-
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    XMLElement keyFrameElem = rootElem.GetChild("frame");
-    if (!keyFrameElem)
-    {
-        LOGERROR("Could not found key frame");
-        return false;
-    }
-
-    float endTime = 0.0f;
-
-    while (keyFrameElem)
-    {
-        endTime += keyFrameElem.GetFloat("duration");
-        frameEndTimes_.Push(endTime);
-
-        SharedPtr<Sprite2D> sprite;
-        Vector<String> names = keyFrameElem.GetAttribute("sprite").Split('@');
-        if (names.Size() == 1)
-            sprite = cache->GetResource<Sprite2D>(names[0]);
-        else if (names.Size() == 2)
-        {
-            SpriteSheet2D* spriteSheet = cache->GetResource<SpriteSheet2D>(names[0], false);
-            // If sprite sheet not found, try get in current directory
-            if (!spriteSheet)
-                spriteSheet = cache->GetResource<SpriteSheet2D>(GetParentPath(GetName()) + names[0]);
-
-            if (!spriteSheet)
-            {
-                LOGERROR("Could not get sprite speet");
-                return false;
-            }
-
-            sprite = spriteSheet->GetSprite(names[1]);
-        }
-
-        if (!sprite)
-        {
-            LOGERROR("Could not get sprite");
-            return false;
-        }
-
-        frameSprites_.Push(sprite);
-        keyFrameElem = keyFrameElem.GetNext("frame");
-    }
-
-    return true;
-}
-
-bool Animation2D::Save(Serializer& dest) const
-{
-    XMLFile xmlFile(context_);
-    XMLElement rootElem = xmlFile.CreateRoot("animation");
-    
-    float endTime = 0.0f;
-    for (unsigned i = 0; i < frameSprites_.Size(); ++i)
-    {
-        XMLElement frameElem = rootElem.CreateChild("frame");
-        frameElem.SetFloat("duration", frameEndTimes_[i] - endTime);
-        endTime = frameEndTimes_[i];
-
-        Sprite2D* sprite = frameSprites_[i];
-        SpriteSheet2D* spriteSheet = sprite->GetSpriteSheet();
-        if (!spriteSheet)
-            frameElem.SetString("sprite", sprite->GetName());
-        else
-            frameElem.SetString("sprite", spriteSheet->GetName() + "@" + sprite->GetName());
-    }
-
-    return xmlFile.Save(dest);
-}
-
-float Animation2D::GetTotalTime() const
-{
-    return frameEndTimes_.Empty() ? 0.0f : frameEndTimes_.Back();
-}
-
-unsigned Animation2D::GetNumFrames() const
-{
-    return frameSprites_.Size();
-}
-
-Sprite2D* Animation2D::GetFrameSprite(unsigned index) const
-{
-    if (index < frameSprites_.Size())
-        return frameSprites_[index];
-
-    return 0;
-}
-
-Sprite2D* Animation2D::GetFrameSpriteByTime(float time) const
-{
-    if (time < 0.0f)
-        return 0;
-
-    for (unsigned i = 0; i < frameEndTimes_.Size(); ++i)
-    {
-        if (time <= frameEndTimes_[i])
-            return frameSprites_[i];
-    }
-
-    return 0;
-}
-
-}
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Precompiled.h"
+#include "Animation2D.h"
+#include "AnimationSet2D.h"
+#include "Sprite2D.h"
+
+#include "DebugNew.h"
+
+namespace Urho3D
+{
+
+Reference2D::Reference2D() :
+    type_(OT_BONE),
+    timeline_(0),
+    zIndex_(0)
+{
+}
+
+MainlineKey2D::MainlineKey2D() :
+    time_(0)
+{
+}
+
+const Reference2D* MainlineKey2D::GetReference(int timeline) const
+{
+    for (unsigned i = 0; i < references_.Size(); ++i)
+    {
+        if (references_[i].timeline_ == timeline)
+            return &references_[i];
+    }
+    return 0;
+}
+
+TimelineKey2D::TimelineKey2D() :
+    time_(0.0f),
+    spin_(1),
+    hotSpot_(0.0f, 1.0f),
+    alpha_(1.0f)
+{
+}
+
+Timeline2D::Timeline2D() :
+    type_(OT_BONE),
+    parent_(-1)
+{
+}
+
+Animation2D::Animation2D(AnimationSet2D* animationSet) : 
+    animationSet_(animationSet),
+    length_(0.0f), 
+    looped_(true)
+{
+}
+
+Animation2D::~Animation2D()
+{
+}
+
+void Animation2D::SetName(const String& name)
+{
+    name_ = name;
+}
+
+void Animation2D::SetLength(float length)
+{
+    length_ = Max(0.0f, length);
+}
+
+void Animation2D::SetLooped(bool looped)
+{
+    looped_ = looped;
+}
+
+void Animation2D::AddMainlineKey(const MainlineKey2D& mainlineKey)
+{
+    mainlineKeys_.Push(mainlineKey);
+}
+
+void Animation2D::AddTimeline(const Timeline2D& timeline)
+{
+    timelines_.Push(timeline);
+}
+
+void Animation2D::SetTimelineParent(int timeline, int timelineParent)
+{
+    if (timeline == timelineParent)
+        return;
+    timelines_[timeline].parent_ = timelineParent;
+}
+
+AnimationSet2D* Animation2D::GetAnimationSet() const
+{
+    return animationSet_;
+}
+
+
+Transform2D::Transform2D() :
+position_(Vector2::ZERO),
+    angle_(0.0f),
+    scale_(Vector2::ONE)
+{
+
+}
+
+Transform2D::Transform2D(const Vector2 position, float angle, const Vector2& scale) :
+position_(position), 
+    angle_(angle), 
+    scale_(scale)
+{
+
+}
+
+Transform2D::Transform2D(const Transform2D& other) :
+position_(other.position_), 
+    angle_(other.angle_), 
+    scale_(other.scale_)
+{
+
+}
+
+Transform2D& Transform2D::operator = (const Transform2D& other)
+{
+    position_ = other.position_; 
+    angle_ = other.angle_;
+    scale_ = other.scale_;
+    return *this;
+}
+
+Transform2D Transform2D::operator * (const Transform2D& other) const
+{
+    float x = scale_.x_ * other.position_.x_;
+    float y = scale_.y_ * other.position_.y_;
+    float s = Sin(angle_);
+    float c = Cos(angle_);
+
+    Vector2 position;
+    position.x_ = (x * c) - (y * s);
+    position.y_ = (x * s) + (y * c);
+    position = position_ + position;
+
+    float angle = angle_ + other.angle_;
+    Vector2 scale = scale_ * other.scale_;
+
+    return Transform2D(position, angle, scale);
+}
+
+Urho3D::Transform2D Transform2D::Lerp(const Transform2D& other, float t, int spin) const
+{
+    Transform2D ret;
+    ret.position_ = position_.Lerp(other.position_, t);
+
+    if (spin > 0 && angle_ > other.angle_)
+        ret.angle_ = Urho3D::Lerp(angle_, other.angle_ + 360.0f, t);
+    else if (spin < 0 && angle_ < other.angle_)
+        ret.angle_= Urho3D::Lerp(angle_, other.angle_ - 360.0f, t);
+    else
+        ret.angle_= Urho3D::Lerp(angle_, other.angle_, t);
+
+    ret.scale_ = scale_.Lerp(other.scale_, t);
+    return ret;
+}
+
+}

+ 187 - 66
Source/Engine/Urho2D/Animation2D.h

@@ -1,66 +1,187 @@
-//
-// Copyright (c) 2008-2014 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-#include "Resource.h"
-
-namespace Urho3D
-{
-
-class Sprite2D;
-
-/// 2D animation.
-class URHO3D_API Animation2D : public Resource
-{
-    OBJECT(Animation2D);
-
-public:
-    /// Construct.
-    Animation2D(Context* context);
-    /// Destruct.
-    virtual ~Animation2D();
-    /// Register object factory.
-    static void RegisterObject(Context* context);
-
-    /// Load resource. Return true if successful.
-    virtual bool Load(Deserializer& source);
-    /// Save resource. Return true if successful.
-    virtual bool Save(Serializer& dest) const;
-
-    /// Return total time.
-    float GetTotalTime() const;
-    /// Return number of frames.
-    unsigned GetNumFrames() const;
-    /// Return Frame sprite.
-    Sprite2D* GetFrameSprite(unsigned index) const;
-    /// Return frame sprite by time.
-    Sprite2D* GetFrameSpriteByTime(float time) const;
-
-private:
-    /// Frame end times.
-    PODVector<float> frameEndTimes_;
-    /// Frame sprites.
-    Vector<SharedPtr<Sprite2D> > frameSprites_;
-};
-
-}
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "HashMap.h"
+#include "Ptr.h"
+#include "RefCounted.h"
+#include "Vector2.h"
+
+namespace Urho3D
+{
+
+class AnimationSet2D;
+class Sprite2D;
+
+/// Object type.
+enum ObjectType2D
+{
+    /// Bone.
+    OT_BONE = 0,
+    /// Sprite.
+    OT_SPRITE,
+};
+
+/// Reference.
+struct Reference2D
+{
+    /// Construct.
+    Reference2D();
+
+    /// Object type.
+    ObjectType2D type_;
+    /// Timeline.
+    int timeline_;
+    /// Z index (draw order).
+    int zIndex_;
+};
+
+/// Mainline Key.
+struct MainlineKey2D
+{
+public:
+    /// Construct.
+    MainlineKey2D();
+
+    /// Return reference by timeline.
+    const Reference2D* GetReference(int timeline) const;
+
+    /// Time.
+    float time_;
+    /// References.
+    Vector<Reference2D> references_;
+};
+
+struct Transform2D
+{
+    /// Construct.
+    Transform2D();
+    /// Construct from position, angle, scale.
+    Transform2D(const Vector2 position, float angle, const Vector2& scale);
+    /// Copy-construct from another transform.
+    Transform2D(const Transform2D& other);
+
+    /// Assign from another transform.
+    Transform2D& operator = (const Transform2D& other);
+    /// Multiply a transform.
+    Transform2D operator * (const Transform2D& other) const;
+    /// Linear interpolation with another transform.
+    Transform2D Lerp(const Transform2D& other, float t, int spin) const;
+
+    /// Position.
+    Vector2 position_;
+    /// Angle.
+    float angle_;
+    /// Scale.
+    Vector2 scale_;
+};
+
+/// Timeline key.
+struct TimelineKey2D
+{
+    /// Construct.
+    TimelineKey2D();
+
+    /// Time.
+    float time_;
+    /// Spin direction.
+    int spin_;
+    /// Transform.
+    Transform2D transform_;
+    /// Sprite.
+    SharedPtr<Sprite2D> sprite_;
+    /// Hot spot (pivot).
+    Vector2 hotSpot_;
+    /// Alpha.
+    float alpha_;
+};
+
+/// Timeline.
+struct Timeline2D
+{
+    /// Construct.
+    Timeline2D();
+
+    /// Name.
+    String name_;
+    /// Parent.
+    int parent_;
+    /// Object type.
+    ObjectType2D type_;
+    /// Object keys.
+    Vector<TimelineKey2D> timelineKeys_;
+};
+
+/// Spriter animation. for more information please refer to http://www.brashmonkey.com/spriter.htm.
+class URHO3D_API Animation2D : public RefCounted
+{
+public:
+    /// Construct.
+    Animation2D(AnimationSet2D* animationSet);
+    /// Destruct
+    virtual ~Animation2D();
+
+    /// Set name.
+    void SetName(const String& name);
+    /// Set length.
+    void SetLength(float length);
+    /// Set looped.
+    void SetLooped(bool looped);
+    /// Add mainline key.
+    void AddMainlineKey(const MainlineKey2D& mainlineKey);
+    /// Add timeline.
+    void AddTimeline(const Timeline2D& timeline);
+    /// Set time line parent.
+    void SetTimelineParent(int timeline, int timelineParent);
+
+    /// Return animation set.
+    AnimationSet2D* GetAnimationSet() const;
+    /// Return name.
+    const String& GetName() const { return name_; }
+    /// Return length.
+    float GetLength() const { return length_; }
+    /// Return looped.
+    bool IsLooped() const { return looped_; }
+    /// Return all mainline keys.
+    const Vector<MainlineKey2D>& GetMainlineKeys() const { return mainlineKeys_; }
+    /// Return number of timelines.
+    unsigned GetNumTimelines() const { return timelines_.Size();}
+    /// Return timeline by index.
+    const Timeline2D& GetTimeline(unsigned index) const { return timelines_[index]; }
+
+private:
+    /// Animation set.
+    WeakPtr<AnimationSet2D> animationSet_;
+    /// Name.
+    String name_;
+    /// Length.
+    float length_;
+    /// Looped.
+    bool looped_;
+    /// All mainline Keys.
+    Vector<MainlineKey2D> mainlineKeys_;
+    /// All timelines.
+    Vector<Timeline2D> timelines_;
+};
+
+}

+ 286 - 0
Source/Engine/Urho2D/AnimationSet2D.cpp

@@ -0,0 +1,286 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Precompiled.h"
+#include "Animation2D.h"
+#include "AnimationSet2D.h"
+#include "Context.h"
+#include "Drawable2D.h"
+#include "FileSystem.h"
+#include "Log.h"
+#include "ResourceCache.h"
+#include "Sprite2D.h"
+#include "XMLFile.h"
+
+#include "DebugNew.h"
+
+namespace Urho3D
+{
+
+AnimationSet2D::AnimationSet2D(Context* context) :
+    Resource(context)
+{
+}
+
+AnimationSet2D::~AnimationSet2D()
+{
+}
+
+void AnimationSet2D::RegisterObject(Context* context)
+{
+    context->RegisterFactory<AnimationSet2D>();
+}
+
+bool AnimationSet2D::Load(Deserializer& source)
+{
+    XMLFile xmlFile(context_);
+    if (!xmlFile.Load(source))
+    {
+        LOGERROR("Load XML filed " + source.GetName());
+        return false;
+    }
+
+    XMLElement rootElem = xmlFile.GetRoot("spriter_data");
+    if (!rootElem)
+    {
+        LOGERROR("Invalid spriter file " + source.GetName());
+        return false;
+    }
+    
+    if (!LoadFolders(rootElem))
+        return false;
+
+    XMLElement entityElem = rootElem.GetChild("entity");
+    if (!entityElem)
+    {
+        LOGERROR("Could not find entity");
+        return false;
+    }
+    
+    for (XMLElement animationElem = entityElem.GetChild("animation"); animationElem; animationElem = animationElem.GetNext("animation"))
+    {
+        if (!LoadAnimation(animationElem))
+            return false;
+    }
+
+    return true;
+}
+
+unsigned AnimationSet2D::GetNumAnimations() const
+{
+    return animations_.Size();
+}
+
+Animation2D* AnimationSet2D::GetAnimation(unsigned index) const
+{
+    if (index < animations_.Size())
+        return animations_[index];
+    return 0;
+}
+
+Animation2D* AnimationSet2D::GetAnimation(const String& name) const
+{
+    for (unsigned i = 0; i < animations_.Size(); ++i)
+    {
+        if (animations_[i]->GetName() == name)
+            return animations_[i];
+    }
+    return 0;
+}
+
+Sprite2D* AnimationSet2D::GetSprite(unsigned folderId, unsigned fileId) const
+{
+    unsigned key = (folderId << 16) + fileId;
+    HashMap<unsigned, SharedPtr<Sprite2D> >::ConstIterator i = sprites_.Find(key);
+    if (i != sprites_.End())
+        return i->second_;
+    return 0;
+}
+
+bool AnimationSet2D::LoadFolders(const XMLElement& rootElem)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    String parentPath = GetParentPath(GetName());
+
+    for (XMLElement folderElem = rootElem.GetChild("folder"); folderElem; folderElem = folderElem.GetNext("folder"))
+    {
+        unsigned folderId = folderElem.GetUInt("id");
+
+        for (XMLElement fileElem = folderElem.GetChild("file"); fileElem; fileElem = fileElem.GetNext("file"))
+        {
+            unsigned fileId = fileElem.GetUInt("id");
+            String fileName = fileElem.GetAttribute("name");
+
+            SharedPtr<Sprite2D> sprite(cache->GetResource<Sprite2D>(parentPath + fileName));
+            if (!sprite)
+            {
+                LOGERROR("Could not load sprite " + parentPath + fileName);
+                return false;
+            }
+            
+            Vector2 hotSpot(0.0f, 1.0f);
+            if (fileElem.HasAttribute("pivot_x"))
+                hotSpot.x_ = fileElem.GetFloat("pivot_x");
+            if (fileElem.HasAttribute("pivot_y"))
+                hotSpot.y_ = fileElem.GetFloat("pivot_y");
+            sprite->SetHotSpot(hotSpot);
+
+            sprites_[(folderId << 16) + fileId] = sprite;
+        }
+    }
+
+    return true;
+}
+
+
+bool AnimationSet2D::LoadAnimation(const XMLElement& animationElem)
+{
+    SharedPtr<Animation2D> animation(new Animation2D(this));
+    
+    String name = animationElem.GetAttribute("name");
+    animation->SetName(name);
+
+    float length = animationElem.GetFloat("length") * 0.001f;
+    animation->SetLength(length);
+
+    bool looped = true;
+    if (animationElem.HasAttribute("looping"))
+        looped = animationElem.GetBool("looping");
+    animation->SetLooped(looped);
+
+    // Load time lines
+    for (XMLElement timelineElem = animationElem.GetChild("timeline"); timelineElem; timelineElem = timelineElem.GetNext("timeline"))
+    {
+        Timeline2D timeline;
+        timeline.name_ = timelineElem.GetAttribute("name");
+        if (timelineElem.GetAttribute("object_type") == "bone")
+            timeline.type_ = OT_BONE;
+        else
+            timeline.type_ = OT_SPRITE;
+
+        for (XMLElement keyElem = timelineElem.GetChild("key"); keyElem; keyElem = keyElem.GetNext("key"))
+        {
+            TimelineKey2D key;
+            key.time_ = keyElem.GetFloat("time") * 0.001f;
+            key.spin_ = 1;
+            if (keyElem.HasAttribute("spin"))
+                key.spin_ = keyElem.GetInt("spin");
+
+            XMLElement childElem = keyElem.GetChild();
+
+            Vector2 position;
+            position.x_ = childElem.GetFloat("x") * PIXEL_SIZE;
+            position.y_ = childElem.GetFloat("y") * PIXEL_SIZE;
+
+            float angle = childElem.GetFloat("angle");
+
+            Vector2 scale(Vector2::ONE);
+            if (childElem.HasAttribute("scale_x"))
+                scale.x_ = childElem.GetFloat("scale_x");
+
+            if (childElem.HasAttribute("scale_y"))
+                scale.y_ = childElem.GetFloat("scale_y");
+
+            key.transform_ = Transform2D(position, angle, scale);
+
+            if (timeline.type_ == OT_SPRITE)
+            {
+                int folder = childElem.GetUInt("folder");
+                int file = childElem.GetUInt("file");
+                key.sprite_ = GetSprite(folder, file);
+                if (!key.sprite_)
+                {
+                    LOGERROR("Could not find sprite");
+                    return false;
+                }
+
+                if (childElem.HasAttribute("pivot_x"))
+                    key.hotSpot_.x_ = childElem.GetFloat("pivot_x");
+                else
+                    key.hotSpot_.x_ = key.sprite_->GetHotSpot().x_;
+
+                if (childElem.HasAttribute("pivot_y"))
+                    key.hotSpot_.y_ = childElem.GetFloat("pivot_y");
+                else
+                    key.hotSpot_.y_ = key.sprite_->GetHotSpot().y_;
+
+                if (childElem.HasAttribute("a"))
+                    key.alpha_ = childElem.GetFloat("a");
+            }
+
+            timeline.timelineKeys_.Push(key);
+        }
+
+        // Add end key for looped animation
+        if (looped && timeline.timelineKeys_.Back().time_ != length)
+        {
+            TimelineKey2D key = timeline.timelineKeys_.Front();
+            key.time_ = length;
+            timeline.timelineKeys_.Push(key);
+        }
+
+        animation->AddTimeline(timeline);
+    }
+
+    // Load main line
+    XMLElement mainlineElem = animationElem.GetChild("mainline");
+    for (XMLElement keyElem = mainlineElem.GetChild("key"); keyElem; keyElem = keyElem.GetNext("key"))
+    {
+        MainlineKey2D mainlineKey;
+        int id = keyElem.GetInt("id");
+        mainlineKey.time_ = keyElem.GetFloat("time") * 0.001f;
+
+        for (XMLElement refElem = keyElem.GetChild(); refElem; refElem = refElem.GetNext())
+        {
+            Reference2D ref;
+            
+            int refId = refElem.GetInt("id");
+            if (refElem.GetName() == "bone_ref")
+                ref.type_ = OT_BONE;
+            else
+                ref.type_ = OT_SPRITE;
+
+            ref.timeline_ = refElem.GetInt("timeline");
+
+            if (refElem.HasAttribute("parent"))
+            {
+                int parent = refElem.GetInt("parent");
+                int parentTimeline = mainlineKey.references_[parent].timeline_;
+                animation->SetTimelineParent(ref.timeline_, parentTimeline);
+            }
+            
+            if (refElem.GetName() == "object_ref")
+                ref.zIndex_ = refElem.GetInt("z_index");
+
+            mainlineKey.references_.Push(ref);
+        }
+
+        animation->AddMainlineKey(mainlineKey);
+    }
+
+    animations_.Push(animation);
+
+    return true;
+}
+
+
+}

+ 72 - 0
Source/Engine/Urho2D/AnimationSet2D.h

@@ -0,0 +1,72 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "Resource.h"
+
+namespace Urho3D
+{
+
+class XMLElement;
+class Sprite2D;
+class Animation2D;
+
+/// Spriter animation set, it includes one or more animations, for more information please refer to http://www.brashmonkey.com/spriter.htm.
+class URHO3D_API AnimationSet2D : public Resource
+{
+    OBJECT(AnimationSet2D);
+
+public:
+    /// Construct.
+    AnimationSet2D(Context* context);
+    /// Destruct.
+    virtual ~AnimationSet2D();
+    /// Register object factory. 
+    static void RegisterObject(Context* context);
+
+    /// Load resource. Return true if successful.
+    virtual bool Load(Deserializer& source);
+
+    /// Get number of animations.
+    unsigned GetNumAnimations() const;
+    /// Return animation by index.
+    Animation2D* GetAnimation(unsigned index) const;
+    /// Return animation by name.
+    Animation2D* GetAnimation(const String& name) const;
+
+private:
+    /// Load folders.
+    bool LoadFolders(const XMLElement& rootElem);
+    /// Load animation.
+    bool LoadAnimation(const XMLElement& animationElem);
+    /// Return sprite by folder id and file id.
+    Sprite2D* GetSprite(unsigned folderId, unsigned fileId) const;
+
+    /// Sprites.
+    HashMap<unsigned, SharedPtr<Sprite2D> > sprites_;
+    /// Animations.
+    Vector<SharedPtr<Animation2D> > animations_;
+};
+
+}
+

+ 41 - 4
Source/Engine/Urho2D/StaticSprite2D.cpp

@@ -38,7 +38,9 @@ StaticSprite2D::StaticSprite2D(Context* context) :
     Drawable2D(context),
     Drawable2D(context),
     flipX_(false),
     flipX_(false),
     flipY_(false),
     flipY_(false),
-    color_(Color::WHITE)
+    color_(Color::WHITE),
+    useHotSpot_(false),
+    hotSpot_(0.5f, 0.5f)
 {
 {
     vertices_.Reserve(6);
     vertices_.Reserve(6);
 }
 }
@@ -87,6 +89,30 @@ void StaticSprite2D::SetColor(const Color& color)
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
+void StaticSprite2D::SetUseHotSpot(bool useHotSpot)
+{
+    if (useHotSpot == useHotSpot_)
+        return;
+
+    useHotSpot_ = useHotSpot;
+    verticesDirty_ = true;
+    MarkNetworkUpdate();
+}
+
+void StaticSprite2D::SetHotSpot(const Vector2& hotspot)
+{
+    if (hotspot == hotSpot_)
+        return;
+
+    hotSpot_ = hotspot;
+
+    if (useHotSpot_)
+    {
+        verticesDirty_ = true;
+        MarkNetworkUpdate();
+    }
+}
+
 void StaticSprite2D::OnWorldBoundingBoxUpdate()
 void StaticSprite2D::OnWorldBoundingBoxUpdate()
 {
 {
     boundingBox_.Clear();
     boundingBox_.Clear();
@@ -145,9 +171,20 @@ void StaticSprite2D::UpdateVertices()
     float width = (float)rectangle_.Width() * PIXEL_SIZE;     // Compute width and height in pixels
     float width = (float)rectangle_.Width() * PIXEL_SIZE;     // Compute width and height in pixels
     float height = (float)rectangle_.Height() * PIXEL_SIZE;
     float height = (float)rectangle_.Height() * PIXEL_SIZE;
 
 
-    const Vector2& hotSpot = sprite_->GetHotSpot();
-    float hotSpotX = flipX_ ? (1.0f - hotSpot.x_) : hotSpot.x_;
-    float hotSpotY = flipY_ ? (1.0f - hotSpot.y_) : hotSpot.y_;
+    float hotSpotX;
+    float hotSpotY;
+
+    if (useHotSpot_)
+    {
+        hotSpotX = flipX_ ? (1.0f - hotSpot_.x_) : hotSpot_.x_;
+        hotSpotY = flipY_ ? (1.0f - hotSpot_.y_) : hotSpot_.y_;
+    }
+    else
+    {
+        const Vector2& hotSpot = sprite_->GetHotSpot();
+        hotSpotX = flipX_ ? (1.0f - hotSpot.x_) : hotSpot.x_;
+        hotSpotY = flipY_ ? (1.0f - hotSpot.y_) : hotSpot.y_;
+    }
 
 
     float leftX = -width * hotSpotX;
     float leftX = -width * hotSpotX;
     float rightX = width * (1.0f - hotSpotX);
     float rightX = width * (1.0f - hotSpotX);

+ 12 - 0
Source/Engine/Urho2D/StaticSprite2D.h

@@ -48,6 +48,10 @@ public:
     void SetFlipY(bool flipY);
     void SetFlipY(bool flipY);
     /// Set color.
     /// Set color.
     void SetColor(const Color& color);
     void SetColor(const Color& color);
+    /// Set use hot spot.
+    void SetUseHotSpot(bool useHotSpot);
+    /// Set hot spot.
+    void SetHotSpot(const Vector2& hotspot);
 
 
     /// Return flip X.
     /// Return flip X.
     bool GetFlipX() const { return flipX_; }
     bool GetFlipX() const { return flipX_; }
@@ -55,6 +59,10 @@ public:
     bool GetFlipY() const { return flipY_; }
     bool GetFlipY() const { return flipY_; }
     /// Return color.
     /// Return color.
     const Color& GetColor() const { return color_; }
     const Color& GetColor() const { return color_; }
+    /// Return use hot spot.
+    bool GetUseHotSpot() const { return useHotSpot_; }
+    /// Return hot spot.
+    const Vector2& GetHotSpot() const { return hotSpot_; }
 
 
 protected:
 protected:
     /// Recalculate the world-space bounding box.
     /// Recalculate the world-space bounding box.
@@ -68,6 +76,10 @@ protected:
     bool flipY_;
     bool flipY_;
     /// Color.
     /// Color.
     Color color_;
     Color color_;
+    /// Use hot spot.
+    bool useHotSpot_;
+    /// Hot spot.
+    Vector2 hotSpot_;
 };
 };
 
 
 }
 }

+ 7 - 5
Source/Engine/Urho2D/Urho2D.cpp

@@ -22,7 +22,7 @@
 
 
 #include "Precompiled.h"
 #include "Precompiled.h"
 #include "AnimatedSprite2D.h"
 #include "AnimatedSprite2D.h"
-#include "Animation2D.h"
+#include "AnimationSet2D.h"
 #include "CollisionBox2D.h"
 #include "CollisionBox2D.h"
 #include "CollisionChain2D.h"
 #include "CollisionChain2D.h"
 #include "CollisionCircle2D.h"
 #include "CollisionCircle2D.h"
@@ -65,17 +65,19 @@ void RegisterUrho2DLibrary(Context* context)
     MaterialCache2D::RegisterObject(context);
     MaterialCache2D::RegisterObject(context);
     DrawableProxy2D::RegisterObject(context);
     DrawableProxy2D::RegisterObject(context);
 
 
+    Sprite2D::RegisterObject(context);
+    SpriteSheet2D::RegisterObject(context);
+    
     // Must register objects from base to derived order
     // Must register objects from base to derived order
     Drawable2D::RegisterObject(context);
     Drawable2D::RegisterObject(context);
     StaticSprite2D::RegisterObject(context);
     StaticSprite2D::RegisterObject(context);
+
+    AnimationSet2D::RegisterObject(context);
     AnimatedSprite2D::RegisterObject(context);
     AnimatedSprite2D::RegisterObject(context);
-    Animation2D::RegisterObject(context);
+
     ParticleEffect2D::RegisterObject(context);
     ParticleEffect2D::RegisterObject(context);
     ParticleEmitter2D::RegisterObject(context);
     ParticleEmitter2D::RegisterObject(context);
 
 
-    Sprite2D::RegisterObject(context);
-    SpriteSheet2D::RegisterObject(context);
-
     PhysicsWorld2D::RegisterObject(context);
     PhysicsWorld2D::RegisterObject(context);
     RigidBody2D::RegisterObject(context);
     RigidBody2D::RegisterObject(context);
 
 

+ 5 - 7
Source/Samples/24_Urho2DSprite/Urho2DSprite.cpp

@@ -21,7 +21,7 @@
 //
 //
 
 
 #include "AnimatedSprite2D.h"
 #include "AnimatedSprite2D.h"
-#include "Animation2D.h"
+#include "AnimationSet2D.h"
 #include "Camera.h"
 #include "Camera.h"
 #include "CoreEvents.h"
 #include "CoreEvents.h"
 #include "Engine.h"
 #include "Engine.h"
@@ -117,9 +117,9 @@ void Urho2DSprite::CreateScene()
         spriteNodes_.Push(spriteNode);
         spriteNodes_.Push(spriteNode);
     }
     }
 
 
-    // Get animation
-    Animation2D* animation = cache->GetResource<Animation2D>("Urho2D/GoldIcon.anm");
-    if (!animation)
+    // Get animation set
+    AnimationSet2D* animationSet = cache->GetResource<AnimationSet2D>("Urho2D/GoldIcon.scml");
+    if (!animationSet)
         return;
         return;
 
 
     SharedPtr<Node> spriteNode(scene_->CreateChild("AnimatedSprite2D"));
     SharedPtr<Node> spriteNode(scene_->CreateChild("AnimatedSprite2D"));
@@ -127,9 +127,7 @@ void Urho2DSprite::CreateScene()
 
 
     AnimatedSprite2D* animatedSprite = spriteNode->CreateComponent<AnimatedSprite2D>();
     AnimatedSprite2D* animatedSprite = spriteNode->CreateComponent<AnimatedSprite2D>();
     // Set animation
     // Set animation
-    animatedSprite->SetAnimation(animation);
-    // Set blend mode
-    animatedSprite->SetBlendMode(BLEND_ALPHA);
+    animatedSprite->SetAnimation(animationSet, "idle");
 }
 }
 
 
 void Urho2DSprite::CreateInstructions()
 void Urho2DSprite::CreateInstructions()

+ 33 - 0
Source/Samples/33_Urho2DSpriterAnimation/CMakeLists.txt

@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2008-2014 the Urho3D project.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Define target name
+set (TARGET_NAME 33_Urho2DSpriterAnimation)
+
+# Define source files
+define_source_files (EXTRA_H_FILES ${COMMON_SAMPLE_H_FILES})
+
+# Setup target with resource copying
+setup_main_executable ()
+
+# Setup test cases
+add_test (NAME ${TARGET_NAME} COMMAND ${TARGET_NAME} -timeout ${URHO3D_TEST_TIME_OUT})

+ 193 - 0
Source/Samples/33_Urho2DSpriterAnimation/Urho2DSpriterAnimation.cpp

@@ -0,0 +1,193 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "AnimatedSprite2D.h"
+#include "AnimationSet2D.h"
+#include "Camera.h"
+#include "CoreEvents.h"
+#include "Drawable2D.h"
+#include "Engine.h"
+#include "Font.h"
+#include "Graphics.h"
+#include "Input.h"
+#include "Octree.h"
+#include "Renderer.h"
+#include "ResourceCache.h"
+#include "Scene.h"
+#include "Text.h"
+#include "Urho2DSpriterAnimation.h"
+#include "Zone.h"
+
+#include "DebugNew.h"
+
+static const char* animationNames[] =
+{
+    "idle",
+    "run",
+    "attack",
+    "hit",
+    "dead",
+    "dead2",
+    "dead3",
+};
+
+DEFINE_APPLICATION_MAIN(Urho2DSpriterAnimation)
+
+Urho2DSpriterAnimation::Urho2DSpriterAnimation(Context* context) :
+    Sample(context),
+    animationIndex_(0)
+{
+}
+
+void Urho2DSpriterAnimation::Start()
+{
+    // Execute base class startup
+    Sample::Start();
+
+    // Create the scene content
+    CreateScene();
+
+    // Create the UI content
+    CreateInstructions();
+
+    // Setup the viewport for displaying the scene
+    SetupViewport();
+
+    // Hook up to the frame update events
+    SubscribeToEvents();
+}
+
+void Urho2DSpriterAnimation::CreateScene()
+{
+    scene_ = new Scene(context_);
+    scene_->CreateComponent<Octree>();
+
+    // Create camera node
+    cameraNode_ = scene_->CreateChild("Camera");
+    // Set camera's position
+    cameraNode_->SetPosition(Vector3(0.0f, 0.0f, -10.0f));
+
+    Camera* camera = cameraNode_->CreateComponent<Camera>();
+    camera->SetOrthographic(true);
+
+    Graphics* graphics = GetSubsystem<Graphics>();
+    camera->SetOrthoSize((float)graphics->GetHeight() * PIXEL_SIZE);
+
+    ResourceCache* cache = GetSubsystem<ResourceCache>();  
+    AnimationSet2D* animationSet = cache->GetResource<AnimationSet2D>("Urho2D/imp/imp.scml");
+    if (!animationSet)
+        return;
+
+    spriteNode_ = scene_->CreateChild("SpriterAnimation");
+    spriteNode_->SetPosition(Vector3(-1.4f, 2.0f, 0.0f));
+
+    AnimatedSprite2D* animatedSprite = spriteNode_->CreateComponent<AnimatedSprite2D>();
+    animatedSprite->SetAnimation(animationSet, animationNames[animationIndex_]);
+}
+
+void Urho2DSpriterAnimation::CreateInstructions()
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    UI* ui = GetSubsystem<UI>();
+
+    // Construct new Text object, set string to display and font to use
+    Text* instructionText = ui->GetRoot()->CreateChild<Text>();
+    instructionText->SetText("Mouse click to play next animation, \nUse WASD keys to move, use PageUp PageDown keys to zoom.");
+    instructionText->SetFont(cache->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 15);
+
+    // Position the text relative to the screen center
+    instructionText->SetHorizontalAlignment(HA_CENTER);
+    instructionText->SetVerticalAlignment(VA_CENTER);
+    instructionText->SetPosition(0, ui->GetRoot()->GetHeight() / 4);
+}
+
+void Urho2DSpriterAnimation::SetupViewport()
+{
+    Renderer* renderer = GetSubsystem<Renderer>();
+
+    // Set up a viewport to the Renderer subsystem so that the 3D scene can be seen
+    SharedPtr<Viewport> viewport(new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>()));
+    renderer->SetViewport(0, viewport);
+}
+
+void Urho2DSpriterAnimation::MoveCamera(float timeStep)
+{
+    // Do not move if the UI has a focused element (the console)
+    if (GetSubsystem<UI>()->GetFocusElement())
+        return;
+
+    Input* input = GetSubsystem<Input>();
+
+    // Movement speed as world units per second
+    const float MOVE_SPEED = 4.0f;
+
+    // Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
+    if (input->GetKeyDown('W'))
+        cameraNode_->Translate(Vector3::UP * MOVE_SPEED * timeStep);
+    if (input->GetKeyDown('S'))
+        cameraNode_->Translate(Vector3::DOWN * MOVE_SPEED * timeStep);
+    if (input->GetKeyDown('A'))
+        cameraNode_->Translate(Vector3::LEFT * MOVE_SPEED * timeStep);
+    if (input->GetKeyDown('D'))
+        cameraNode_->Translate(Vector3::RIGHT * MOVE_SPEED * timeStep);
+
+    if (input->GetKeyDown(KEY_PAGEUP))
+    {
+        Camera* camera = cameraNode_->GetComponent<Camera>();
+        camera->SetZoom(camera->GetZoom() * 1.01f);
+    }
+
+    if (input->GetKeyDown(KEY_PAGEDOWN))
+    {
+        Camera* camera = cameraNode_->GetComponent<Camera>();
+        camera->SetZoom(camera->GetZoom() * 0.99f);
+    }
+}
+
+void Urho2DSpriterAnimation::SubscribeToEvents()
+{
+    // Subscribe HandleUpdate() function for processing update events
+    SubscribeToEvent(E_UPDATE, HANDLER(Urho2DSpriterAnimation, HandleUpdate));
+    SubscribeToEvent(E_MOUSEBUTTONDOWN, HANDLER(Urho2DSpriterAnimation, HandleMouseButtonDown));
+
+
+    // Unsubscribe the SceneUpdate event from base class to prevent camera pitch and yaw in 2D sample
+    UnsubscribeFromEvent(E_SCENEUPDATE);
+}
+
+void Urho2DSpriterAnimation::HandleUpdate(StringHash eventType, VariantMap& eventData)
+{
+    using namespace Update;
+
+    // Take the frame time step, which is stored as a float
+    float timeStep = eventData[P_TIMESTEP].GetFloat();
+
+    // Move the camera, scale movement with time step
+    MoveCamera(timeStep);
+}
+
+void Urho2DSpriterAnimation::HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
+{
+    AnimatedSprite2D* animatedSprite = spriteNode_->GetComponent<AnimatedSprite2D>();
+    animationIndex_ = (animationIndex_ + 1) % 7;
+    animatedSprite->SetAnimation(animationNames[animationIndex_]);
+}

+ 92 - 0
Source/Samples/33_Urho2DSpriterAnimation/Urho2DSpriterAnimation.h

@@ -0,0 +1,92 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "Sample.h"
+
+namespace Urho3D
+{
+    class Node;
+    class Scene;
+}
+
+/// Urho2D sprite example.
+/// This sample demonstrates:
+///     - Creating a 2D scene with spriter animation
+///     - Displaying the scene using the Renderer subsystem
+///     - Handling keyboard to move and zoom 2D camera
+class Urho2DSpriterAnimation : public Sample
+{
+    OBJECT(Urho2DSpriterAnimation);
+
+public:
+    /// Construct.
+    Urho2DSpriterAnimation(Context* context);
+
+    /// Setup after engine initialization and before running the main loop.
+    virtual void Start();
+
+protected:
+    /// Return XML patch instructions for screen joystick layout for a specific sample app, if any.
+    virtual String GetScreenJoystickPatchString() const { return
+        "<patch>"
+        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/attribute[@name='Is Visible']\" />"
+        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Zoom In</replace>"
+        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]\">"
+        "        <element type=\"Text\">"
+        "            <attribute name=\"Name\" value=\"KeyBinding\" />"
+        "            <attribute name=\"Text\" value=\"PAGEUP\" />"
+        "        </element>"
+        "    </add>"
+        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/attribute[@name='Is Visible']\" />"
+        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Zoom Out</replace>"
+        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]\">"
+        "        <element type=\"Text\">"
+        "            <attribute name=\"Name\" value=\"KeyBinding\" />"
+        "            <attribute name=\"Text\" value=\"PAGEDOWN\" />"
+        "        </element>"
+        "    </add>"
+        "</patch>";
+    }
+
+private:
+    /// Construct the scene content.
+    void CreateScene();
+    /// Construct an instruction text to the UI.
+    void CreateInstructions();
+    /// Set up a viewport for displaying the scene.
+    void SetupViewport();
+    /// Read input and moves the camera.
+    void MoveCamera(float timeStep);
+    /// Subscribe to application-wide logic update events.
+    void SubscribeToEvents();
+    /// Handle the logic update event.
+    void HandleUpdate(StringHash eventType, VariantMap& eventData);
+    /// Handle mouse button down event.
+    void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData);
+
+    /// Sprite nodes.
+    SharedPtr<Node> spriteNode_;
+    /// Animation index.
+    int animationIndex_;
+};

+ 1 - 0
Source/Samples/CMakeLists.txt

@@ -70,3 +70,4 @@ add_subdirectory (29_SoundSynthesis)
 add_subdirectory (30_LightAnimation)
 add_subdirectory (30_LightAnimation)
 add_subdirectory (31_MaterialAnimation)
 add_subdirectory (31_MaterialAnimation)
 add_subdirectory (32_Urho2DConstraints)
 add_subdirectory (32_Urho2DConstraints)
+add_subdirectory (33_Urho2DSpriterAnimation)