melonjs 10.12.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +6 -6
- package/dist/melonjs.js +22651 -22529
- package/dist/melonjs.min.js +5 -6
- package/dist/melonjs.module.d.ts +195 -195
- package/dist/melonjs.module.js +22107 -21977
- package/package.json +14 -14
- package/src/application/application.js +231 -0
- package/src/audio/audio.js +13 -7
- package/src/camera/camera2d.js +6 -6
- package/src/game.js +9 -232
- package/src/index.js +3 -3
- package/src/input/keyboard.js +2 -2
- package/src/input/pointer.js +4 -5
- package/src/input/pointerevent.js +8 -8
- package/src/lang/deprecated.js +0 -29
- package/src/level/level.js +2 -2
- package/src/level/tiled/TMXLayer.js +2 -2
- package/src/level/tiled/TMXTileMap.js +3 -3
- package/src/loader/loader.js +64 -28
- package/src/loader/loadingscreen.js +28 -115
- package/src/loader/melonjs_logo.png +0 -0
- package/src/physics/body.js +27 -51
- package/src/physics/detector.js +3 -3
- package/src/physics/quadtree.js +58 -29
- package/src/physics/world.js +32 -3
- package/src/polyfill/index.js +4 -0
- package/src/renderable/container.js +2 -2
- package/src/renderable/imagelayer.js +8 -8
- package/src/renderable/light2d.js +40 -11
- package/src/renderable/trigger.js +4 -4
- package/src/state/stage.js +1 -1
- package/src/state/state.js +50 -3
- package/src/system/device.js +808 -1039
- package/src/system/dom.js +69 -0
- package/src/system/event.js +13 -1
- package/src/system/platform.js +32 -0
- package/src/system/save.js +23 -14
- package/src/system/timer.js +12 -35
- package/src/text/bitmaptext.js +1 -2
- package/src/text/text.js +10 -14
- package/src/text/textmetrics.js +1 -2
- package/src/tweens/tween.js +6 -6
- package/src/utils/string.js +13 -24
- package/src/video/canvas/canvas_renderer.js +3 -2
- package/src/video/renderer.js +2 -2
- package/src/video/texture/canvas_texture.js +36 -2
- package/src/video/video.js +15 -9
- package/src/video/webgl/glshader.js +1 -1
- package/src/video/webgl/webgl_renderer.js +1 -1
package/src/physics/body.js
CHANGED
|
@@ -7,8 +7,6 @@ import collision from "./collision.js";
|
|
|
7
7
|
import * as arrayUtil from "./../utils/array.js";
|
|
8
8
|
import timer from "./../system/timer.js";
|
|
9
9
|
import { clamp } from "./../math/math.js";
|
|
10
|
-
import { world } from "./../game.js";
|
|
11
|
-
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
12
|
* @classdesc
|
|
@@ -74,7 +72,9 @@ class Body {
|
|
|
74
72
|
|
|
75
73
|
if (typeof this.vel === "undefined") {
|
|
76
74
|
/**
|
|
77
|
-
*
|
|
75
|
+
* The current velocity of the body.
|
|
76
|
+
* See to apply a force if you need to modify a body velocity
|
|
77
|
+
* @see Body.force
|
|
78
78
|
* @public
|
|
79
79
|
* @type {Vector2d}
|
|
80
80
|
* @default <0,0>
|
|
@@ -85,15 +85,15 @@ class Body {
|
|
|
85
85
|
|
|
86
86
|
if (typeof this.force === "undefined") {
|
|
87
87
|
/**
|
|
88
|
-
* body force
|
|
89
|
-
*
|
|
88
|
+
* body force to apply to this the body in the current step.
|
|
89
|
+
* (any positive or negative force will be cancelled after every world/body update cycle)
|
|
90
90
|
* @public
|
|
91
91
|
* @type {Vector2d}
|
|
92
92
|
* @default <0,0>
|
|
93
93
|
* @see Body.setMaxVelocity
|
|
94
94
|
* @example
|
|
95
95
|
* // define a default maximum acceleration, initial force and friction
|
|
96
|
-
* this.body.force.set(
|
|
96
|
+
* this.body.force.set(1, 0);
|
|
97
97
|
* this.body.friction.set(0.4, 0);
|
|
98
98
|
* this.body.setMaxVelocity(3, 15);
|
|
99
99
|
*
|
|
@@ -103,8 +103,6 @@ class Body {
|
|
|
103
103
|
* this.body.force.x = -this.body.maxVel.x;
|
|
104
104
|
* } else if (me.input.isKeyPressed("right")) {
|
|
105
105
|
* this.body.force.x = this.body.maxVel.x;
|
|
106
|
-
* } else {
|
|
107
|
-
* this.body.force.x = 0;
|
|
108
106
|
* }
|
|
109
107
|
* }
|
|
110
108
|
*/
|
|
@@ -463,10 +461,12 @@ class Body {
|
|
|
463
461
|
this.vel.y *= -this.bounce;
|
|
464
462
|
}
|
|
465
463
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
464
|
+
if (!this.ignoreGravity) {
|
|
465
|
+
// cancel the falling an jumping flags if necessary
|
|
466
|
+
var dir = this.falling === true ? 1 : this.jumping === true ? -1 : 0;
|
|
467
|
+
this.falling = overlap.y >= dir;
|
|
468
|
+
this.jumping = overlap.y <= -dir;
|
|
469
|
+
}
|
|
470
470
|
}
|
|
471
471
|
}
|
|
472
472
|
|
|
@@ -507,14 +507,12 @@ class Body {
|
|
|
507
507
|
}
|
|
508
508
|
}
|
|
509
509
|
|
|
510
|
-
|
|
511
510
|
/**
|
|
512
511
|
* Returns true if the any of the shape composing the body contains the given point.
|
|
513
512
|
* @method Body#contains
|
|
514
513
|
* @param {Vector2d} point
|
|
515
514
|
* @returns {boolean} true if contains
|
|
516
515
|
*/
|
|
517
|
-
|
|
518
516
|
/**
|
|
519
517
|
* Returns true if the any of the shape composing the body contains the given point.
|
|
520
518
|
* @param {number} x x coordinate
|
|
@@ -591,27 +589,23 @@ class Body {
|
|
|
591
589
|
}
|
|
592
590
|
|
|
593
591
|
/**
|
|
594
|
-
*
|
|
595
|
-
*
|
|
592
|
+
* Updates the parent's position as well as computes the new body's velocity based
|
|
593
|
+
* on the values of force/friction. Velocity chages are proportional to the
|
|
594
|
+
* me.timer.tick value (which can be used to scale velocities). The approach to moving the
|
|
595
|
+
* parent renderable is to compute new values of the Body.vel property then add them to
|
|
596
|
+
* the parent.pos value thus changing the postion the amount of Body.vel each time the
|
|
597
|
+
* update call is made. <br>
|
|
598
|
+
* Updates to Body.vel are bounded by maxVel (which defaults to viewport size if not set) <br>
|
|
599
|
+
* At this time a call to Body.Update does not call the onBodyUpdate callback that is listed in the constructor arguments.
|
|
600
|
+
* @protected
|
|
601
|
+
* @param {number} dt time since the last update in milliseconds.
|
|
602
|
+
* @returns {boolean} true if resulting velocity is different than 0
|
|
596
603
|
*/
|
|
597
|
-
|
|
604
|
+
update(dt) { // eslint-disable-line no-unused-vars
|
|
598
605
|
// apply timer.tick to delta time for linear interpolation (when enabled)
|
|
599
606
|
// #761 add delta time in body update
|
|
600
607
|
var deltaTime = /* dt * */ timer.tick;
|
|
601
608
|
|
|
602
|
-
// apply gravity to the current velocity
|
|
603
|
-
if (!this.ignoreGravity) {
|
|
604
|
-
var worldGravity = world.gravity;
|
|
605
|
-
|
|
606
|
-
// apply gravity if defined
|
|
607
|
-
this.vel.x += worldGravity.x * this.gravityScale * deltaTime;
|
|
608
|
-
this.vel.y += worldGravity.y * this.gravityScale * deltaTime;
|
|
609
|
-
|
|
610
|
-
// check if falling / jumping
|
|
611
|
-
this.falling = (this.vel.y * Math.sign(worldGravity.y * this.gravityScale)) > 0;
|
|
612
|
-
this.jumping = (this.falling ? false : this.jumping);
|
|
613
|
-
}
|
|
614
|
-
|
|
615
609
|
// apply force if defined
|
|
616
610
|
if (this.force.x !== 0) {
|
|
617
611
|
this.vel.x += this.force.x * deltaTime;
|
|
@@ -649,28 +643,10 @@ class Body {
|
|
|
649
643
|
if (this.vel.x !== 0) {
|
|
650
644
|
this.vel.x = clamp(this.vel.x, -this.maxVel.x, this.maxVel.x);
|
|
651
645
|
}
|
|
652
|
-
}
|
|
653
646
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
* me.timer.tick value (which can be used to scale velocities). The approach to moving the
|
|
658
|
-
* parent renderable is to compute new values of the Body.vel property then add them to
|
|
659
|
-
* the parent.pos value thus changing the postion the amount of Body.vel each time the
|
|
660
|
-
* update call is made. <br>
|
|
661
|
-
* Updates to Body.vel are bounded by maxVel (which defaults to viewport size if not set) <br>
|
|
662
|
-
*
|
|
663
|
-
* In addition, when the gravity calcuation is made, if the Body.vel.y > 0 then the Body.falling
|
|
664
|
-
* property is set to true and Body.jumping is set to !Body.falling.
|
|
665
|
-
*
|
|
666
|
-
* At this time a call to Body.Update does not call the onBodyUpdate callback that is listed in the constructor arguments.
|
|
667
|
-
* @protected
|
|
668
|
-
* @param {number} dt time since the last update in milliseconds.
|
|
669
|
-
* @returns {boolean} true if resulting velocity is different than 0
|
|
670
|
-
*/
|
|
671
|
-
update(dt) {
|
|
672
|
-
// update the velocity
|
|
673
|
-
this.computeVelocity(dt);
|
|
647
|
+
// check if falling / jumping
|
|
648
|
+
this.falling = (this.vel.y * Math.sign(this.force.y)) > 0;
|
|
649
|
+
this.jumping = (this.falling ? false : this.jumping);
|
|
674
650
|
|
|
675
651
|
// update the body ancestor position
|
|
676
652
|
this.ancestor.pos.add(this.vel);
|
package/src/physics/detector.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as SAT from "./sat.js";
|
|
2
2
|
import ResponseObject from "./response.js";
|
|
3
3
|
import Vector2d from "./../math/vector2.js";
|
|
4
|
-
import
|
|
4
|
+
import game from "./../game.js";
|
|
5
5
|
|
|
6
6
|
// a dummy object when using Line for raycasting
|
|
7
7
|
let dummyObj = {
|
|
@@ -50,7 +50,7 @@ function shouldCollide(a, b) {
|
|
|
50
50
|
export function collisionCheck(objA, response = globalResponse) {
|
|
51
51
|
var collisionCounter = 0;
|
|
52
52
|
// retreive a list of potential colliding objects from the game world
|
|
53
|
-
var candidates = world.broadphase.retrieve(objA);
|
|
53
|
+
var candidates = game.world.broadphase.retrieve(objA);
|
|
54
54
|
|
|
55
55
|
for (var i = candidates.length, objB; i--, (objB = candidates[i]);) {
|
|
56
56
|
|
|
@@ -139,7 +139,7 @@ export function rayCast(line, result = []) {
|
|
|
139
139
|
var collisionCounter = 0;
|
|
140
140
|
|
|
141
141
|
// retrieve a list of potential colliding objects from the game world
|
|
142
|
-
var candidates = world.broadphase.retrieve(line);
|
|
142
|
+
var candidates = game.world.broadphase.retrieve(line);
|
|
143
143
|
|
|
144
144
|
for (var i = candidates.length, objB; i--, (objB = candidates[i]);) {
|
|
145
145
|
|
package/src/physics/quadtree.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Vector2d from "./../math/vector2.js";
|
|
2
2
|
import Container from "./../renderable/container.js";
|
|
3
3
|
import * as arrayUtil from "./../utils/array.js";
|
|
4
|
-
import { viewport } from "./../game.js";
|
|
5
4
|
|
|
6
5
|
/*
|
|
7
6
|
* A QuadTree implementation in JavaScript, a 2d spatial subdivision algorithm.
|
|
@@ -21,16 +20,17 @@ var QT_ARRAY = [];
|
|
|
21
20
|
* or create a new one if the array is empty
|
|
22
21
|
* @ignore
|
|
23
22
|
*/
|
|
24
|
-
function QT_ARRAY_POP(bounds, max_objects = 4, max_levels = 4, level = 0) {
|
|
23
|
+
function QT_ARRAY_POP(world, bounds, max_objects = 4, max_levels = 4, level = 0) {
|
|
25
24
|
if (QT_ARRAY.length > 0) {
|
|
26
25
|
var _qt = QT_ARRAY.pop();
|
|
26
|
+
_qt.world = world;
|
|
27
27
|
_qt.bounds = bounds;
|
|
28
28
|
_qt.max_objects = max_objects;
|
|
29
29
|
_qt.max_levels = max_levels;
|
|
30
30
|
_qt.level = level;
|
|
31
31
|
return _qt;
|
|
32
32
|
} else {
|
|
33
|
-
return new QuadTree(bounds, max_objects, max_levels, level);
|
|
33
|
+
return new QuadTree(world, bounds, max_objects, max_levels, level);
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
|
|
@@ -55,12 +55,17 @@ var QT_VECTOR = new Vector2d();
|
|
|
55
55
|
*/
|
|
56
56
|
class QuadTree {
|
|
57
57
|
/**
|
|
58
|
+
* @param {World} world the physic world this QuadTree belongs to
|
|
58
59
|
* @param {Bounds} bounds bounds of the node
|
|
59
60
|
* @param {number} [max_objects=4] max objects a node can hold before splitting into 4 subnodes
|
|
60
61
|
* @param {number} [max_levels=4] total max levels inside root Quadtree
|
|
61
62
|
* @param {number} [level] deepth level, required for subnodes
|
|
62
63
|
*/
|
|
63
|
-
constructor(bounds, max_objects = 4, max_levels = 4, level = 0) {
|
|
64
|
+
constructor(world, bounds, max_objects = 4, max_levels = 4, level = 0) {
|
|
65
|
+
|
|
66
|
+
this.world = world;
|
|
67
|
+
this.bounds = bounds;
|
|
68
|
+
|
|
64
69
|
this.max_objects = max_objects;
|
|
65
70
|
this.max_levels = max_levels;
|
|
66
71
|
|
|
@@ -82,36 +87,60 @@ class QuadTree {
|
|
|
82
87
|
top = this.bounds.top;
|
|
83
88
|
|
|
84
89
|
//top right node
|
|
85
|
-
this.nodes[0] = QT_ARRAY_POP(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
this.nodes[0] = QT_ARRAY_POP(
|
|
91
|
+
this.world,
|
|
92
|
+
this.bounds, {
|
|
93
|
+
left : left + subWidth,
|
|
94
|
+
top : top,
|
|
95
|
+
width : subWidth,
|
|
96
|
+
height : subHeight
|
|
97
|
+
},
|
|
98
|
+
this.max_objects,
|
|
99
|
+
this.max_levels,
|
|
100
|
+
nextLevel
|
|
101
|
+
);
|
|
91
102
|
|
|
92
103
|
//top left node
|
|
93
|
-
this.nodes[1] = QT_ARRAY_POP(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
this.nodes[1] = QT_ARRAY_POP(
|
|
105
|
+
this.world,
|
|
106
|
+
this.bounds, {
|
|
107
|
+
left : left,
|
|
108
|
+
top: top,
|
|
109
|
+
width : subWidth,
|
|
110
|
+
height : subHeight
|
|
111
|
+
},
|
|
112
|
+
this.max_objects,
|
|
113
|
+
this.max_levels,
|
|
114
|
+
nextLevel
|
|
115
|
+
);
|
|
99
116
|
|
|
100
117
|
//bottom left node
|
|
101
|
-
this.nodes[2] = QT_ARRAY_POP(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
118
|
+
this.nodes[2] = QT_ARRAY_POP(
|
|
119
|
+
this.world,
|
|
120
|
+
this.bounds, {
|
|
121
|
+
left : left,
|
|
122
|
+
top : top + subHeight,
|
|
123
|
+
width : subWidth,
|
|
124
|
+
height : subHeight
|
|
125
|
+
},
|
|
126
|
+
this.max_objects,
|
|
127
|
+
this.max_levels,
|
|
128
|
+
nextLevel
|
|
129
|
+
);
|
|
107
130
|
|
|
108
131
|
//bottom right node
|
|
109
|
-
this.nodes[3] = QT_ARRAY_POP(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
132
|
+
this.nodes[3] = QT_ARRAY_POP(
|
|
133
|
+
this.world,
|
|
134
|
+
this.bounds, {
|
|
135
|
+
left : left + subWidth,
|
|
136
|
+
top : top + subHeight,
|
|
137
|
+
width : subWidth,
|
|
138
|
+
height : subHeight
|
|
139
|
+
},
|
|
140
|
+
this.max_objects,
|
|
141
|
+
this.max_levels,
|
|
142
|
+
nextLevel
|
|
143
|
+
);
|
|
115
144
|
}
|
|
116
145
|
|
|
117
146
|
/*
|
|
@@ -125,7 +154,7 @@ class QuadTree {
|
|
|
125
154
|
|
|
126
155
|
// use game world coordinates for floating items
|
|
127
156
|
if (item.isFloating === true) {
|
|
128
|
-
pos = viewport.localToWorld(bounds.left, bounds.top, QT_VECTOR);
|
|
157
|
+
pos = this.world.app.viewport.localToWorld(bounds.left, bounds.top, QT_VECTOR);
|
|
129
158
|
} else {
|
|
130
159
|
pos = QT_VECTOR.set(item.left, item.top);
|
|
131
160
|
}
|
package/src/physics/world.js
CHANGED
|
@@ -28,6 +28,13 @@ class World extends Container {
|
|
|
28
28
|
// to mimic the previous behavior
|
|
29
29
|
this.anchorPoint.set(0, 0);
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* the application (game) this physic world belong to
|
|
33
|
+
* @public
|
|
34
|
+
* @type {Application}
|
|
35
|
+
*/
|
|
36
|
+
this.app = null;
|
|
37
|
+
|
|
31
38
|
/**
|
|
32
39
|
* the rate at which the game world is updated,
|
|
33
40
|
* may be greater than or lower than the display fps
|
|
@@ -80,7 +87,7 @@ class World extends Container {
|
|
|
80
87
|
* @public
|
|
81
88
|
* @type {QuadTree}
|
|
82
89
|
*/
|
|
83
|
-
this.broadphase = new QuadTree(this.getBounds().clone(), collision.maxChildren, collision.maxDepth);
|
|
90
|
+
this.broadphase = new QuadTree(this, this.getBounds().clone(), collision.maxChildren, collision.maxDepth);
|
|
84
91
|
|
|
85
92
|
// reset the world container on the game reset signal
|
|
86
93
|
event.on(event.GAME_RESET, this.reset, this);
|
|
@@ -140,6 +147,24 @@ class World extends Container {
|
|
|
140
147
|
return this;
|
|
141
148
|
}
|
|
142
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Apply gravity to the given body
|
|
152
|
+
* @name bodyApplyVelocity
|
|
153
|
+
* @memberof World
|
|
154
|
+
* @private
|
|
155
|
+
* @param {Body} body
|
|
156
|
+
*/
|
|
157
|
+
bodyApplyGravity(body) {
|
|
158
|
+
// apply gravity to the current velocity
|
|
159
|
+
if (!body.ignoreGravity && body.gravityScale !== 0) {
|
|
160
|
+
var gravity = this.gravity;
|
|
161
|
+
|
|
162
|
+
// apply gravity if defined
|
|
163
|
+
body.force.x += (body.mass * gravity.x) * body.gravityScale;
|
|
164
|
+
body.force.y += (body.mass * gravity.y) * body.gravityScale;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
143
168
|
/**
|
|
144
169
|
* update the game world
|
|
145
170
|
* @name reset
|
|
@@ -147,7 +172,7 @@ class World extends Container {
|
|
|
147
172
|
* @param {number} dt the time passed since the last frame update
|
|
148
173
|
* @returns {boolean} true if the word is dirty
|
|
149
174
|
*/
|
|
150
|
-
update
|
|
175
|
+
update(dt) {
|
|
151
176
|
var isPaused = state.isPaused();
|
|
152
177
|
|
|
153
178
|
// clear the quadtree
|
|
@@ -163,13 +188,17 @@ class World extends Container {
|
|
|
163
188
|
// if the game is not paused, and ancestor can be updated
|
|
164
189
|
if (!(isPaused && (!ancestor.updateWhenPaused)) &&
|
|
165
190
|
(ancestor.inViewport || ancestor.alwaysUpdate)) {
|
|
166
|
-
// apply
|
|
191
|
+
// apply gravity to this body
|
|
192
|
+
this.bodyApplyGravity(body);
|
|
193
|
+
// body update function (this moves it)
|
|
167
194
|
if (body.update(dt) === true) {
|
|
168
195
|
// mark ancestor as dirty
|
|
169
196
|
ancestor.isDirty = true;
|
|
170
197
|
};
|
|
171
198
|
// handle collisions against other objects
|
|
172
199
|
collisionCheck(ancestor);
|
|
200
|
+
// clear body force
|
|
201
|
+
body.force.set(0, 0);
|
|
173
202
|
}
|
|
174
203
|
}
|
|
175
204
|
});
|
package/src/polyfill/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// https://github.com/melonjs/melonJS/issues/1092
|
|
2
2
|
import "core-js/proposals/global-this";
|
|
3
3
|
|
|
4
|
+
// es10 string trim functions
|
|
5
|
+
import "core-js/es/string/trim-left";
|
|
6
|
+
import "core-js/es/string/trim-right";
|
|
7
|
+
|
|
4
8
|
// "built-in" polyfills
|
|
5
9
|
import "./console.js";
|
|
6
10
|
import "./performance.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import utils from "./../utils/utils.js";
|
|
2
|
-
import
|
|
2
|
+
import game from "./../game.js";
|
|
3
3
|
import * as event from "./../system/event.js";
|
|
4
4
|
import pool from "./../system/pooling.js";
|
|
5
5
|
import state from "./../state/state.js";
|
|
@@ -638,7 +638,7 @@ class Container extends Renderable {
|
|
|
638
638
|
* @memberof Container
|
|
639
639
|
* @public
|
|
640
640
|
* @param {Renderable} child
|
|
641
|
-
* @param {boolean} [keepalive=
|
|
641
|
+
* @param {boolean} [keepalive=false] true to prevent calling child.destroy()
|
|
642
642
|
*/
|
|
643
643
|
removeChild(child, keepalive) {
|
|
644
644
|
if (this.hasChild(child)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { renderer } from "./../video/video.js";
|
|
2
2
|
import * as event from "./../system/event.js";
|
|
3
3
|
import pool from "./../system/pooling.js";
|
|
4
|
-
import
|
|
4
|
+
import game from "./../game.js";
|
|
5
5
|
import Sprite from "./sprite.js";
|
|
6
6
|
import * as stringUtil from "./../utils/string.js";
|
|
7
7
|
|
|
@@ -134,7 +134,7 @@ class ImageLayer extends Sprite {
|
|
|
134
134
|
this.repeatY = true;
|
|
135
135
|
break;
|
|
136
136
|
}
|
|
137
|
-
this.resize(viewport.width, viewport.height);
|
|
137
|
+
this.resize(game.viewport.width, game.viewport.height);
|
|
138
138
|
this.createPattern();
|
|
139
139
|
}
|
|
140
140
|
|
|
@@ -146,13 +146,13 @@ class ImageLayer extends Sprite {
|
|
|
146
146
|
event.on(event.VIEWPORT_ONRESIZE, this.resize, this);
|
|
147
147
|
// force a first refresh when the level is loaded
|
|
148
148
|
event.once(event.LEVEL_LOADED, () => {
|
|
149
|
-
this.updateLayer(viewport.pos);
|
|
149
|
+
this.updateLayer(game.viewport.pos);
|
|
150
150
|
});
|
|
151
151
|
// in case the level is not added to the root container,
|
|
152
152
|
// the onActivateEvent call happens after the LEVEL_LOADED event
|
|
153
153
|
// so we need to force a first update
|
|
154
154
|
if (this.ancestor.root !== true) {
|
|
155
|
-
this.updateLayer(viewport.pos);
|
|
155
|
+
this.updateLayer(game.viewport.pos);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
|
@@ -193,8 +193,8 @@ class ImageLayer extends Sprite {
|
|
|
193
193
|
|
|
194
194
|
var width = this.width,
|
|
195
195
|
height = this.height,
|
|
196
|
-
bw = viewport.bounds.width,
|
|
197
|
-
bh = viewport.bounds.height,
|
|
196
|
+
bw = game.viewport.bounds.width,
|
|
197
|
+
bh = game.viewport.bounds.height,
|
|
198
198
|
ax = this.anchorPoint.x,
|
|
199
199
|
ay = this.anchorPoint.y,
|
|
200
200
|
|
|
@@ -204,8 +204,8 @@ class ImageLayer extends Sprite {
|
|
|
204
204
|
* See https://github.com/melonjs/melonJS/issues/741#issuecomment-138431532
|
|
205
205
|
* for a thorough description of how this works.
|
|
206
206
|
*/
|
|
207
|
-
x = ax * (rx - 1) * (bw - viewport.width) + this.offset.x - rx * vpos.x,
|
|
208
|
-
y = ay * (ry - 1) * (bh - viewport.height) + this.offset.y - ry * vpos.y;
|
|
207
|
+
x = ax * (rx - 1) * (bw - game.viewport.width) + this.offset.x - rx * vpos.x,
|
|
208
|
+
y = ay * (ry - 1) * (bh - game.viewport.height) + this.offset.y - ry * vpos.y;
|
|
209
209
|
|
|
210
210
|
|
|
211
211
|
// Repeat horizontally; start drawing from left boundary
|
|
@@ -4,19 +4,41 @@ import Renderable from "./renderable.js";
|
|
|
4
4
|
/** @ignore */
|
|
5
5
|
function createGradient(light) {
|
|
6
6
|
var context = light.texture.context;
|
|
7
|
-
|
|
8
|
-
var
|
|
9
|
-
|
|
7
|
+
|
|
8
|
+
var x1 = light.texture.width / 2,
|
|
9
|
+
y1 = light.texture.height / 2;
|
|
10
|
+
|
|
11
|
+
var radiusX = light.radiusX,
|
|
12
|
+
radiusY = light.radiusY;
|
|
13
|
+
|
|
14
|
+
var scaleX, scaleY, invScaleX, invScaleY;
|
|
15
|
+
var gradient;
|
|
16
|
+
|
|
10
17
|
|
|
11
18
|
light.texture.clear();
|
|
12
19
|
|
|
20
|
+
if (radiusX >= radiusY) {
|
|
21
|
+
scaleX = 1;
|
|
22
|
+
invScaleX = 1;
|
|
23
|
+
scaleY = radiusY/radiusX;
|
|
24
|
+
invScaleY = radiusX/radiusY;
|
|
25
|
+
gradient = context.createRadialGradient(x1, y1 * invScaleY, 0, x1, radiusY * invScaleY, radiusX);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
scaleY = 1;
|
|
29
|
+
invScaleY = 1;
|
|
30
|
+
scaleX = radiusX/radiusY;
|
|
31
|
+
invScaleX = radiusY/radiusX;
|
|
32
|
+
gradient = context.createRadialGradient(x1 * invScaleX, y1, 0, x1 * invScaleX, y1, radiusY);
|
|
33
|
+
}
|
|
34
|
+
|
|
13
35
|
gradient.addColorStop( 0, light.color.toRGBA(light.intensity));
|
|
14
36
|
gradient.addColorStop( 1, light.color.toRGBA(0.0));
|
|
15
37
|
|
|
16
|
-
context.beginPath();
|
|
17
38
|
context.fillStyle = gradient;
|
|
18
|
-
|
|
19
|
-
context.
|
|
39
|
+
|
|
40
|
+
context.setTransform(scaleX, 0, 0, scaleY, 0, 0);
|
|
41
|
+
context.fillRect(0, 0, light.texture.width * invScaleX, light.texture.height * invScaleY);
|
|
20
42
|
}
|
|
21
43
|
|
|
22
44
|
/**
|
|
@@ -31,13 +53,14 @@ class Light2d extends Renderable {
|
|
|
31
53
|
/**
|
|
32
54
|
* @param {number} x - The horizontal position of the light.
|
|
33
55
|
* @param {number} y - The vertical position of the light.
|
|
34
|
-
* @param {number}
|
|
56
|
+
* @param {number} radiusX - The horizontal radius of the light.
|
|
57
|
+
* @param {number} [radiusY=radiusX] - The vertical radius of the light.
|
|
35
58
|
* @param {Color|string} [color="#FFF"] the color of the light
|
|
36
59
|
* @param {number} [intensity=0.7] - The intensity of the light.
|
|
37
60
|
*/
|
|
38
|
-
constructor(x, y,
|
|
61
|
+
constructor(x, y, radiusX, radiusY = radiusX, color = "#FFF", intensity = 0.7) {
|
|
39
62
|
// call the parent constructor
|
|
40
|
-
super(x, y,
|
|
63
|
+
super(x, y, radiusX * 2, radiusY * 2);
|
|
41
64
|
|
|
42
65
|
/**
|
|
43
66
|
* the color of the light
|
|
@@ -47,10 +70,16 @@ class Light2d extends Renderable {
|
|
|
47
70
|
this.color = pool.pull("Color").parseCSS(color);
|
|
48
71
|
|
|
49
72
|
/**
|
|
50
|
-
* The radius of the light
|
|
73
|
+
* The horizontal radius of the light
|
|
74
|
+
* @type {number}
|
|
75
|
+
*/
|
|
76
|
+
this.radiusX = radiusX;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The vertical radius of the light
|
|
51
80
|
* @type {number}
|
|
52
81
|
*/
|
|
53
|
-
this.
|
|
82
|
+
this.radiusY = radiusY;
|
|
54
83
|
|
|
55
84
|
/**
|
|
56
85
|
* The intensity of the light
|
|
@@ -2,7 +2,7 @@ import Renderable from "./renderable.js";
|
|
|
2
2
|
import collision from "./../physics/collision.js";
|
|
3
3
|
import Body from "./../physics/body.js";
|
|
4
4
|
import level from "./../level/level.js";
|
|
5
|
-
import
|
|
5
|
+
import game from "./../game.js";
|
|
6
6
|
import pool from "./../system/pooling.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -89,7 +89,7 @@ class Trigger extends Renderable {
|
|
|
89
89
|
getTriggerSettings() {
|
|
90
90
|
// Lookup for the container instance
|
|
91
91
|
if (typeof(this.triggerSettings.container) === "string") {
|
|
92
|
-
this.triggerSettings.container = world.getChildByName(this.triggerSettings.container)[0];
|
|
92
|
+
this.triggerSettings.container = game.world.getChildByName(this.triggerSettings.container)[0];
|
|
93
93
|
}
|
|
94
94
|
return this.triggerSettings;
|
|
95
95
|
}
|
|
@@ -99,7 +99,7 @@ class Trigger extends Renderable {
|
|
|
99
99
|
*/
|
|
100
100
|
onFadeComplete() {
|
|
101
101
|
level.load(this.gotolevel, this.getTriggerSettings());
|
|
102
|
-
viewport.fadeOut(this.fade, this.duration);
|
|
102
|
+
game.viewport.fadeOut(this.fade, this.duration);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/**
|
|
@@ -118,7 +118,7 @@ class Trigger extends Renderable {
|
|
|
118
118
|
if (this.fade && this.duration) {
|
|
119
119
|
if (!this.fading) {
|
|
120
120
|
this.fading = true;
|
|
121
|
-
viewport.fadeIn(this.fade, this.duration,
|
|
121
|
+
game.viewport.fadeIn(this.fade, this.duration,
|
|
122
122
|
this.onFadeComplete.bind(this));
|
|
123
123
|
}
|
|
124
124
|
} else {
|
package/src/state/stage.js
CHANGED
package/src/state/state.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { pauseTrack, resumeTrack } from "./../audio/audio.js";
|
|
2
2
|
import * as fctUtil from "./../utils/function.js";
|
|
3
3
|
import * as event from "./../system/event.js";
|
|
4
|
-
import
|
|
4
|
+
import game from "./../game.js";
|
|
5
|
+
import * as device from "./../system/device.js";
|
|
5
6
|
import Stage from "./../state/stage.js";
|
|
6
7
|
import DefaultLoadingScreen from "./../loader/loadingscreen.js";
|
|
7
8
|
|
|
@@ -140,14 +141,60 @@ event.on(event.BOOT, () => {
|
|
|
140
141
|
event.on(event.VIDEO_INIT, () => {
|
|
141
142
|
state.change(state.DEFAULT, true);
|
|
142
143
|
});
|
|
143
|
-
});
|
|
144
144
|
|
|
145
|
+
if (typeof globalThis.addEventListener === "function") {
|
|
146
|
+
// set pause/stop action on losing focus
|
|
147
|
+
globalThis.addEventListener("blur", () => {
|
|
148
|
+
if (device.stopOnBlur) {
|
|
149
|
+
state.stop(true);
|
|
150
|
+
}
|
|
151
|
+
if (device.pauseOnBlur) {
|
|
152
|
+
state.pause(true);
|
|
153
|
+
}
|
|
154
|
+
}, false);
|
|
155
|
+
// set restart/resume action on gaining focus
|
|
156
|
+
globalThis.addEventListener("focus", () => {
|
|
157
|
+
if (device.stopOnBlur) {
|
|
158
|
+
state.restart(true);
|
|
159
|
+
}
|
|
160
|
+
if (device.resumeOnFocus) {
|
|
161
|
+
state.resume(true);
|
|
162
|
+
}
|
|
163
|
+
// force focus if autofocus is on
|
|
164
|
+
if (device.autoFocus) {
|
|
165
|
+
device.focus();
|
|
166
|
+
}
|
|
167
|
+
}, false);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (typeof globalThis.document !== "undefined") {
|
|
171
|
+
if (typeof globalThis.document.addEventListener === "function") {
|
|
172
|
+
// register on the visibilitychange event if supported
|
|
173
|
+
globalThis.document.addEventListener("visibilitychange", () => {
|
|
174
|
+
if (globalThis.document.visibilityState === "visible") {
|
|
175
|
+
if (device.stopOnBlur) {
|
|
176
|
+
state.restart(true);
|
|
177
|
+
}
|
|
178
|
+
if (device.resumeOnFocus) {
|
|
179
|
+
state.resume(true);
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
if (device.stopOnBlur) {
|
|
183
|
+
state.stop(true);
|
|
184
|
+
}
|
|
185
|
+
if (device.pauseOnBlur) {
|
|
186
|
+
state.pause(true);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}, false );
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
145
193
|
|
|
146
194
|
/**
|
|
147
195
|
* a State Manager (state machine)
|
|
148
196
|
* @namespace state
|
|
149
197
|
*/
|
|
150
|
-
|
|
151
198
|
var state = {
|
|
152
199
|
|
|
153
200
|
/**
|