UNPKG

5.48 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 if (manifestEntry.rotate === "cw") {
70 animation.rotateClockwise();
71 }
72 if (manifestEntry.rotate === "180") {
73 animation.rotateClockwise().rotateClockwise();
74 }
75 if (manifestEntry.rotate === "ccw") {
76 animation.rotateCounterclockwise();
77 }
78 animation.name = key;
79 return animation;
80}
81
82function generateAnimationsFromManifest(images, manifest) {
83 var animations = {};
84 for (var key in manifest) {
85 if (manifest.hasOwnProperty(key)) {
86 var info = manifest[key];
87 animations[key] = makeAnimationFromManifest(images, key, info);
88 }
89 }
90 return animations;
91}
92
93/**
94 * Loads and constructs {@link Animation}s from a manifest. An instance of AnimationLoader is available as {@link Splat.Game#animations}.
95 * @constructor
96 * @param {ImageLoader} imageLoader The ImageLoader used to fetch all {@link external:image}s.
97 * @param {object} manifest The list of {@link Animation}s to build.
98 * @example
99 var manifest = {
100 "player-left": { // The Animation's name
101 "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.
102 "frames": 4, // The number of frames in the Animation
103 "msPerFrame": 100 // How many milliseconds to display each frame
104 },
105 "player-right": {
106 "strip": "img/player-left.png", // Re-use the left sprite-strip
107 "frames": 4,
108 "msPerFrame": 100,
109 "flip": "horizontal" // Flip the animation horizontally so we can use the left image for the right.
110 },
111 "item": { // Create an animation from individual images named "img/item/[0000-0009].png"
112 "prefix": "img/item/", // Image filename prefix
113 "suffix": ".png", // Image filename suffix
114 "padNumberTo": 4, // Number part of image is 4 characters long.
115 "frames": 10, // Load 10 separate image files [0-9].
116 "msPerFrame": 100,
117 "repeatAt": 5, // Loop the animation back at frame 5.
118 "rotate": "cw" // Rotate the animation clockwise.
119 }
120 };
121 var imageLoader = new Splat.ImageLoader();
122 var animationLoader = new Splat.AnimationLoader(imageLoader, manifest);
123 */
124function AnimationLoader(imageLoader, manifest) {
125 /**
126 * The ImageLoader used to fetch all {@link external:image}s.
127 * @member {ImageLoader}
128 */
129 this.imageLoader = imageLoader;
130 /**
131 * The list of {@link Animation} metadata.
132 * @member {object}
133 */
134 this.manifest = manifest;
135 loadImagesFromManifest(imageLoader, manifest);
136}
137/**
138 * Test if all {@link Animation}s are loaded.
139 * @returns {boolean}
140 */
141AnimationLoader.prototype.allLoaded = function() {
142 if (this.loaded) {
143 return true;
144 }
145 var loaded = this.imageLoader.allLoaded();
146 if (loaded) {
147 this.animations = generateAnimationsFromManifest(this.imageLoader, this.manifest);
148 this.loaded = true;
149 }
150 return loaded;
151};
152/**
153 * Load a single {@link Animation}.
154 * @param {string} name The name to store the {@link Animation} under. This name will be used to retrieve the Animation from {@link AnimationLoader#get}.
155 * @param {object} info A single-animation portion of {@link AnimationLoader#manifest}.
156 */
157AnimationLoader.prototype.load = function(name, info) {
158 this.manifest[name] = info;
159 this.loaded = false;
160 loadImageFromManifest(this.imageLoader, name, info);
161};
162/**
163 * Fetch a loaded {@link Animation}.
164 * @param {string} name The name used to identify the {@link Animation} in the {@link AnimationLoader#manifest}.
165 * @returns {Animation}
166 */
167AnimationLoader.prototype.get = function(name) {
168 var anim = this.animations[name];
169 if (anim === undefined) {
170 console.error("Unknown animation: " + name);
171 }
172 return anim;
173};
174
175module.exports = AnimationLoader;