1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the Declarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquicksprite_p.h"
48 \qmlclass Sprite QQuickSprite
49 \inqmlmodule QtQuick 2
50 \brief The Sprite element represents a sprite animation
52 QQuickSprite renders sprites of one or more frames and animates them. The sprites
53 can be in the middle of an image file, or split along multiple rows, as long as they form
54 a contiguous line wrapping to the next row of the file from the left edge of the file.
56 Sprites within one animation must be the same size, however sprites within the same file
57 do not. Sprites without a frameCount specified assume that they take the entire file.
59 There are several software tools to help turn images into sprite sheets, here are some examples:
61 http://www.personal.psu.edu/zez1/blogs/my_blog/2011/05/scripts-4-photoshop-file-sequence-to-layers-to-sprite-sheet.html
63 http://registry.gimp.org/node/20943
65 http://www.imagemagick.org/script/montage.php
68 \qmlproperty int QtQuick2::Sprite::duration
70 Duration of the animation. Values below 0 are invalid.
72 If frameRate is valid then it will be used to calculate the duration of the frames.
73 If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used.
76 \qmlproperty int QtQuick2::Sprite::durationVariation
78 The duration of the animation can vary by up to this amount. Variation will never decrease the
79 length of the animation to less than 0.
81 durationVariation will only take effect if duration is
82 used to calculate the duration of frames.
88 \qmlproperty qreal QtQuick2::Sprite::frameRate
90 Frames per second to show in the animation. Values below 0 are invalid.
92 If frameRate is valid then it will be used to calculate the duration of the frames.
93 If not, and frameDuration is valid , then frameDuration will be used. Otherwise duration is used.
96 \qmlproperty qreal QtQuick2::Sprite::frameRateVariation
98 The frame rate between animations can vary by up to this amount. Variation will never decrease the
99 length of the animation to less than 0.
101 frameRateVariation will only take effect if frameRate is
102 used to calculate the duration of frames.
108 \qmlproperty int QtQuick2::Sprite::frameDuration
110 Duration of each frame of the animation. Values below 0 are invalid.
112 If frameRate is valid then it will be used to calculate the duration of the frames.
113 If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used.
116 \qmlproperty int QtQuick2::Sprite::frameDurationVariation
118 The duration of a frame in the animation can vary by up to this amount. Variation will never decrease the
119 length of the animation to less than 0.
121 frameDurationVariation will only take effect if frameDuration is
122 used to calculate the duration of frames.
128 \qmlproperty string QtQuick2::Sprite::name
130 The name of this sprite, for use in the to property of other sprites.
133 \qmlproperty QVariantMap QtQuick2::Sprite::to
135 A list of other sprites and weighted transitions to them,
136 for example {"a":1, "b":2, "c":0} would specify that one-third should
137 transition to sprite "a" when this sprite is done, and two-thirds should
138 transition to sprite "b" when this sprite is done. As the transitions are
139 chosen randomly, these proportions will not be exact. With "c":0 in the list,
140 no sprites will randomly transition to "c", but it wll be a valid path if a sprite
143 If no list is specified, or the sum of weights in the list is zero, then the sprite
144 will repeat itself after completing.
147 \qmlproperty int QtQuick2::Sprite::frames
149 Number of frames in this sprite.
152 \qmlproperty int QtQuick2::Sprite::frameHeight
154 Height of a single frame in this sprite.
157 \qmlproperty int QtQuick2::Sprite::frameWidth
159 Width of a single frame in this sprite.
162 \qmlproperty int QtQuick2::Sprite::frameX
164 The X coordinate in the image file of the first frame of the sprite.
167 \qmlproperty int QtQuick2::Sprite::frameY
169 The Y coordinate in the image file of the first frame of the sprite.
172 \qmlproperty url QtQuick2::Sprite::source
174 The image source for the animation.
176 If frameHeight and frameWidth are not specified, it is assumed to be a single long row of square frames.
177 Otherwise, it can be multiple contiguous rows or rectangluar frames, when one row runs out the next will be used.
179 If frameX and frameY are specified, the row of frames will be taken with that x/y coordinate as the upper left corner.
183 \qmlproperty bool QtQuick2::Sprite::reverse
185 If true, then the animation will be played in reverse.
191 \qmlproperty bool QtQuick2::Sprite::randomStart
193 If true, then the animation will start its first animation with a random amount of its duration skipped.
194 This allows them to not look like they all just started when the animation begins.
196 This only affects the very first animation played. Transitioning to another animation, or the same
197 animation again, will not trigger this.
203 \qmlproperty bool QtQuick2::Sprite::frameSync
205 If true, then the animation will have no duration. Instead, the animation will advance
206 one frame each time a frame is rendered to the screen. This syncronizes it with the painting
207 rate as opposed to elapsed time.
209 If frameSync is set to true, it overrides all of duration, frameRate and frameDuration.
214 static const int unsetDuration = -2;//-1 means perframe for duration
215 QQuickSprite::QQuickSprite(QObject *parent)
216 : QQuickStochasticState(parent)
217 , m_generatedCount(0)
227 , m_frameRate(unsetDuration)
228 , m_frameRateVariation(0)
229 , m_frameDuration(unsetDuration)
230 , m_frameDurationVariation(0)
235 int QQuickSprite::variedDuration() const //Deals with precedence when multiple durations are set
240 if (m_frameRate != unsetDuration) {
241 qreal fpms = (m_frameRate
242 + (m_frameRateVariation * ((qreal)qrand()/RAND_MAX) * 2)
243 - m_frameRateVariation) / 1000.0;
244 return qMax(qreal(0.0) , m_frames / fpms);
245 } else if (m_frameDuration != unsetDuration) {
246 int mspf = m_frameDuration
247 + (m_frameDurationVariation * ((qreal)qrand()/RAND_MAX) * 2)
248 - m_frameDurationVariation;
249 return qMax(0, m_frames * mspf);
251 qWarning() << "Sprite::duration is changing meaning to the full animation duration.";
252 qWarning() << "Use Sprite::frameDuration for the old meaning, of per frame duration.";
253 qWarning() << "As an interim measure, duration/durationVariation means the same as frameDuration/frameDurationVariation, and you'll get this warning spewed out everywhere to movtivate you.";
254 //Note that the spammyness is due to this being the best location to detect, but also called once each animation loop
255 return QQuickStochasticState::variedDuration() * m_frames;