Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Actual, Basic Example of using Spine in Corona?
Started by richard9 Sep 30 2013 04:40 AM

14 replies to this topic
spine basics
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Corona Geek

  • 1,118 posts
  • Enterprise

So, really struggling here and could use some guidance. I just need to know the most basic method to get an animation on screen using Spine.

 

-- Require in the spine manager
local spine = require ("spine-corona.spine")

-- Extract animation data from Json
-- Assume it's in a folder called "anim" and is named "skeleton.json"
local json = spine.SkeletonJson.new()
local data = json:readSkeletonDataFile("anim/skeleton.json")

-- Make the skeleton using this data
local char = spine.Skeleton.new( data )

-- Fetch the idle animation
local idle = data:findAnimation( "idle" )

-- Overwrite how spine creates bone animations.
-- Assume seperate images; no imageSheets.
function char:createImage(attachment)
    return display.newImage("anim/"..attachment.name..".png")
end

-- Set the animation state
-- If I remove this line, Corona loads with no error messages, 
-- but there is no character on-screen.
idle.apply( char, nil, true)

 

 

Unfortunately, idle.apply complains that char (the skeleton) is nil. (It's not - a print statement confirms it.) However, looking at the animationState code, it's looking for "skeleton.skeletonData", which doesn't seem to exist.

 

Where am I going wrong? The esoteric sample code is nice but I don't have animations to blend together. Just a single skeleton with a single animation to play.

 



[TOPIC: post.html]
#2

Reaver

[GLOBAL: userInfoPane.html]
Reaver
  • Enthusiast

  • 87 posts
  • Corona SDK

Hi!

 

I'm not sure this will solve the problem but apply should be called on the animation so it should be idle:apply(char, time, true). This leads me to believe that the idle variable is nil in the example.

 

You will also need to execute apply in a loop which increments a timer so that the animation can change based on the time change and then call skeleton:updateWorldTransform() afterwards to draw the change in animation. This is typically a runtime listener that gets executed on the "enterframe" event.

 

Let me know if anything is unclear :)



[TOPIC: post.html]
#3

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Corona Geek

  • 1,118 posts
  • Enterprise

idle is not nil; not only is there no error on finding the animation, but it shows up (properly) as a table if you use a print statement.

 

If I apply an actual number to the time variable (ie: 1000) Animation.lua reports an error with ipairs() on line 49. If I move the apply command to a Runtime loop (ie: the one shown in the sample code provided by Esoteric) the same error occurs. 

 

Totally stuck here... :(



[TOPIC: post.html]
#4

Reaver

[GLOBAL: userInfoPane.html]
Reaver
  • Enthusiast

  • 87 posts
  • Corona SDK

Did using : instead of . provide any useful results at least? :P 

 

I'm not sure if it's necessary but I also run skeleton:setToSetupPose() before doing anything else with animations for example (just because it was done in the spine example). It might be the setup that is needed. 



[TOPIC: post.html]
#5

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Corona Geek

  • 1,118 posts
  • Enterprise

Well, you're right, I completely forgot to use : instead of ., which is a historical weakness of mine. But when I do that, I get:

 

/spine-lua/Animation.lua:221: attempt to perform arithmetic on field 'rotation' (a nil value)
(That line: amount = bone.data.rotation + (lastFrameValue + amount * percent) - bone.rotation )

 

...which strikes me as a legit bug in the Spine implementation or how it exports data.  

 

Investigating the variables, bone.data.rotation exists, while bone.rotation does not. 'bone' does exist, however.



[TOPIC: post.html]
#6

Reaver

[GLOBAL: userInfoPane.html]
Reaver
  • Enthusiast

  • 87 posts
  • Corona SDK

I think everyone does that :P It's usually the first thing I check for when I get an error that a variable that I know has a value is reported of having a nil value.

 

I think calling skeleton:setToSetupPose() should initialize the bone fields including rotation. It should be called towards the end of the setup code and definitely before the animation is applied.



[TOPIC: post.html]
#7

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Corona Geek

  • 1,118 posts
  • Enterprise

Reaver, you're absolutely right - setToSetupPose() does add those values. Crazy that it's not just added while making the skeleton, but okay.

 

So now the project loads without errors...but there is nothing on-screen. (I know from experience that if I feed the wrong path/filename to :createImage() that I would get an error, so it's finding the right assets.)  I have the Runtime loop running like this:

 

local lastTime = 0
local animationTime = 0
Runtime:addEventListener("enterFrame", function (event)
  
  -- Compute time in seconds since last frame.
  local currentTime = event.time / 1000
  local delta = currentTime - lastTime
  lastTime = currentTime

  -- Update the state with the delta time, apply it, and update the world transforms.
  idle:apply( char, delta, true )
  char:updateWorldTransform()
end)

 

What am I missing to actually see anything?



[TOPIC: post.html]
#8

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Corona Geek

  • 1,118 posts
  • Enterprise

Self update: It seems that the spine character is set to have a bottom reference point.

 

skeleton.group.x = display.contentCenterX
skeleton.group.y = display.contentHeight

 

 

That gets my character visible! The only problem? There's no animation at all (despite the Runtime listener). So it seems that the code above (previous post) is not enough to animate?



[TOPIC: post.html]
#9

Reaver

[GLOBAL: userInfoPane.html]
Reaver
  • Enthusiast

  • 87 posts
  • Corona SDK

Nice. I think you might want to have an animationTime variable that you add the delta value to

 

local animationTime = 0

 

then in render loop:

 

animationTIme = animationTime + delta

idle:apply(char, animationTime, true)

 

 

Right now if delta is roughly the same value each frame the animation will be set to the same state each time the apply is called. Apply sets the skeleton rig to a state based on the time. If the time is the same each time apply is called the skeleton will be set to the same pose.



[TOPIC: post.html]
#10

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Corona Geek

  • 1,118 posts
  • Enterprise

You're right. That did it. It's animating! Thanks Reaver!

 

Now to begin writing replacement code so Corona users can use this stuff without being bogged down in the details.



[TOPIC: post.html]
#11

Reaver

[GLOBAL: userInfoPane.html]
Reaver
  • Enthusiast

  • 87 posts
  • Corona SDK

No problem!

 

You should also look at animationState. It removes some of the details and sets up a queue for animations.



[TOPIC: post.html]
#12

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Corona Geek

  • 1,118 posts
  • Enterprise

Yeah, I suppose my beef was that if you only have one animation, animationState is completely counterproductive. But I will take a look asap.



[TOPIC: post.html]
#13

Esoteric Software

[GLOBAL: userInfoPane.html]
Esoteric Software
  • Observer

  • 20 posts
  • Corona SDK

I've fixed Bone not have SRT values by default. Sorry I didn't see this earlier, I'm more active on the Spine forums.



[TOPIC: post.html]
#14

AnarchyApp-Starpond

[GLOBAL: userInfoPane.html]
AnarchyApp-Starpond
  • Observer

  • 5 posts
  • Corona SDK

Hi everyone, could someone put up the final Corona code for a basic example using Spine that works.



[TOPIC: post.html]
#15

Esoteric Software

[GLOBAL: userInfoPane.html]
Esoteric Software
  • Observer

  • 20 posts
  • Corona SDK

There are three examples in the spine-corona project on github. :)




[topic_controls]
[/topic_controls]