**
****************************************************************************/
-import QtQuick.Particles 2.0
-import QtQuick.Particles 2.0 as Qlp
import QtQuick 2.0
+import QtQuick.Particles 2.0
Item {
id: root
source: "../images/meteor.png"
frames: 35
duration: 40
- speedModifiesDuration: -0.1
+ randomStart: true
to: {"explode":0, "spinning":1}
},Sprite {
name: "explode"
source: "../images/_explo.png"
frames: 22
duration: 40
- speedModifiesDuration: -0.1
to: {"nullFrame":1}
},Sprite {//Not sure if this is needed, but seemed easiest
name: "nullFrame"
*/
/*!
+ \qmlproperty bool QtQuick2::Sprite::randomStart
+
+ If true, then the animation will start its first animation with a random amount of its duration skipped.
+ This allows them to not look like they all just started when the animation begins.
+
+ This only affects the very first animation played. Transitioning to another animation, or the same
+ animation again, will not trigger this.
+
+ Default is false.
+*/
+
+/*!
\qmlproperty bool QtQuick2::Sprite::frameSync
If true, then the animation will have no duration. Instead, the animation will advance
state normally does.
*/
+static const int NINF = -1000000;//magic number for random start time - should be more negative than a single realistic animation duration
/* TODO:
make sharable?
solve the state data initialization/transfer issue so as to not need to make friends
return;
m_things[index] = state;
m_duration[index] = m_states[state]->variedDuration();
+ if (m_states[state]->randomStart())
+ m_startTimes[index] = NINF;
+ else
+ m_startTimes[index] = 0;
m_goals[index] = -1;
restart(index);
}
{
if (index >= m_things.count())
return;
- //Will never change until start is called again with a new state - this is not a 'pause'
+ //Will never change until start is called again with a new state (or manually advanced) - this is not a 'pause'
for (int i=0; i<m_stateUpdates.count(); i++)
m_stateUpdates[i].second.removeAll(index);
}
void QQuickStochasticEngine::restart(int index)
{
+ bool randomStart = (m_startTimes[index] == NINF);
m_startTimes[index] = m_timeOffset;
if (m_addAdvance)
m_startTimes[index] += m_advanceTime.elapsed();
+ if (randomStart)
+ m_startTimes[index] -= qrand() % m_duration[index];
int time = m_duration[index] + m_startTimes[index];
for (int i=0; i<m_stateUpdates.count(); i++)
m_stateUpdates[i].second.removeAll(index);
void QQuickSpriteEngine::restart(int index) //Reimplemented to recognize and handle pseudostates
{
+ bool randomStart = (m_startTimes[index] == NINF);
if (m_sprites[m_things[index]]->frameSync()) {//Manually advanced
m_startTimes[index] = 0;
+ if (randomStart && m_sprites[m_things[index]]->m_generatedCount)
+ m_startTimes[index] += qrand() % m_sprites[m_things[index]]->m_generatedCount;
} else {
m_startTimes[index] = m_timeOffset;
if (m_addAdvance)
m_startTimes[index] += m_advanceTime.elapsed();
+ if (randomStart)
+ m_startTimes[index] -= qrand() % m_duration[index];
int time = spriteDuration(index) + m_startTimes[index];
+ if (randomStart) {
+ int curTime = m_timeOffset + (m_addAdvance ? m_advanceTime.elapsed() : 0);
+ while (time < curTime) //Fast forward through psuedostates as needed
+ time += spriteDuration(index);
+ }
+
for (int i=0; i<m_stateUpdates.count(); i++)
m_stateUpdates[i].second.removeAll(index);
addToUpdateList(time, index);
Q_OBJECT
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
Q_PROPERTY(int durationVariation READ durationVariation WRITE setDurationVariation NOTIFY durationVariationChanged)
+ //Note than manually advanced sprites need to query this variable and implement own behaviour for it
+ Q_PROPERTY(bool randomStart READ randomStart WRITE setRandomStart NOTIFY randomStartChanged)
Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
QQuickStochasticState(QObject* parent = 0)
: QObject(parent)
, m_duration(1000)
+ , m_durationVariation(0)
+ , m_randomStart(false)
{
}
- m_durationVariation);
}
+ bool randomStart() const
+ {
+ return m_randomStart;
+ }
+
signals:
void durationChanged(int arg);
void entered();//### Just playing around - don't expect full state API
+ void randomStartChanged(bool arg);
+
public slots:
void setDuration(int arg)
{
}
}
+ void setRandomStart(bool arg)
+ {
+ if (m_randomStart != arg) {
+ m_randomStart = arg;
+ emit randomStartChanged(arg);
+ }
+ }
+
private:
QString m_name;
QVariantMap m_to;
int m_durationVariation;
friend class QQuickStochasticEngine;
+ bool m_randomStart;
};
class Q_AUTOTEST_EXPORT QQuickStochasticEngine : public QObject