Skip to content

Commit 701c4b3

Browse files
committed
Animation repeat and yoyo support.
1 parent 101e4f5 commit 701c4b3

4 files changed

Lines changed: 123 additions & 56 deletions

File tree

v3/src/animation/AnimationManager.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@ AnimationManager.prototype = {
3636
this.textureManager = textureManager;
3737
},
3838

39-
// add frame name based animation
40-
// add frame index based animation
41-
// add bone based animation
42-
// add animation from json data
43-
39+
// config format:
4440
// {
4541
// frames: [
4642
// { key: textureKey, frame: textureFrame },
@@ -53,11 +49,11 @@ AnimationManager.prototype = {
5349
// delay: integer
5450
// repeat: -1 = forever, otherwise integer
5551
// repeatDelay: integer
56-
// yoyo: boolean,
52+
// yoyo: boolean
53+
// hideOnComplete: boolean
5754
// onStart: function
5855
// onRepeat: function
5956
// onComplete: function,
60-
//
6157
// transitions: [
6258
// {
6359
// key: string <- key of the animation to blend with,

v3/src/animation/frame/Animation.js

Lines changed: 81 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,10 @@ var Animation = function (manager, key, config)
77

88
this.key = key;
99

10-
// frames: [
11-
// { key: textureKey, frame: textureFrame },
12-
// { key: textureKey, frame: textureFrame, duration: float },
13-
// { key: textureKey, frame: textureFrame, onUpdate: function }
14-
// ],
15-
// framerate: integer,
16-
// duration: float (seconds, optional, ignored if framerate is set),
17-
// skipMissedFrames: boolean,
18-
// delay: integer
19-
// repeat: -1 = forever, otherwise integer
20-
// repeatDelay: integer
21-
// yoyo: boolean,
22-
// onStart: function
23-
// onRepeat: function
24-
// onComplete: function,
25-
2610
// Extract all the frame data into the frames array
2711
this.frames = GetFrames(manager.textureManager, GetObjectValue(config, 'frames', []));
2812

29-
// Scale the time (make it go faster / slower) >>> move to Animation Component?
30-
this.timeScale = 1;
13+
this.firstFrame = this.frames[0];
3114

3215
// The frame rate of playback in frames per second (default 24 if duration is null)
3316
this.framerate = GetObjectValue(config, 'framerate', null);
@@ -92,8 +75,8 @@ Animation.prototype = {
9275
startFrame = 0;
9376
}
9477

95-
component.currentAnim = this;
96-
component.currentFrame = this.frames[startFrame];
78+
component.updateAnimation(this);
79+
component.updateFrame(this.frames[startFrame]);
9780
},
9881

