Flesh out the sprite documentation
authorAlan Alpert <alan.alpert@nokia.com>
Fri, 11 May 2012 09:38:49 +0000 (19:38 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 14 May 2012 03:36:33 +0000 (05:36 +0200)
Task-number: QTBUG-24770

Change-Id: I40c46aa29ffdcc5899bece46c4b6227ca29695cd
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/particles/qquickimageparticle.cpp
src/quick/doc/images/spritecutting.png [new file with mode: 0644]
src/quick/doc/images/spriteenginegraph.png [new file with mode: 0644]
src/quick/doc/src/elements.qdoc
src/quick/doc/src/sprites.qdoc [new file with mode: 0644]
src/quick/items/qquickanimatedsprite.cpp
src/quick/items/qquicksprite.cpp
src/quick/items/qquickspritesequence.cpp

index c0b0e8e..80420ee 100644 (file)
@@ -625,6 +625,8 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size)
 
     Note that the sprite image will be scaled to a square based on the size of
     the particle being rendered.
 
     Note that the sprite image will be scaled to a square based on the size of
     the particle being rendered.
+
+    For full details, see the \l{Sprite Animation} overview.
 */
 /*!
     \qmlproperty url QtQuick.Particles2::ImageParticle::colorTable
 */
 /*!
     \qmlproperty url QtQuick.Particles2::ImageParticle::colorTable
diff --git a/src/quick/doc/images/spritecutting.png b/src/quick/doc/images/spritecutting.png
new file mode 100644 (file)
index 0000000..1958ee2
Binary files /dev/null and b/src/quick/doc/images/spritecutting.png differ
diff --git a/src/quick/doc/images/spriteenginegraph.png b/src/quick/doc/images/spriteenginegraph.png
new file mode 100644 (file)
index 0000000..ef09df4
Binary files /dev/null and b/src/quick/doc/images/spriteenginegraph.png differ
index 63fcd1a..4053386 100644 (file)
@@ -50,11 +50,13 @@ two elements.
 \li \l {Rectangle} - A rectangle element
 \li \l {Image} - For incorporating bitmaps into a scene
 \li \l {BorderImage} - Allows the use of images as borders
 \li \l {Rectangle} - A rectangle element
 \li \l {Image} - For incorporating bitmaps into a scene
 \li \l {BorderImage} - Allows the use of images as borders
-\li \l {AnimatedImage} - For playing animations stored in a series of frames
+\li \l {AnimatedSprite} - For playing animations stored as a series of frames
+\li \l {AnimatedImage} - For playing animations stored as an animated GIF
 \li \l {Gradient} - For defining a color gradient
 \li \l {GradientStop} - Used to define a color within a \l {Gradient}
 \li \l {SystemPalette} - Provides access to the Qt palettes
 \li \l {Canvas} - Provides a 2D canvas element
 \li \l {Gradient} - For defining a color gradient
 \li \l {GradientStop} - Used to define a color within a \l {Gradient}
 \li \l {SystemPalette} - Provides access to the Qt palettes
 \li \l {Canvas} - Provides a 2D canvas element
+\li \l {SpriteSequence} - For playing and transitioning between multiple animations stored as a series of frames
 \endlist
 
 \section1 Text Handling
 \endlist
 
 \section1 Text Handling
diff --git a/src/quick/doc/src/sprites.qdoc b/src/quick/doc/src/sprites.qdoc
new file mode 100644 (file)
index 0000000..e59b308
--- /dev/null
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qtquick-spriteengine.html
+\ingroup qml-features
+\title Sprite Animations
+\brief Sprite-based animations with flexible transitioning
+
+\section1 Sprite Engine
+
+The QtQuick sprite engine is a stochastic state machine combined with the ability
+to chop up images containing multiple frames of an animation.
+
+\section2 State Machine
+
+A primary function of the sprite engine is its internal state machine. This is not the same as
+the states and transitions in Qt Quick, and is more like a conventional state machine. Sprites
+can have weighted transitions to other sprites, or back to themselves. When a sprite animation
+finishes, the sprite engine will choose the next sprite randomly, based on the weighted transitions
+available for the sprite that just finished.
+
+You can affect the currently playing sprite in two ways. You can arbitrarily force it to immediately
+start playing any sprite, or you can tell it to gradually transition to a given sprite. If you
+instruct it to gradually transition, then it will reach the target sprite by going through valid
+state transitions using the fewest number of intervening sprites (but ignoring relative weightings).
+This allows you to easily insert a transitional animation between two different sprites.
+
+\image spriteenginegraph.png
+
+As an example, consider the above diagram which illustrates the sprites for a hypothetical 2D
+platform game character. The character starts by displaying the standing state. From this state,
+barring external input, he will transition to either the waiting animation, the walking animation,
+or play the standing animation again. Because the weights for those transitions are one, zero and three
+respectively, he has a one in four chance of playing the waiting animation when the standing animation
+finishes, and a three in four chance of playing the standing animation again. This allows for a character
+who has a slightly animated and variable behavior while waiting.
+
+Because there is a zero weight transition to the walking animation, the standing animation will not normally
+transition there. But if you set the goal animation to be the walking animation, it would play the walking
+animation when it finished the standing animation. If it was previously in the waiting animation, it would
+finish playing that, then play the standing animation, then play the walking animation. It would then continue to
+play the walking animation until the goal animation is unset, at which point it would switch to the standing
+animation after finishing the walking animation.
+
+If you set the goal state then to the jumping animation, it would finish the walking animation before
+playing the jumping animation. Because the jumping animation does not transition to other states, it will still
+keep playing the jumping animation until the state is forced to change. In this example, you could set it back to
+walking and change to goal animation to walking or to nothing (which would lead it to play the standing animation
+after the walking animation). Note that by forcibly setting the animation, you can start playing the animation
+immediately.
+
+\section2 Input Format
+
+The file formats accepted by the sprite engine is the same as the file formats accepted by other QML elements,
+such as \l Image. In order to animate the image however, the sprite engine requires the image file to contain
+all of the frames of the animation. They should be arranged in a contiguous line, which may wrap from the right
+edge of the file to a lower row starting from the left edge of the file (and which is placed directly below the
+previous row).
+
+\image spritecutting.png
+
+As an example, take the above image. For now just consider the black numbers, and assume the squares are 40x40 pixels.
+Normally, the image is read from the top-left corner. If you specified the frame size as 40x40 pixels, and a frame count
+of 8, then it would read in the frames as they are numbered. The frame in the top left would be the first frame, the frame
+in the top right would be the fifth frame, and then it would wrap to the next row (at pixel location 0,40 in the file) to read
+the sixth frame. It would stop reading after the frame marked 8, and if there was any image data in the square below frame four
+then it would not be included in the animation.
+
+It is possible to load animations from an arbitrary offset, but they will still follow the same pattern.
+Consider now the red numbers. If we specify that the animation begins at pixel location 120,0, with a
+frame count of 5 and the same frame size as before, then it will load the frames as they are numbered in red.
+The first 120x40 of the image will not be used, as it starts reading 40x40 blocks from the location of 120,0.
+When it reaches the end of the file at 160,0, it then starts to read the next row from 0,40.
+
+The blue numbers show the frame numbers if you tried to load two frames of that size, starting from 40,40. Note
+that it is possible to load multiple sprites out of the one image file. The red, blue and black numbers can all
+be loaded as separate animations to the same sprite engine. The following code loads the animations as per the image.
+It also specifies that animations are to played at 20 frames per second.
+
+\code
+Sprite {
+    name: "black"
+    source: "image.png"
+    frameCount: 8
+    frameWidth: 40
+    frameHeight: 40
+    frameRate: 20
+}
+Sprite {
+    name: "red"
+    source: "image.png"
+    frameX: 120
+    frameCount: 5
+    frameWidth: 40
+    frameHeight: 40
+    frameRate: 20
+}
+Sprite {
+    name: "blue"
+    source: "image.png"
+    frameX: 40
+    frameX: 40
+    frameCount: 2
+    frameWidth: 40
+    frameHeight: 40
+    frameRate: 20
+}
+\endcode
+
+Frames within one animation must be the same size, however multiple animations within the same file
+do not. Sprites without a frameCount specified assume that they take the entire file, and you must specify
+the frame size. Sprites without a frame size assume that they are square and take the entire file without wrapping,
+and you must specify a frame count.
+
+The sprite engine internally copies and cuts up images to fit in an easier to read internal format, which leads
+to some graphics memory limitations. Because it requires all the sprites for a single engine to be in the same
+texture, attempting to load many different animations can run into texture memory limits on embedded devices. In
+these situations, a warning will be output to the console containing the maximum texture size.
+
+There are several software tools to help turn images into sprite sheets, here are some examples:
+Photoshop plugin:
+http://www.personal.psu.edu/zez1/blogs/my_blog/2011/05/scripts-4-photoshop-file-sequence-to-layers-to-sprite-sheet.html
+Gimp plugin:
+http://registry.gimp.org/node/20943
+Cmd-line tool:
+http://www.imagemagick.org/script/montage.php
+
+
+\section2 Elements Using the Sprite Engine
+
+Sprites for the sprite engine can be defined using the \l Sprite element. This element includes the input parameters
+as well as the length of the animation and weighted transitions to other animations. It is purely a data class, and
+does not render anything.
+
+\l SpriteSequence is an element which uses a sprite engine to draw the sprites defined in it. It is a single and
+self-contained sprite engine, and does not interact with other sprite engines. \l Sprite elements can be shared between
+sprite engine using elements, but this is not done automatically. So if you have defined a sprite in one \l SpriteSequence
+you will need to redefine it (or reference the same \l Sprite element) in the sprites property of another \l SpriteSequence
+in order to transition to that animation.
+
+Additionally, \l ImageParticle can use \l Sprite elements to define sprites for each particle. This is again a single
+sprite engine per element. This works similarly to SpriteSequence, but it also has the parametrized variability provided
+by the \l ImageParticle element.
+
+\section1 AnimatedSprite
+
+For use-cases which do not need to transition between animations, consider the \l AnimatedSprite element.
+This element displays sprite animations with the same input format, but only one at a time. It also provides more fine-grained
+manual control, as there is no sprite engine managing the timing and transitions behind the scenes.
+
+*/
index 2049001..a5e5d99 100644 (file)
@@ -215,6 +215,14 @@ struct AnimatedSpriteVertices {
     \inqmlmodule QtQuick 2
     \inherits Item
     \brief The AnimatedSprite element draws a sprite animation
     \inqmlmodule QtQuick 2
     \inherits Item
     \brief The AnimatedSprite element draws a sprite animation
+
+    AnimatedSprite provides rendering and control over animations which are provided
+    as multiple frames in the same image file. You can play it at a fixed speed, at the
+    frame rate of your display, or manually advance and control the progress.
+
+    For details of how a sprite animation is defined see the \l{Sprite Animation} overview.
+    Note that the AnimatedSprite element does not use Sprite elements to define multiple animations,
+    but instead encapsulates a single animation itself.
 */
 
 /*!
 */
 
 /*!
index 724bf8f..8b77d23 100644 (file)
@@ -54,16 +54,7 @@ QT_BEGIN_NAMESPACE
     can be in the middle of an image file, or split along multiple rows, as long as they form
     a contiguous line wrapping to the next row of the file from the left edge of the file.
 
     can be in the middle of an image file, or split along multiple rows, as long as they form
     a contiguous line wrapping to the next row of the file from the left edge of the file.
 
-    Sprites within one animation must be the same size, however sprites within the same file
-    do not. Sprites without a frameCount specified assume that they take the entire file.
-
-    There are several software tools to help turn images into sprite sheets, here are some examples:
-    Photoshop plugin:
-    http://www.personal.psu.edu/zez1/blogs/my_blog/2011/05/scripts-4-photoshop-file-sequence-to-layers-to-sprite-sheet.html
-    Gimp plugin:
-    http://registry.gimp.org/node/20943
-    Cmd-line tool:
-    http://www.imagemagick.org/script/montage.php
+    For full details, see the \l{Sprite Animation} overview.
 */
 /*!
     \qmlproperty int QtQuick2::Sprite::duration
 */
 /*!
     \qmlproperty int QtQuick2::Sprite::duration
index 80dad16..7f7d1cc 100644 (file)
@@ -215,6 +215,10 @@ struct SpriteVertices {
     \inherits Item
     \brief The SpriteSequence element draws a sprite animation
 
     \inherits Item
     \brief The SpriteSequence element draws a sprite animation
 
+    SpriteSequence renders and controls a list of animations defined
+    by \l Sprite elements.
+
+    For full details, see the \l{Sprite Animation} overview.
 */
 /*!
     \qmlproperty bool QtQuick2::SpriteSequence::running
 */
 /*!
     \qmlproperty bool QtQuick2::SpriteSequence::running