-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathanimator.js
113 lines (95 loc) · 3.19 KB
/
animator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
var gamejs = require('gamejs');
/**
* @fileoverview The images making up a animation are stored in the column of
* the spritesheet. a spritesheet can contain multiple columns.
*/
/**
* Access invidual images on a spritesheet image by index number
*/
var SpriteSheet = exports.SpriteSheet = function(imagePath, sheetSpec) {
/**
* @returns {Surface} the requested sub-surface
*/
this.get = function(id) {
return surfaceCache[id - offset];
};
/**
* constructor
*/
var width = sheetSpec.width;
var height = sheetSpec.height;
var offset = sheetSpec.offset || 0;
var image = gamejs.image.load(imagePath);
var surfaceCache = [];
for (var i=0; i<image.rect.width; i+=width) {
for (var j=0;j<image.rect.height;j+=height) {
var srf = new gamejs.Surface([width, height]);
var rect = new gamejs.Rect(i, j, width, height);
srf.blit(image, new gamejs.Rect([0,0],[width,height]), rect);
surfaceCache.push(srf);
}
}
this.rect = new gamejs.Rect([0, 0], [width, height]);
return this;
};
/**
* An animation helper: given a SpriteSheet and a animation specificiation
* this class helps playing the animation. Use `start(animation)` to start
* an animation and `update(msDuration)` to update the animation status in
* your game tick.
*
* `animationSheet.image` will always contain the current image.
*
* Don't forget to `clone()` an AnimationSheet instead of passing the same
* one to different actors.
*
* AnimationSpec: {'walk': [0, 3], 'walkHit': [4, 6], 'pause': [7]}
* @param {SpriteSheet}
* @param {Object}
* @param {Number}
*/
var AnimationSheet = exports.AnimationSheet = function(spriteSheet, animationSpec, fps) {
this.fps = fps || 6;
this.frameDuration = 1000 / this.fps;
this.spec = animationSpec;
this.currentFrame = null;
this.currentFrameDuration = 0;
this.currentAnimation = null;
this.spriteSheet = spriteSheet;
this.image = null;
return this;
}
AnimationSheet.prototype.start = function(animation) {
this.currentAnimation = animation;
this.currentFrame = this.spec[animation][0];
this.currentFrameDuration = 0;
return;
};
AnimationSheet.prototype.update = function(msDuration) {
if (!this.currentAnimation) {
throw new Error('no animation set');
}
this.currentFrameDuration += msDuration;
if (this.currentFrameDuration >= this.frameDuration) {
this.currentFrame++;
this.currentFrameDuration = 0;
// loop back to first frame if animation finished or single frame
var aniSpec = this.spec[this.currentAnimation];
if (aniSpec.length == 1 || this.currentFrame > aniSpec[1]) {
// unless third argument is false, which means: do not loop
if (aniSpec.length === 3 && aniSpec[2] === false) {
this.currentFrame--;
} else {
this.currentFrame = aniSpec[0];
}
}
}
this.image = this.spriteSheet.get(this.currentFrame);
return;
};
AnimationSheet.prototype.clone = function() {
return new AnimationSheet(this.spriteSheet, this.spec, this.fps);
};
AnimationSheet.prototype.getSize = function() {
return [this.spriteSheet.rect.width, this.spriteSheet.rect.height];
};