Saturday, January 12, 2013

Sprite animation from sprite sheet with BB10 Cascades QML

In past I have posted solution for how to achieve sprite animation from sprite sheet with Qt C++ widget framework and with QML framework.

I tried to do the same with BB10 Cascades QML. Final output will look like below.


While it was quite straight forward to achieve this with Qt or QML, with Cascades you will need to tweak few things, like desabling the implicit Cascades animation and enabling cliping.

Following is my code for the dragon sprite.

        Container {
            id: sprite;
            preferredHeight: 100;
            preferredWidth: 100;
            clipContentToBounds: true
            horizontalAlignment: HorizontalAlignment.Center
            verticalAlignment: VerticalAlignment.Center
            layout: AbsoluteLayout {}  
            
            onCreationCompleted: {
                timer.timeout.connect(renderNextFrame);
                timer.start(200);
            }
                        
            function renderNextFrame() {
                dragonSprite.currentFrame = 
                      (dragonSprite.currentFrame + 1) % dragonSprite.frameCount;
                dragonSprite.translationX = 
                     -(dragonSprite.currentFrame * sprite.preferredWidth);
            }
                              
            ImageView{
                id: dragonSprite
                imageSource: "dragon.png"
                scalingMethod: ScalingMethod.AspectFill
                preferredHeight: 100
                preferredWidth: 500 
                property int currentFrame: 0
                property int frameCount: 5
                
                attachedObjects: [
                    ImplicitAnimationController {
                        propertyName: "translationX"
                        enabled: false
                    }
                ]  
            }
        }
First, I am creating parent Container which will hold ImageView with sprite sheet as image source.

We need enable clipping by setting clipContentToBounds to true so only certain portion of image is visible not whole image and also need to set preferredHeight, preferredWidth to indicate clip region.

Then I am attaching the renderNextFrame function with timeout signal. renderNextFrame takes care of which frame to display by changing current frame and translating the image view accordingly.

Second, I am creating ImageView with sprite sheet image as image source. We need to set scalingMethod to ScalingMethod.AspectFill so that unnecessary scaling is not performed. Again we need to set preferredWidth, preferredHeight so that proper frame is displayed.

I am also storing max frame count and current frame number with image.

And finally we need to disable the implicit animation for translationX property. Without this you will not be able to achieve smooth sprite animation. We can use ImplicitAnimationController element to disable implicit animation. However it allows only certain property to be disabled. Here is documentation about ImplicitAnimationController.

Once this is done, you will be able to see smooth animation.

No comments:

Post a Comment