UNPKG

4.99 kBJavaScriptView Raw
1var AssetLoader = require("./assets/asset-loader");
2var loadImage = require("./assets/load-image");
3var Input = require("./input");
4var Prefabs = require("./prefabs");
5var Scene = require("./scene");
6var SoundManager = require("./sound-manager");
7var splitFilmStripAnimations = require("./split-filmstrip-animations");
8
9function Game(canvas, customRequire) {
10 this.animations = customRequire("./data/animations");
11 splitFilmStripAnimations(this.animations);
12 this.canvas = canvas;
13 this.context = canvas.getContext("2d");
14 this.images = new AssetLoader(customRequire("./data/images"), loadImage);
15 this.inputs = new Input(customRequire("./data/inputs"), canvas);
16 this.require = customRequire;
17 this.sounds = new SoundManager(customRequire("./data/sounds"));
18 this.prefabs = new Prefabs(customRequire("./data/prefabs"));
19 this.lastTime = -1;
20 this.remainingDebugTime = undefined;
21
22 this.scaleCanvasToCssSize();
23 window.addEventListener("resize", this.onCanvasResize.bind(this));
24
25 this.scenes = this.makeScenes(customRequire("./data/scenes"));
26 this.run = this.run.bind(this);
27}
28Game.prototype.makeScenes = function(sceneList) {
29 var names = Object.keys(sceneList);
30 var scenes = {};
31 for (var i = 0; i < names.length; i++) {
32 var name = names[i];
33 scenes[name] = new Scene(name, {
34 animations: this.animations,
35 canvas: this.canvas,
36 context: this.context,
37 images: this.images,
38 inputs: this.inputs,
39 prefabs: this.prefabs,
40 require: this.require,
41 scaleCanvasToCssSize: this.scaleCanvasToCssSize.bind(this),
42 scaleCanvasToFitRectangle: this.scaleCanvasToFitRectangle.bind(this),
43 scenes: scenes,
44 sounds: this.sounds
45 });
46 if (sceneList[name].first) {
47 scenes[name].start();
48 }
49 }
50 return scenes;
51};
52Game.prototype.start = function() {
53 if (this.running) {
54 return;
55 }
56 this.running = true;
57 this.lastTime = -1;
58 window.requestAnimationFrame(this.run);
59};
60Game.prototype.stop = function() {
61 this.running = false;
62};
63Game.prototype.run = function(time) {
64 var scenes = Object.keys(this.scenes);
65
66 if (this.lastTime === -1) {
67 this.lastTime = time;
68 }
69 var elapsed = time - this.lastTime;
70 this.lastTime = time;
71
72 for (var i = 0; i < scenes.length; i++) {
73 var name = scenes[i];
74 var scene = this.scenes[name];
75 scene.simulate(elapsed);
76 }
77 for (i = 0; i < scenes.length; i++) {
78 name = scenes[i];
79 scene = this.scenes[name];
80 this.context.save();
81 scene.render(elapsed);
82 this.context.restore();
83 }
84
85 if (this.remainingDebugTime !== undefined) {
86 this.remainingDebugTime -= elapsed;
87 if (this.remainingDebugTime <= 0) {
88 this.remainingDebugTime = undefined;
89 this.logDebugTimes();
90 }
91 }
92
93 if (this.running) {
94 window.requestAnimationFrame(this.run);
95 }
96};
97Game.prototype.timeSystems = function(total) {
98 var scenes = Object.keys(this.scenes);
99 for (var i = 0; i < scenes.length; i++) {
100 var name = scenes[i];
101 var scene = this.scenes[name];
102 scene.simulation.resetTimings();
103 scene.renderer.resetTimings();
104 }
105 this.remainingDebugTime = total;
106};
107Game.prototype.logDebugTimes = function() {
108 var scenes = Object.keys(this.scenes);
109 var timings = [];
110 for (var i = 0; i < scenes.length; i++) {
111 var name = scenes[i];
112 var scene = this.scenes[name];
113 timings = timings.concat(scene.simulation.timings());
114 timings = timings.concat(scene.renderer.timings());
115 }
116 console.table(groupTimings(timings));
117};
118function groupTimings(timings) {
119 var total = timings.map(function(timing) {
120 return timing.time;
121 }).reduce(function(a, b) {
122 return a + b;
123 });
124 timings.sort(function(a, b) {
125 return b.time - a.time;
126 }).forEach(function(timing) {
127 timing.percent = timing.time / total;
128 });
129 return timings;
130}
131Game.prototype.onCanvasResize = function() {
132 this.resizer();
133};
134Game.prototype.scaleCanvasToCssSize = function() {
135 this.resizer = function() {
136 var canvasStyle = window.getComputedStyle(this.canvas);
137 var width = parseInt(canvasStyle.width);
138 var height = parseInt(canvasStyle.height);
139 this.canvas.width = width;
140 this.canvas.height = height;
141 }.bind(this);
142 this.resizer();
143};
144Game.prototype.scaleCanvasToFitRectangle = function(width, height) {
145 this.resizer = function() {
146 var canvasStyle = window.getComputedStyle(this.canvas);
147 var cssWidth = parseInt(canvasStyle.width);
148 var cssHeight = parseInt(canvasStyle.height);
149 var cssAspectRatio = cssWidth / cssHeight;
150
151 var desiredWidth = width;
152 var desiredHeight = height;
153 var desiredAspectRatio = width / height;
154 if (desiredAspectRatio > cssAspectRatio) {
155 desiredHeight = Math.floor(width / cssAspectRatio);
156 } else if (desiredAspectRatio < cssAspectRatio) {
157 desiredWidth = Math.floor(height * cssAspectRatio);
158 }
159
160 this.canvas.width = desiredWidth;
161 this.canvas.height = desiredHeight;
162 }.bind(this);
163 this.resizer();
164};
165
166module.exports = Game;