-
Notifications
You must be signed in to change notification settings - Fork 1
/
sprites.js
98 lines (82 loc) · 3 KB
/
sprites.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
import Random from "../utils/random";
export default class Sprites {
constructor() {
this.random = new Random();
this.imageMap = {};
this.spriteMap = {};
}
getSprite(object) {
if (!this.spriteMap[object.id]) {
this.spriteMap[object.id] = {};
}
if (!object.spriteMap[object.animation]) {
throw new Error(`Animation '${object.animation}' not found in: ${JSON.stringify(object)}`);
}
let objectSpriteMap = null;
if (!this.spriteMap[object.id][object.animation]) {
this.spriteMap[object.id][object.animation] = {
tick: 0,
frame: 0,
imageWidth: 0,
imageHeight: 0,
columns: 0,
config: object.spriteMap[object.animation],
image: this.makeImage(object.spriteMap[object.animation].sheet, () => {
objectSpriteMap.imageWidth = objectSpriteMap.image.width;
objectSpriteMap.imageHeight = objectSpriteMap.image.height;
objectSpriteMap.columns = objectSpriteMap.imageWidth / this.getAlign(objectSpriteMap.config.align, 'x');
}),
};
// hack for referencing object shortcut
objectSpriteMap = this.spriteMap[object.id][object.animation];
}
if (!objectSpriteMap) {
objectSpriteMap = this.spriteMap[object.id][object.animation];
}
objectSpriteMap.tick++;
// handle random animation delays
if (object.animationRandomDelay && this.random.chance() && objectSpriteMap.tick >= objectSpriteMap.config.delay) {
objectSpriteMap.tick -= this.random.number(5, 15);
}
if (objectSpriteMap.tick >= objectSpriteMap.config.delay) {
objectSpriteMap.tick = 0;
objectSpriteMap.frame++;
if (objectSpriteMap.frame >= objectSpriteMap.columns) {
objectSpriteMap.frame = 0;
}
}
return {
image: objectSpriteMap.image,
imageX: objectSpriteMap.frame * this.getAlign(objectSpriteMap.config.align, 'x'),
imageY: 0,
sizeX: this.getAlign(objectSpriteMap.config.align, 'x'),
sizeY: this.getAlign(objectSpriteMap.config.align, 'y'),
};
}
getAlign(align, symbol) {
return Array.isArray(align) ? align[symbol === 'x' ? 0 : 1] : align;
}
drawSprite(x, y, object, ctx) {
const sprite = this.getSprite(object);
ctx.drawImage(
sprite.image,
sprite.imageX,
sprite.imageY,
sprite.sizeX,
sprite.sizeY,
x,
y,
object.size.x,
object.size.y
);
}
makeImage(src, callback) {
const image = new Image();
image.onload = callback;
image.src = src;
return image;
}
getImage(src) {
return this.imageMap[src] || this.makeImage(src);
}
}