UNPKG

5.18 kBJavaScriptView Raw
1"use strict";
2
3var buffer = require("./buffer");
4var Animation = require("./animation");
5
6function makeFrame(img, frameWidth, f) {
7 return buffer.makeBuffer(frameWidth, img.height, function(ctx) {
8 var sx = f * frameWidth;
9 ctx.drawImage(img, sx, 0, frameWidth, img.height, 0, 0, frameWidth, img.height);
10 });
11}
12
13function makeAnimation(img, numFrames, time) {
14 var a = new Animation();
15 var frameWidth = img.width / numFrames |0;
16 for (var f = 0; f < numFrames; f++) {
17 a.add(makeFrame(img, frameWidth, f), time);
18 }
19 return a;
20}
21
22function loadImageFromManifest(imageLoader, name, info) {
23 if (info.strip !== undefined) {
24 imageLoader.load(name, info.strip);
25 } else if (info.prefix !== undefined) {
26 for (var i = 1; i <= info.frames; i++) {
27 var number = "" + i;
28 if (info.padNumberTo > 1) {
29 while (number.length < info.padNumberTo) {
30 number = "0" + number;
31 }
32 }
33 name = info.prefix + number + info.suffix;
34 imageLoader.load(name + i, name);
35 }
36 }
37}
38
39function loadImagesFromManifest(imageLoader, manifest) {
40 for (var key in manifest) {
41 if (manifest.hasOwnProperty(key)) {
42 var info = manifest[key];
43 loadImageFromManifest(imageLoader, key, info);
44 }
45 }
46}
47
48function makeAnimationFromManifest(images, key, manifestEntry) {
49 var animation;
50 if (manifestEntry.strip !== undefined) {
51 var strip = images.get(key);
52 animation = makeAnimation(strip, manifestEntry.frames, manifestEntry.msPerFrame);
53 } else if (manifestEntry.prefix !== undefined) {
54 animation = new Animation();
55 for (var i = 1; i <= manifestEntry.frames; i++) {
56 var frame = images.get(key + i);
57 animation.add(frame, manifestEntry.msPerFrame);
58 }
59 }
60 if (manifestEntry.repeatAt !== undefined) {
61 animation.repeatAt = manifestEntry.repeatAt;
62 }
63 if (manifestEntry.flip === "horizontal") {
64 animation.flipHorizontally();
65 }
66 if (manifestEntry.flip === "vertical") {
67 animation.flipVertically();
68 }
69 animation.name = key;
70 return animation;
71}
72
73function generateAnimationsFromManifest(images, manifest) {
74 var animations = {};
75 for (var key in manifest) {
76 if (manifest.hasOwnProperty(key)) {
77 var info = manifest[key];
78 animations[key] = makeAnimationFromManifest(images, key, info);
79 }
80 }
81 return animations;
82}
83
84/**
85 * Loads and constructs {@link Animation}s from a manifest. An instance of AnimationLoader is available as {@link Splat.Game#animations}.
86 * @constructor
87 * @param {ImageLoader} imageLoader The ImageLoader used to fetch all {@link external:image}s.
88 * @param {object} manifest The list of {@link Animation}s to build.
89 * @example
90 var manifest = {
91 "player-left": { // The Animation's name
92 "strip": "img/player-left.png", // The path to a sprite-strip. A sprite strip is multiple frames side-by-side horizontally in a single image.
93 "frames": 4, // The number of frames in the Animation
94 "msPerFrame": 100 // How many milliseconds to display each frame
95 },
96 "player-right": {
97 "strip": "img/player-left.png", // Re-use the left sprite-strip
98 "frames": 4,
99 "msPerFrame": 100,
100 "flip": "horizontal" // Flip the animation horizontally so we can use the left image for the right.
101 },
102 "item": { // Create an animation from individual images named "img/item/[0000-0009].png"
103 "prefix": "img/item/", // Image filename prefix
104 "suffix": ".png", // Image filename suffix
105 "padNumberTo": 4, // Number part of image is 4 characters long.
106 "frames": 10, // Load 10 separate image files [0-9].
107 "msPerFrame": 100,
108 "repeatAt": 5, // Loop the animation back at frame 5.
109 }
110 };
111 var imageLoader = new Splat.ImageLoader();
112 var animationLoader = new Splat.AnimationLoader(imageLoader, manifest);
113 */
114function AnimationLoader(imageLoader, manifest) {
115 /**
116 * The ImageLoader used to fetch all {@link external:image}s.
117 * @member {ImageLoader}
118 */
119 this.imageLoader = imageLoader;
120 /**
121 * The list of {@link Animation} metadata.
122 * @member {object}
123 */
124 this.manifest = manifest;
125 loadImagesFromManifest(imageLoader, manifest);
126}
127/**
128 * Test if all {@link Animation}s are loaded.
129 * @returns {boolean}
130 */
131AnimationLoader.prototype.allLoaded = function() {
132 if (this.loaded) {
133 return true;
134 }
135 var loaded = this.imageLoader.allLoaded();
136 if (loaded) {
137 this.animations = generateAnimationsFromManifest(this.imageLoader, this.manifest);
138 this.loaded = true;
139 }
140 return loaded;
141};
142/**
143 * Load a single {@link Animation}.
144 * @param {string} name The name to store the {@link Animation} under. This name will be used to retrieve the Animation from {@link AnimationLoader#get}.
145 * @param {object} info A single-animation portion of {@link AnimationLoader#manifest}.
146 */
147AnimationLoader.prototype.load = function(name, info) {
148 this.manifest[name] = info;
149 this.loaded = false;
150 loadImageFromManifest(this.imageLoader, name, info);
151};
152/**
153 * Fetch a loaded {@link Animation}.
154 * @param {string} name The name used to identify the {@link Animation} in the {@link AnimationLoader#manifest}.
155 * @returns {Animation}
156 */
157AnimationLoader.prototype.get = function(name) {
158 var anim = this.animations[name];
159 if (anim === undefined) {
160 console.error("Unknown animation: " + name);
161 }
162 return anim;
163};
164
165module.exports = AnimationLoader;