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