9982
checkFrame: function (index)
@@ -105,36 +88,100 @@ Animation.prototype = {
10588
{
10689
// When is the next update due?
10790
var frame = component.currentFrame;
91+
var diff = component.accumulator - component.nextTick;
10892

109-
component.nextTick = this.msPerFrame + frame.duration;
93+
component.accumulator = diff;
94+
component.nextTick = (this.msPerFrame + frame.duration) * component.timescale;
11095
},
11196

112-
setFrame: function (component)
97+
nextFrame: function (component)
11398
{
114-
// Example data:
115-
// timestamp = 2356.534000020474
116-
// frameDelta = 17.632333353807383 (diff since last timestamp)
117-
118-
// Work out which frame should be set next on the child, and set it
119-
12099
var frame = component.currentFrame;
121100

122-
var diff = component.accumulator - component.nextTick;
101+
// TODO: Add frame skip support
123102

124103
if (frame.nextFrame)
125104
{
126-
component.currentFrame = frame.nextFrame;
105+
component.updateFrame(frame.nextFrame);
106+
107+
this.getNextTick(component);
108+
}
109+
else
110+
{
111+
// We're at the end of the animation
112+
113+
// Yoyo? (happens before repeat)
114+
if (this.yoyo)
115+
{
116+
component.forward = false;
117+
}
118+
else if (component.repeatCounter > 0)
119+
{
120+
// Repeat (happens before complete)
121+
this.repeatAnimation(component);
122+
}
123+
else
124+
{
125+
// OnComplete
126+
component.stop();
127+
}
128+
}
129+
},
130+
131+
repeatAnimation: function (component)
132+
{
133+
component.repeatCounter--;
134+
135+
component.forward = true;
136+
137+
component.updateFrame(this.firstFrame);
127138

128-
component.updateFrame();
139+
this.getNextTick(component);
129140

130-
component.accumulator = diff;
141+
component.nextTick += (this.repeatDelay * 1000) * component.timescale;
142+
143+
// OnRepeat
144+
},
145+
146+
previousFrame: function (component)
147+
{
148+
var frame = component.currentFrame;
149+
150+
// TODO: Add frame skip support
151+
152+
if (frame.prevFrame)
153+
{
154+
component.updateFrame(frame.prevFrame);
131155

132156
this.getNextTick(component);
133157
}
134158
else
135159
{
136-
// We're at the end of the animation
137-
component.stop();
160+
// We're at the start of the animation
161+
162+
if (component.repeatCounter > 0)
163+
{
164+
// Repeat (happens before complete)
165+
this.repeatAnimation(component);
166+
}
167+
else
168+
{
169+
// OnComplete
170+
component.stop();
171+
}
172+
}
173+
},
174+
175+
setFrame: function (component)
176+
{
177+
// Work out which frame should be set next on the child, and set it
178+
if (component.forward)
179+
{
180+
this.nextFrame(component);
181+
}
182+
else
183+
{
184+
this.previousFrame(component);
138185
}
139186
},
140187

v3/src/checksum.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
var CHECKSUM = {
2-
build: 'fa396890-1994-11e7-861e-87bce096a6e5'
2+
build: '63ce9e00-199b-11e7-a808-a7360c964cd7'
33
};
44
module.exports = CHECKSUM;

v3/src/components/Animation.js

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,38 @@ var Animation = function (parent)
1919
// Reference to the Phaser.AnimationFrame object
2020
this.currentFrame = null;
2121

22-
// Timing playhead values
22+
// Scale the time (make it go faster / slower)
23+
this.timescale = 1;
24+
25+
// Playhead values
26+
27+
// Move the playhead forward (true) or in reverse (false)
28+
this.forward = true;
29+
2330
this.accumulator = 0;
31+
2432
this.nextTick = 0;
33+
34+
this.repeatCounter = 0;
2535
};
2636

2737
Animation.prototype.constructor = Animation;
2838

2939
Animation.prototype = {
3040

41+
updateAnimation: function (animation)
42+
{
43+
this.currentAnim = animation;
44+
},
45+
46+
updateFrame: function (animationFrame)
47+
{
48+
this.currentFrame = animationFrame;
49+
50+
this.parent.texture = animationFrame.frame.texture;
51+
this.parent.frame = animationFrame.frame;
52+
},
53+
3154
load: function (key, startFrame)
3255
{
3356
if (startFrame === undefined) { startFrame = 0; }
@@ -39,8 +62,6 @@ Animation.prototype = {
3962

4063
// Load the new animation in
4164
this.animationManager.load(this, key, startFrame);
42-
43-
this.updateFrame();
4465
},
4566

4667
play: function (key, startFrame)
@@ -49,24 +70,22 @@ Animation.prototype = {
4970

5071
this.load(key, startFrame);
5172

73+
// Move to reset?
5274
this.accumulator = 0;
75+
this.nextTick = 0;
76+
77+
// Should give us 9,007,199,254,740,991 safe repeats
78+
this.repeatCounter = (this.currentAnim.repeat === -1) ? Number.MAX_SAFE_INTEGER : this.currentAnim.repeat;
5379

5480
this.currentAnim.getNextTick(this);
5581

82+
this.forward = true;
5683
this.isPlaying = true;
5784
},
5885

59-
stop: function ()
60-
{
61-
this.isPlaying = false;
62-
},
63-
64-
updateFrame: function ()
65-
{
66-
this.parent.texture = this.currentFrame.frame.texture;
67-
this.parent.frame = this.currentFrame.frame;
68-
},
69-
86+
// Example data:
87+
// timestamp = 2356.534000020474
88+
// frameDelta = 17.632333353807383 (diff since last timestamp)
7089
update: function (timestamp, frameDelta)
7190
{
7291
if (this.isPlaying)
@@ -78,6 +97,11 @@ Animation.prototype = {
7897
this.currentAnim.setFrame(this);
7998
}
8099
}
100+
},
101+
102+
stop: function ()
103+
{
104+
this.isPlaying = false;
81105
}
82106

83107
};

0 commit comments

Comments
 (0)