Advanced sprite animation

Hey guys, I have a little problem with the sprite api and would like to hear your suggestions.
In my previous games or prototypes I did never use the sprite api so in this section I am a absolute beginner.

I have read the blog post about the new sprite methods by Brent Sorrentino ( http://www.coronalabs.com/blog/2012/10/02/animated-sprites-and-methods/ ) and tried to include them into my game.

At first I show you how it should work and then I show you how I tried to make it work :wink:

The frame change should correspond to the y speed. The middle frame (7) should be drawn at the highest point in the jump arc, and the last frame(15) should be drawn when his y position is equal to his starting position(where he jumped from). Once the animation finishes, if the player is still falling, the last 3 frames could be used in a sweep loop (16,15,14,15,16,15,14, ect…).


At the very first I would declare some sequences (This is just theoretical!)

Note: I use two different imagesheets, one for the running and one for the jumping animation.

[code]local sequenceData = {

{ name = “Run”, start = 1, count = 16, time = 800 },
{ name = “jumpBegin”, start = 1, count = 7, time = 400 },
{ name = “midJump”, start = 8, count = 9, time = 450 },
{ name = “falling”, frames = { 16, 15, 14, 15, 16, 15, 14 }, loopCount = 1 }

[/code]

After that I create the player:

local player = display.newSprite(mySheet, sequenceData)

You can see that this sprite uses only the imagesheet “mySheet”, there may be conflicts with the second imagesheet…

Now I create the jump function (it starts with a button touch) :

local function onButtonJumpEvent(event) if event.phase == "began" then player:setLinearVelocity(0, -250) end end

This makes the player jump, nothing wrong with it. I have some sort of “if player.isGround == true” condition but I want to focus on the important things.

–

And now… the most important function for the player animations - the function that handles all the different sequences…

This is the point were I get stuck! I can check the players current y-speed by using the following:

[code]local function checkVelocity()
local vx, vy = player:getLinearVelocity()

end [/code]

… but I have some problems with the next steps. How do I change between different imagesheets and when do I have to change the sequences? Or do I have to use a completely different method?

I have already tried to change the sequences but sometimes the animation stopped or got stuck at one frame.

If you have any suggestions please feel free to answer :slight_smile:

Best Regards,

Max / CineTek [import]uid: 138330 topic_id: 31775 reply_id: 331775[/import]

Hi Max,

This is a fairly complicated scenario, but certainly it should be achievable…

First, can you combine your running and jumping frames into one image sheet instead of two? I don’t think the current sprite API allows for “multi-sprites”, that is, a single sprite object that pulls sequences from different sheets. I believe that is planned for a future release, but it’s not currently implemented.

You could potentially change image sheets by deleting the current sprite and replacing it with a new one, but it’s more complicated. Ideally you should combine your sheets.

Now, in regards to the jump… you say that the frames “correspond with the y speed”. Do your jump heights vary? If so, should the jump frames be “evenly divided” along the total height?

For example, if there are 7 animation frames in the upward arc, and the total height varies, should it always switch to frame #2 at 1/7th the way up, frame #3 at 2/7th the way up, frame #4 at 3/7th the way up, etc.? If this is the case, you should detect your “frame change points” mathematically during the “checkVelocity” Runtime listener… that’s fairly complicated but I’m sure there’s a method. Then, on each altitude point along the upward arc, you just switch to the appropriate frame using player:setFrame( frame ). In effect, you’d be manually changing frames instead of starting a timed sequence. Downward arc would be the same method.

Now, if your scenario is slightly more simple, in that you just need to start a timed sequence at the start, peak, and end of the jump, I think you’ve already figured that part out. Just change the sequence using player:setSequence( sequenceName )

Remember that you need to PLAY a sequence every time you change it! It will not start playing automatically. I mentioned this in my tutorial but maybe it wasn’t clear enough.

I think the bigger challenge for you isn’t the sprite methods, but determining when in the jump you need to trigger a sequence change. Monitoring linear Y velocity is a fine approach, but remember that you’ll probably get small values at both the beginning AND the end of the physical jump… as the player accelerates from the ground, and as the player decelerates from the effect of gravity at the arc top. You’ll need to somehow determine that the “midJump” sequence change doesn’t happen until the TOP, and never trigger it near the jump beginning.

That was a mouthful! Hopefully this helps though… you’re on the right track, you just need to fine-tune your sensory method.

Brent Sorrentino
[import]uid: 9747 topic_id: 31775 reply_id: 126936[/import]

Hi Brent,

Thanks! It definitive helps me out. Yes, I was struggeling with the right moment to trigger the different events but now I should be able to solve my problem.

One thing that might still cause problems is the single imagesheet. Because of maimal compatibility with the new iPad and bigger screens, my animations are very big - up to 320x384 px per frame. But I think that I can easily scale them down.

I will take your suggestions with the jump arcs and try them out. The easy method just works fine, but it does not look as smooth as expected. So I will use the more complex method and work with the “frame change points”.

Thanks, again!

Max

[import]uid: 138330 topic_id: 31775 reply_id: 126953[/import]

Hi Max,

This is a fairly complicated scenario, but certainly it should be achievable…

First, can you combine your running and jumping frames into one image sheet instead of two? I don’t think the current sprite API allows for “multi-sprites”, that is, a single sprite object that pulls sequences from different sheets. I believe that is planned for a future release, but it’s not currently implemented.

You could potentially change image sheets by deleting the current sprite and replacing it with a new one, but it’s more complicated. Ideally you should combine your sheets.

Now, in regards to the jump… you say that the frames “correspond with the y speed”. Do your jump heights vary? If so, should the jump frames be “evenly divided” along the total height?

For example, if there are 7 animation frames in the upward arc, and the total height varies, should it always switch to frame #2 at 1/7th the way up, frame #3 at 2/7th the way up, frame #4 at 3/7th the way up, etc.? If this is the case, you should detect your “frame change points” mathematically during the “checkVelocity” Runtime listener… that’s fairly complicated but I’m sure there’s a method. Then, on each altitude point along the upward arc, you just switch to the appropriate frame using player:setFrame( frame ). In effect, you’d be manually changing frames instead of starting a timed sequence. Downward arc would be the same method.

Now, if your scenario is slightly more simple, in that you just need to start a timed sequence at the start, peak, and end of the jump, I think you’ve already figured that part out. Just change the sequence using player:setSequence( sequenceName )

Remember that you need to PLAY a sequence every time you change it! It will not start playing automatically. I mentioned this in my tutorial but maybe it wasn’t clear enough.

I think the bigger challenge for you isn’t the sprite methods, but determining when in the jump you need to trigger a sequence change. Monitoring linear Y velocity is a fine approach, but remember that you’ll probably get small values at both the beginning AND the end of the physical jump… as the player accelerates from the ground, and as the player decelerates from the effect of gravity at the arc top. You’ll need to somehow determine that the “midJump” sequence change doesn’t happen until the TOP, and never trigger it near the jump beginning.

That was a mouthful! Hopefully this helps though… you’re on the right track, you just need to fine-tune your sensory method.

Brent Sorrentino
[import]uid: 9747 topic_id: 31775 reply_id: 126936[/import]

Hi Brent,

Thanks! It definitive helps me out. Yes, I was struggeling with the right moment to trigger the different events but now I should be able to solve my problem.

One thing that might still cause problems is the single imagesheet. Because of maimal compatibility with the new iPad and bigger screens, my animations are very big - up to 320x384 px per frame. But I think that I can easily scale them down.

I will take your suggestions with the jump arcs and try them out. The easy method just works fine, but it does not look as smooth as expected. So I will use the more complex method and work with the “frame change points”.

Thanks, again!

Max

[import]uid: 138330 topic_id: 31775 reply_id: 126953[/import]