1 | "use strict";
|
2 | var __extends = (this && this.__extends) || (function () {
|
3 | var extendStatics = Object.setPrototypeOf ||
|
4 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
5 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
6 | return function (d, b) {
|
7 | extendStatics(d, b);
|
8 | function __() { this.constructor = d; }
|
9 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
10 | };
|
11 | })();
|
12 | Object.defineProperty(exports, "__esModule", { value: true });
|
13 | var p2_1 = require("p2");
|
14 | var Tool_1 = require("./../Tool");
|
15 | var Entity_1 = require("./../Entity");
|
16 | var Module_1 = require("./../Module");
|
17 |
|
18 |
|
19 |
|
20 | var Scene = (function (_super) {
|
21 | __extends(Scene, _super);
|
22 |
|
23 | |
24 |
|
25 |
|
26 | function Scene() {
|
27 | var _this = _super.call(this) || this;
|
28 | |
29 |
|
30 |
|
31 |
|
32 | _this._entities = null;
|
33 | |
34 |
|
35 |
|
36 | _this.tilemap = null;
|
37 | |
38 |
|
39 |
|
40 |
|
41 | _this.world = null;
|
42 | |
43 |
|
44 |
|
45 |
|
46 | _this.materials = [];
|
47 | |
48 |
|
49 |
|
50 |
|
51 | _this.physics = [];
|
52 | |
53 |
|
54 |
|
55 |
|
56 | _this.shakeAmplitude = 0;
|
57 | |
58 |
|
59 |
|
60 |
|
61 | _this._physicQueue = [];
|
62 | _this.setProps({
|
63 | scale: 1,
|
64 | motionFactor: 1,
|
65 | backgroundColor: Tool_1.Color.transparent,
|
66 | backgroundAlpha: 1,
|
67 | gravity: 0,
|
68 | sizeAuto: true
|
69 | });
|
70 | _this.signals.progress = new Tool_1.SignalEvent();
|
71 | _this.context.scene = _this;
|
72 | _this.signals.propChange.bind("gravity", _this.onGravityChange.bind(_this));
|
73 | _this.signals.propChange.bind(["backgroundColor", "backgroundAlpha"], _this.onBackgroundChange.bind(_this));
|
74 | return _this;
|
75 | }
|
76 | |
77 |
|
78 |
|
79 |
|
80 |
|
81 | Scene.prototype.initialize = function (props) {
|
82 | _super.prototype.initialize.call(this, props);
|
83 | this.setProps({
|
84 | width: this.context.game.props.width,
|
85 | height: this.context.game.props.height
|
86 | });
|
87 | this.onBackgroundChange();
|
88 | };
|
89 | |
90 |
|
91 |
|
92 |
|
93 |
|
94 | Scene.prototype.update = function (tick) {
|
95 | var _this = this;
|
96 | tick *= this.props.motionFactor;
|
97 | _super.prototype.update.call(this, tick);
|
98 | if (this.world) {
|
99 | var fixedStep = (1 / 60) * this.props.motionFactor, maxStep = 3;
|
100 | this.world.step(fixedStep, Tool_1.Util.limit(tick, 0, maxStep * fixedStep), maxStep);
|
101 | this._physicQueue.forEach(function (physic) { return _this.physics.find(function (x) { return x.id === physic.id; }) && _this.addPhysic(physic); });
|
102 | }
|
103 | if (this.container && this.shakeAmplitude) {
|
104 | this.container.pivot.set(this.shakeAmplitude * (Math.random() - 0.5), this.shakeAmplitude * (Math.random() - 0.5));
|
105 | }
|
106 | };
|
107 |
|
108 | |
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 | Scene.prototype.fade = function (fadeType, color, duration, onComplete) {
|
117 | var _this = this;
|
118 | if (!this._fade) {
|
119 | this._fade = this.add(new Module_1.Shape(), {
|
120 | width: this.props.width,
|
121 | height: this.props.height,
|
122 | fill: color,
|
123 | fillAlpha: fadeType === "in" ? 1 : 0
|
124 | });
|
125 | }
|
126 | this.timers.addTimer("fade", duration, function () {
|
127 | _this._fade.props.fillAlpha = fadeType === "in" ? 0 : 1;
|
128 | if (onComplete) {
|
129 | onComplete();
|
130 | }
|
131 | }, {
|
132 | update: function (tick, value, ratio) { return _this._fade.props.fillAlpha = fadeType === "in" ? 1 - ratio : ratio; }
|
133 | });
|
134 | return this._fade;
|
135 | };
|
136 | |
137 |
|
138 |
|
139 |
|
140 | Scene.prototype.enablePhysics = function (gravity) {
|
141 | var _this = this;
|
142 | this.disablePhysics();
|
143 | gravity = typeof gravity === "undefined" ? this.props.gravity : gravity;
|
144 | this.world = new p2_1.World({ gravity: [0, gravity] });
|
145 | this.materials = [this.getDefaultMaterial()];
|
146 | this.getAllEntities().filter(function (entity) { return entity.physic; }).forEach(function (entity) {
|
147 | if (!entity.physic.shape.material) {
|
148 | entity.physic.shape.material = _this.getDefaultMaterial();
|
149 | }
|
150 | var materialId = entity.physic.shape.material.id;
|
151 | if (!_this.materials.find(function (material) { return material.id === materialId; })) {
|
152 | _this.materials.push(entity.physic.shape.material);
|
153 | }
|
154 | _this.addPhysic(entity.physic);
|
155 | });
|
156 | this.setProps({ gravity: gravity });
|
157 | this.world.setGlobalStiffness(Number.MAX_VALUE);
|
158 | this.world.on("beginContact", this._onBeginContact.bind(this), false);
|
159 | this.world.on("endContact", this._onEndContact.bind(this), false);
|
160 | this.world.on("preSolve", this._onPreSolve.bind(this), false);
|
161 | };
|
162 | |
163 |
|
164 |
|
165 | Scene.prototype.disablePhysics = function () {
|
166 | var _this = this;
|
167 | if (this.world) {
|
168 | this.physics.forEach(function (physic) { return _this.removePhysic(physic); });
|
169 | this.materials = [];
|
170 | this.physics = [];
|
171 | this.world = null;
|
172 | }
|
173 | };
|
174 | |
175 |
|
176 |
|
177 |
|
178 | Scene.prototype.getDefaultMaterial = function () {
|
179 | return this.world && this.world.defaultMaterial;
|
180 | };
|
181 | |
182 |
|
183 |
|
184 |
|
185 | Scene.prototype.addPhysic = function (physic) {
|
186 | if (this.world) {
|
187 | this.world.addBody(physic.body);
|
188 | this.physics.push(physic);
|
189 | }
|
190 | };
|
191 | |
192 |
|
193 |
|
194 |
|
195 | Scene.prototype.removePhysic = function (physic) {
|
196 | if (this.world) {
|
197 | this.world.removeBody(physic.body);
|
198 | }
|
199 | };
|
200 | |
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 | Scene.prototype.shake = function (amplitude, duration) {
|
207 | var _this = this;
|
208 | if (duration === void 0) { duration = 10; }
|
209 | this.shakeAmplitude = amplitude;
|
210 | this.timers.addTimer("shake", duration, function () {
|
211 | _this.shakeAmplitude = 0;
|
212 | if (_this.container) {
|
213 | _this.container.pivot.set(0, 0);
|
214 | }
|
215 | });
|
216 | };
|
217 | |
218 |
|
219 |
|
220 |
|
221 |
|
222 | Scene.prototype.getPhysicOwnerByBody = function (body) {
|
223 | var physic = this.physics.find(function (x) { return x.body.id === body.id; });
|
224 | return physic && physic.owner;
|
225 | };
|
226 | |
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 | Scene.prototype.setPhysicBouncing = function (physic, bounce) {
|
233 | var _this = this;
|
234 | if (physic.shape.material.id !== this.getDefaultMaterial().id) {
|
235 | var materialId_1 = physic.shape.material.id;
|
236 | this.world.contactMaterials.filter(function (x) { return x.materialA.id === materialId_1 || x.materialB.id === materialId_1; })
|
237 | .forEach(function (contactMaterial) { return _this.world.removeContactMaterial(contactMaterial); });
|
238 | }
|
239 | if (!bounce) {
|
240 | physic.shape.material = this.getDefaultMaterial();
|
241 | }
|
242 | else {
|
243 | var materialOptions_1 = {
|
244 | restitution: bounce,
|
245 | stiffness: Number.MAX_VALUE,
|
246 | friction: this.world.defaultContactMaterial.friction
|
247 | }, material_1 = physic.shape.material = new p2_1.Material(Scene.generateId());
|
248 | this.materials.push(material_1);
|
249 | var contactMaterials = this.materials.map(function (materialB) { return new p2_1.ContactMaterial(material_1, materialB, materialOptions_1); });
|
250 | contactMaterials.forEach(function (contactMaterial) { return _this.world.addContactMaterial(contactMaterial); });
|
251 | }
|
252 | return bounce;
|
253 | };
|
254 | |
255 |
|
256 |
|
257 |
|
258 |
|
259 | Scene.prototype.setTilemap = function (data) {
|
260 | this.tilemap = this.add(new Module_1.Tilemap(), {}, this._background ? 1 : 0);
|
261 | this.tilemap.setData(data);
|
262 | return this.tilemap;
|
263 | };
|
264 | |
265 |
|
266 |
|
267 |
|
268 | Scene.prototype.getEntities = function () {
|
269 | return this._entities || (this._entities = this.children.filter(function (child) { return child instanceof Entity_1.Entity; }));
|
270 | };
|
271 | |
272 |
|
273 |
|
274 |
|
275 | Scene.prototype.getAllEntities = function () {
|
276 | var findChildrenEntities = function (child) {
|
277 | var childrenEntities = child instanceof Entity_1.Entity ? [child] : [];
|
278 | child.children.forEach(function (subchild) { return childrenEntities = childrenEntities.concat(findChildrenEntities(subchild)); });
|
279 | return childrenEntities;
|
280 | };
|
281 | return this.children.reduce(function (acc, entity) { return acc.concat(findChildrenEntities(entity)); }, []);
|
282 | };
|
283 | |
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 | Scene.prototype.getEntitiesInRange = function (xmin, xmax, ymin, ymax, id) {
|
293 | var entities = this.getEntities().
|
294 | filter(function (entity) { return entity.props.x > (xmin - entity.props.width) && entity.props.x < xmax; }).
|
295 | filter(function (entity) { return entity.props.y > (ymin - entity.props.height) && entity.props.y < ymax; });
|
296 | return id ? entities.filter(function (entity) { return id !== entity.id; }) : entities;
|
297 | };
|
298 |
|
299 | |
300 |
|
301 |
|
302 | Scene.prototype.onSizeChange = function () {
|
303 | _super.prototype.onSizeChange.call(this);
|
304 | if (this._background) {
|
305 | this._background.props.width = this.props.width;
|
306 | this._background.props.height = this.props.height;
|
307 | }
|
308 | };
|
309 | |
310 |
|
311 |
|
312 | Scene.prototype.updateFollow = function () {
|
313 | if (this.props.follow) {
|
314 | var follow = this.props.follow, target = follow.target;
|
315 | if (!target.killed) {
|
316 | this.props.x = target.props.x + (follow.centered ? (target.props.width / 2) - (this.props.width / 2) : 0) - follow.offsetX;
|
317 | this.props.y = target.props.y + (follow.centered ? (target.props.height / 2) - (this.props.height / 2) : 0) - follow.offsetY;
|
318 | }
|
319 | else {
|
320 | this.props.follow = null;
|
321 | }
|
322 | }
|
323 | };
|
324 | |
325 |
|
326 |
|
327 | Scene.prototype.onGravityChange = function () {
|
328 | if (this.world) {
|
329 | this.world.gravity = [0, Tool_1.Util.pixelToMeter(this.props.gravity)];
|
330 | }
|
331 | };
|
332 | |
333 |
|
334 |
|
335 | Scene.prototype.onBackgroundChange = function () {
|
336 | var _a = this.props, backgroundColor = _a.backgroundColor, backgroundAlpha = _a.backgroundAlpha;
|
337 | if (!this._background && backgroundColor && backgroundColor !== Tool_1.Color.transparent) {
|
338 | this._background = this.add(new Module_1.Shape(), {
|
339 | stroke: Tool_1.Color.transparent,
|
340 | width: this.props.width,
|
341 | height: this.props.height,
|
342 | fill: backgroundColor,
|
343 | fillAlpha: backgroundAlpha
|
344 | }, 0);
|
345 | }
|
346 | else if (this._background && (!backgroundColor || backgroundColor === Tool_1.Color.transparent)) {
|
347 | this._background.kill();
|
348 | this._background = null;
|
349 | }
|
350 | else if (this._background) {
|
351 | this._background.props.fill = backgroundColor;
|
352 | this._background.props.fillAlpha = backgroundAlpha;
|
353 | }
|
354 | };
|
355 | |
356 |
|
357 |
|
358 |
|
359 | Scene.prototype.onAssetsLoaded = function (done) {
|
360 | done();
|
361 | };
|
362 |
|
363 | |
364 |
|
365 |
|
366 |
|
367 |
|
368 | Scene.prototype._onPreSolve = function (_a) {
|
369 | var _this = this;
|
370 | var contactEquations = _a.contactEquations;
|
371 | contactEquations.forEach(function (contactEquation) {
|
372 | var ownerA = _this.getPhysicOwnerByBody(contactEquation.bodyA), ownerB = _this.getPhysicOwnerByBody(contactEquation.bodyB), wallA = (ownerA instanceof Entity_1.Wall) && ownerA, wallB = (ownerB instanceof Entity_1.Wall) && ownerB, entityA = ownerA && (wallA ? false : ownerA), entityB = ownerB && (wallB ? false : ownerB);
|
373 | if ((entityA && entityA.props.type === Tool_1.Enum.TYPE.GHOST) || (entityB && entityB.props.type === Tool_1.Enum.TYPE.GHOST)) {
|
374 | contactEquation.enabled = false;
|
375 | }
|
376 | else if ((!wallA && wallB) || (wallA && !wallB)) {
|
377 | var wall = wallA || wallB, entity = wallA ? entityB : entityA;
|
378 | if (entity) {
|
379 | contactEquation.enabled = !wall.isConstrainedByDirection(entity);
|
380 | }
|
381 | }
|
382 | });
|
383 | };
|
384 | |
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 | Scene.prototype._onBeginContact = function (_a) {
|
391 | var bodyA = _a.bodyA, bodyB = _a.bodyB;
|
392 | var contact = this._resolveContact(bodyA, bodyB), entityA = contact.entityA, entityB = contact.entityB;
|
393 | if (entityA && contact.contactA) {
|
394 | entityA.collides.push(contact.contactA);
|
395 | }
|
396 | if (entityB && contact.contactB) {
|
397 | entityB.collides.push(contact.contactB);
|
398 | }
|
399 | if (entityA instanceof Entity_1.Wall) {
|
400 | entityB.signals.wallCollision.dispatch();
|
401 | }
|
402 | else if (entityB instanceof Entity_1.Wall) {
|
403 | entityA.signals.wallCollision.dispatch();
|
404 | }
|
405 | else if (entityA && entityB) {
|
406 | contact.entityA.signals.beginCollision.dispatch(contact.entityB.name, contact.entityB);
|
407 | contact.entityB.signals.beginCollision.dispatch(contact.entityA.name, contact.entityA);
|
408 | }
|
409 | };
|
410 | |
411 |
|
412 |
|
413 |
|
414 |
|
415 |
|
416 | Scene.prototype._onEndContact = function (_a) {
|
417 | var bodyA = _a.bodyA, bodyB = _a.bodyB;
|
418 | var contact = this._resolveContact(bodyA, bodyB);
|
419 | if (!contact) {
|
420 | return null;
|
421 | }
|
422 | var entityA = contact.entityA, entityB = contact.entityB;
|
423 | if (entityA) {
|
424 | entityA.collides = entityA.collides.filter(function (collide) { return collide.bodyId !== contact.contactA.bodyId; });
|
425 | }
|
426 | if (entityB) {
|
427 | entityB.collides = entityB.collides.filter(function (collide) { return collide.bodyId !== contact.contactB.bodyId; });
|
428 | }
|
429 | if (entityA && entityB) {
|
430 | entityA.signals.endCollision.dispatch(entityB.name, entityB);
|
431 | entityB.signals.endCollision.dispatch(entityA.name, entityA);
|
432 | this.physics = this.physics.filter(function (physic) { return physic.enabled; });
|
433 | }
|
434 | };
|
435 | |
436 |
|
437 |
|
438 |
|
439 |
|
440 |
|
441 |
|
442 | Scene.prototype._resolveContact = function (bodyA, bodyB) {
|
443 | var ownerA = this.getPhysicOwnerByBody(bodyA), ownerB = this.getPhysicOwnerByBody(bodyB);
|
444 | var contactA = null, contactB = null;
|
445 | var isAbove = function (xA, yA, widthA, xB, yB, widthB) { return yB >= yA && (xA > xB - widthA) && (xA < xB + widthB); };
|
446 | switch (true) {
|
447 | case Boolean(ownerB instanceof Entity_1.Wall) && Boolean(ownerA):
|
448 | contactA = { bodyId: bodyB.id, isAbove: isAbove(ownerA.props.x, ownerA.props.y, ownerA.props.height, ownerB.props.x, ownerB.props.y, ownerB.props.width) };
|
449 | break;
|
450 | case Boolean(ownerA instanceof Entity_1.Wall) && Boolean(ownerB):
|
451 | contactB = { bodyId: bodyA.id, isAbove: isAbove(ownerB.props.x, ownerB.props.y, ownerB.props.height, ownerA.props.x, ownerA.props.y, ownerA.props.width) };
|
452 | break;
|
453 | case Boolean(ownerA) && Boolean(ownerB):
|
454 | contactA = { bodyId: bodyB.id, entity: ownerB, isAbove: isAbove(ownerA.props.x, ownerA.props.y, ownerA.props.height, ownerB.props.x, ownerB.props.y, ownerB.props.width) };
|
455 | contactB = { bodyId: bodyA.id, entity: ownerA, isAbove: isAbove(ownerB.props.x, ownerB.props.y, ownerB.props.height, ownerA.props.x, ownerA.props.y, ownerA.props.width) };
|
456 | break;
|
457 | }
|
458 | return (contactA || contactB) && { entityA: (ownerA instanceof Entity_1.Entity) && ownerA, entityB: (ownerB instanceof Entity_1.Entity) && ownerB, contactA: contactA, contactB: contactB };
|
459 | };
|
460 | return Scene;
|
461 | }(Module_1.Module));
|
462 | exports.Scene = Scene;
|