melonjs 12.0.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 +4 -6
- package/dist/melonjs.js +22325 -22327
- package/dist/melonjs.min.js +5 -6
- package/dist/melonjs.module.d.ts +184 -171
- package/dist/melonjs.module.js +20780 -20771
- package/package.json +12 -13
- package/src/application/application.js +231 -0
- package/src/audio/audio.js +8 -2
- 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 +27 -28
- 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/renderable/container.js +2 -2
- package/src/renderable/imagelayer.js +8 -8
- 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 +814 -981
- package/src/system/event.js +2 -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/text.js +9 -12
- package/src/tweens/tween.js +6 -6
- package/src/utils/string.js +13 -0
- 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/input/pointer.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Vector2d from "./../math/vector2.js";
|
|
2
|
-
import device from "./../system/device.js";
|
|
3
2
|
import Bounds from "./../physics/bounds.js";
|
|
4
|
-
import
|
|
3
|
+
import game from "./../game.js";
|
|
5
4
|
import { globalToLocal } from "./input.js";
|
|
6
5
|
import { locked } from "./pointerevent.js";
|
|
7
6
|
|
|
@@ -333,7 +332,7 @@ class Pointer extends Bounds {
|
|
|
333
332
|
this.gameScreenY = this.y = tmpVec.y;
|
|
334
333
|
|
|
335
334
|
// true if not originally a pointer event
|
|
336
|
-
this.isNormalized =
|
|
335
|
+
this.isNormalized = (typeof globalThis.PointerEvent !== "undefined" && !(event instanceof globalThis.PointerEvent));
|
|
337
336
|
|
|
338
337
|
this.locked = locked;
|
|
339
338
|
this.movementX = event.movementX || 0;
|
|
@@ -361,8 +360,8 @@ class Pointer extends Bounds {
|
|
|
361
360
|
this.type = event.type;
|
|
362
361
|
|
|
363
362
|
// get the current screen to game world offset
|
|
364
|
-
if (typeof viewport !== "undefined") {
|
|
365
|
-
viewport.localToWorld(this.gameScreenX, this.gameScreenY, tmpVec);
|
|
363
|
+
if (typeof game.viewport !== "undefined") {
|
|
364
|
+
game.viewport.localToWorld(this.gameScreenX, this.gameScreenY, tmpVec);
|
|
366
365
|
}
|
|
367
366
|
|
|
368
367
|
/* Initialize the two coordinate space properties. */
|
|
@@ -6,11 +6,11 @@ import { remove } from "./../utils/array.js";
|
|
|
6
6
|
import * as event from "./../system/event.js";
|
|
7
7
|
import timer from "./../system/timer.js";
|
|
8
8
|
import pool from "./../system/pooling.js";
|
|
9
|
-
import device from "./../system/device.js";
|
|
9
|
+
import * as device from "./../system/device.js";
|
|
10
10
|
import Pointer from "./pointer.js";
|
|
11
11
|
import Rect from "./../geometries/rectangle.js";
|
|
12
12
|
import Container from "./../renderable/container.js";
|
|
13
|
-
import
|
|
13
|
+
import game from "./../game.js";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* A pool of `Pointer` objects to cache pointer/touch event coordinates.
|
|
@@ -128,14 +128,14 @@ function enablePointerEvent() {
|
|
|
128
128
|
pointerEventTarget = renderer.getScreenCanvas();
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
if (device.
|
|
131
|
+
if (device.pointerEvent) {
|
|
132
132
|
// standard Pointer Events
|
|
133
133
|
activeEventList = pointerEventList;
|
|
134
134
|
} else {
|
|
135
135
|
// Regular Mouse events
|
|
136
136
|
activeEventList = mouseEventList;
|
|
137
137
|
}
|
|
138
|
-
if (device.touch && !device.
|
|
138
|
+
if (device.touch && !device.pointerEvent) {
|
|
139
139
|
// touch event on mobile devices
|
|
140
140
|
activeEventList = activeEventList.concat(touchEventList);
|
|
141
141
|
}
|
|
@@ -287,10 +287,10 @@ function dispatchEvent(normalizedEvents) {
|
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
// fetch valid candiates from the game world container
|
|
290
|
-
var candidates = world.broadphase.retrieve(currentPointer, Container.prototype._sortReverseZ);
|
|
290
|
+
var candidates = game.world.broadphase.retrieve(currentPointer, Container.prototype._sortReverseZ);
|
|
291
291
|
|
|
292
292
|
// add the main game viewport to the list of candidates
|
|
293
|
-
candidates = candidates.concat([ viewport ]);
|
|
293
|
+
candidates = candidates.concat([ game.viewport ]);
|
|
294
294
|
|
|
295
295
|
for (var c = candidates.length, candidate; c--, (candidate = candidates[c]);) {
|
|
296
296
|
if (eventHandlers.has(candidate) && (candidate.isKinematic !== true)) {
|
|
@@ -416,7 +416,7 @@ function normalizeEvent(originalEvent) {
|
|
|
416
416
|
var _pointer;
|
|
417
417
|
|
|
418
418
|
// PointerEvent or standard Mouse event
|
|
419
|
-
if (device.
|
|
419
|
+
if (device.touchEvent && originalEvent.changedTouches) {
|
|
420
420
|
// iOS/Android Touch event
|
|
421
421
|
for (var i = 0, l = originalEvent.changedTouches.length; i < l; i++) {
|
|
422
422
|
var touchEvent = originalEvent.changedTouches[i];
|
|
@@ -557,7 +557,7 @@ export var throttlingInterval;
|
|
|
557
557
|
export function globalToLocal(x, y, v) {
|
|
558
558
|
v = v || pool.pull("Vector2d");
|
|
559
559
|
var rect = device.getElementBounds(renderer.getScreenCanvas());
|
|
560
|
-
var pixelRatio =
|
|
560
|
+
var pixelRatio = globalThis.devicePixelRatio || 1;
|
|
561
561
|
x -= rect.left + (globalThis.pageXOffset || 0);
|
|
562
562
|
y -= rect.top + (globalThis.pageYOffset || 0);
|
|
563
563
|
var scale = scaleRatio;
|
package/src/lang/deprecated.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import device from "./../system/device.js";
|
|
2
|
-
import { requestPointerLock, exitPointerLock } from "./../input/input.js";
|
|
3
1
|
import { TextureAtlas } from "./../video/texture/atlas.js";
|
|
4
2
|
import Renderer from "./../video/renderer.js";
|
|
5
3
|
import { Draggable, DropTarget } from "./../renderable/dragndrop.js";
|
|
@@ -45,35 +43,8 @@ export function warning(deprecated, replacement, version) {
|
|
|
45
43
|
}
|
|
46
44
|
};
|
|
47
45
|
|
|
48
|
-
/**
|
|
49
|
-
* @public
|
|
50
|
-
* @name turnOnPointerLock
|
|
51
|
-
* @returns {boolean} return true if the request was successfully submitted
|
|
52
|
-
* @memberof device#
|
|
53
|
-
* @deprecated since 10.3.0
|
|
54
|
-
* @see input.requestPointerLock
|
|
55
|
-
*/
|
|
56
|
-
device.turnOnPointerLock = function () {
|
|
57
|
-
warning("device.turnOnPointerLock()", "input.requestPointerLock()", "10.3.0");
|
|
58
|
-
return requestPointerLock();
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @public
|
|
63
|
-
* @name turnOffPointerLock
|
|
64
|
-
* @returns {boolean} return true if the request was successfully submitted
|
|
65
|
-
* @memberof device#
|
|
66
|
-
* @deprecated since 10.3.0
|
|
67
|
-
* @see input.exitPointerLock
|
|
68
|
-
*/
|
|
69
|
-
device.turnOffPointerLock = function () {
|
|
70
|
-
warning("device.turnOffPointerLock()", "input.exitPointerLock()", "10.3.0");
|
|
71
|
-
return exitPointerLock();
|
|
72
|
-
};
|
|
73
|
-
|
|
74
46
|
/**
|
|
75
47
|
* Alias of {@link TextureAtlas}
|
|
76
|
-
*
|
|
77
48
|
* @public
|
|
78
49
|
* @name Texture
|
|
79
50
|
* @class
|
package/src/level/level.js
CHANGED
|
@@ -2,7 +2,7 @@ import utils from "./../utils/utils.js";
|
|
|
2
2
|
import * as event from "./../system/event.js";
|
|
3
3
|
import state from "./../state/state.js";
|
|
4
4
|
import loader from "./../loader/loader.js";
|
|
5
|
-
import
|
|
5
|
+
import game from "./../game.js";
|
|
6
6
|
import TMXTileMap from "./tiled/TMXTileMap.js";
|
|
7
7
|
|
|
8
8
|
|
|
@@ -125,7 +125,7 @@ var level = {
|
|
|
125
125
|
* @param {string} levelId level id
|
|
126
126
|
* @param {object} [options] additional optional parameters
|
|
127
127
|
* @param {Container} [options.container=game.world] container in which to load the specified level
|
|
128
|
-
* @param {Function} [options.onLoaded=
|
|
128
|
+
* @param {Function} [options.onLoaded=game.onLevelLoaded] callback for when the level is fully loaded
|
|
129
129
|
* @param {boolean} [options.flatten=game.mergeGroup] if true, flatten all objects into the given container
|
|
130
130
|
* @param {boolean} [options.setViewportBounds=true] if true, set the viewport bounds to the map size
|
|
131
131
|
* @returns {boolean} true if the level was successfully loaded
|
|
@@ -4,7 +4,7 @@ import * as TMXUtils from "./TMXUtils.js";
|
|
|
4
4
|
import Tile from "./TMXTile.js";
|
|
5
5
|
import Renderable from "./../../renderable/renderable.js";
|
|
6
6
|
import CanvasRenderer from "./../../video/canvas/canvas_renderer";
|
|
7
|
-
import
|
|
7
|
+
import game from "./../../game.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Create required arrays for the given layer object
|
|
@@ -173,7 +173,7 @@ class TMXLayer extends Renderable {
|
|
|
173
173
|
|
|
174
174
|
// check for the correct rendering method
|
|
175
175
|
if (typeof (this.preRender) === "undefined") {
|
|
176
|
-
this.preRender = world.preRender;
|
|
176
|
+
this.preRender = game.world.preRender;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
// set a renderer
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pool from "./../../system/pooling.js";
|
|
2
2
|
import * as event from "./../../system/event.js";
|
|
3
|
-
import
|
|
3
|
+
import game from "./../../game.js";
|
|
4
4
|
import collision from "./../../physics/collision.js";
|
|
5
5
|
import Body from "./../../physics/body.js";
|
|
6
6
|
import TMXOrthogonalRenderer from "./renderer/TMXOrthogonalRenderer.js";
|
|
@@ -396,7 +396,7 @@ class TMXTileMap {
|
|
|
396
396
|
*/
|
|
397
397
|
function _setBounds(width, height) {
|
|
398
398
|
// adjust the viewport bounds if level is smaller
|
|
399
|
-
viewport.setBounds(
|
|
399
|
+
game.viewport.setBounds(
|
|
400
400
|
0, 0,
|
|
401
401
|
Math.max(levelBounds.width, width),
|
|
402
402
|
Math.max(levelBounds.height, height)
|
|
@@ -413,7 +413,7 @@ class TMXTileMap {
|
|
|
413
413
|
if (setViewportBounds === true) {
|
|
414
414
|
event.off(event.VIEWPORT_ONRESIZE, _setBounds);
|
|
415
415
|
// force viewport bounds update
|
|
416
|
-
_setBounds(viewport.width, viewport.height);
|
|
416
|
+
_setBounds(game.viewport.width, game.viewport.height);
|
|
417
417
|
// Replace the resize handler
|
|
418
418
|
event.on(event.VIEWPORT_ONRESIZE, _setBounds, this);
|
|
419
419
|
}
|
package/src/loader/loader.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as fileUtil from "./../utils/file.js";
|
|
2
2
|
import * as event from "./../system/event.js";
|
|
3
|
-
import
|
|
3
|
+
import { ua } from "./../system/platform.js";
|
|
4
4
|
import * as audio from "./../audio/audio.js";
|
|
5
5
|
import state from "./../state/state.js";
|
|
6
6
|
import level from "./../level/level.js";
|
|
7
7
|
import * as TMXUtils from "./../level/tiled/TMXUtils.js";
|
|
8
|
+
import { isDataUrl } from "./../utils/string.js";
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
// contains all the images loaded
|
|
@@ -30,7 +31,7 @@ var timerId = 0;
|
|
|
30
31
|
function checkLoadStatus(onload) {
|
|
31
32
|
if (loadCount === resourceCount) {
|
|
32
33
|
// wait 1/2s and execute callback (cheap workaround to ensure everything is loaded)
|
|
33
|
-
if (onload || loader.onload) {
|
|
34
|
+
if (typeof onload === "function" || loader.onload) {
|
|
34
35
|
// make sure we clear the timer
|
|
35
36
|
clearTimeout(timerId);
|
|
36
37
|
// trigger the onload callback
|
|
@@ -66,8 +67,12 @@ function checkLoadStatus(onload) {
|
|
|
66
67
|
function preloadImage(img, onload, onerror) {
|
|
67
68
|
// create new Image object and add to list
|
|
68
69
|
imgList[img.name] = new Image();
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
if (typeof onload === "function") {
|
|
71
|
+
imgList[img.name].onload = onload;
|
|
72
|
+
}
|
|
73
|
+
if (typeof onerror === "function") {
|
|
74
|
+
imgList[img.name].onerror = onerror;
|
|
75
|
+
}
|
|
71
76
|
if (typeof (loader.crossOrigin) === "string") {
|
|
72
77
|
imgList[img.name].crossOrigin = loader.crossOrigin;
|
|
73
78
|
}
|
|
@@ -83,17 +88,30 @@ function preloadImage(img, onload, onerror) {
|
|
|
83
88
|
* @ignore
|
|
84
89
|
*/
|
|
85
90
|
function preloadFontFace(data, onload, onerror) {
|
|
91
|
+
|
|
92
|
+
if (isDataUrl(data.src) === true) {
|
|
93
|
+
// make sure it in the `url(data:[<mediatype>][;base64],<data>)` format as expected by FontFace
|
|
94
|
+
if (!data.src.startsWith("url(")) {
|
|
95
|
+
data.src = "url(" + data.src + ")";
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
86
99
|
var font = new FontFace(data.name, data.src);
|
|
100
|
+
|
|
87
101
|
// loading promise
|
|
88
102
|
font.load().then(() => {
|
|
89
103
|
// apply the font after the font has finished downloading
|
|
90
104
|
document.fonts.add(font);
|
|
91
105
|
document.body.style.fontFamily = data.name;
|
|
92
|
-
|
|
93
|
-
|
|
106
|
+
if (typeof onload === "function") {
|
|
107
|
+
// onloaded callback
|
|
108
|
+
onload();
|
|
109
|
+
}
|
|
94
110
|
}, function () {
|
|
95
|
-
|
|
96
|
-
|
|
111
|
+
if (typeof onerror === "function") {
|
|
112
|
+
// rejected
|
|
113
|
+
onerror(data.name);
|
|
114
|
+
}
|
|
97
115
|
});
|
|
98
116
|
};
|
|
99
117
|
|
|
@@ -119,7 +137,9 @@ function preloadTMX(tmxData, onload, onerror) {
|
|
|
119
137
|
//if the data is in the tmxData object, don't get it via a XMLHTTPRequest
|
|
120
138
|
if (tmxData.data) {
|
|
121
139
|
addToTMXList(tmxData.data);
|
|
122
|
-
onload
|
|
140
|
+
if (typeof onload === "function") {
|
|
141
|
+
onload();
|
|
142
|
+
}
|
|
123
143
|
return;
|
|
124
144
|
}
|
|
125
145
|
|
|
@@ -153,7 +173,7 @@ function preloadTMX(tmxData, onload, onerror) {
|
|
|
153
173
|
case "tmx":
|
|
154
174
|
case "tsx":
|
|
155
175
|
// ie9 does not fully implement the responseXML
|
|
156
|
-
if (
|
|
176
|
+
if (ua.match(/msie/i) || !xmlhttp.responseXML) {
|
|
157
177
|
if (globalThis.DOMParser) {
|
|
158
178
|
// manually create the XML DOM
|
|
159
179
|
result = (new DOMParser()).parseFromString(xmlhttp.responseText, "text/xml");
|
|
@@ -190,9 +210,11 @@ function preloadTMX(tmxData, onload, onerror) {
|
|
|
190
210
|
addToTMXList(result);
|
|
191
211
|
|
|
192
212
|
// fire the callback
|
|
193
|
-
onload
|
|
213
|
+
if (typeof onload === "function") {
|
|
214
|
+
onload();
|
|
215
|
+
}
|
|
194
216
|
}
|
|
195
|
-
else {
|
|
217
|
+
else if (typeof onerror === "function") {
|
|
196
218
|
onerror(tmxData.name);
|
|
197
219
|
}
|
|
198
220
|
}
|
|
@@ -224,10 +246,12 @@ function preloadJSON(data, onload, onerror) {
|
|
|
224
246
|
if ((xmlhttp.status === 200) || ((xmlhttp.status === 0) && xmlhttp.responseText)) {
|
|
225
247
|
// get the Texture Packer Atlas content
|
|
226
248
|
jsonList[data.name] = JSON.parse(xmlhttp.responseText);
|
|
227
|
-
|
|
228
|
-
|
|
249
|
+
if (typeof onload === "function") {
|
|
250
|
+
// fire the callback
|
|
251
|
+
onload();
|
|
252
|
+
}
|
|
229
253
|
}
|
|
230
|
-
else {
|
|
254
|
+
else if (typeof onerror === "function") {
|
|
231
255
|
onerror(data.name);
|
|
232
256
|
}
|
|
233
257
|
}
|
|
@@ -257,8 +281,11 @@ function preloadBinary(data, onload, onerror) {
|
|
|
257
281
|
buffer[i] = String.fromCharCode(byteArray[i]);
|
|
258
282
|
}
|
|
259
283
|
binList[data.name] = buffer.join("");
|
|
260
|
-
|
|
261
|
-
|
|
284
|
+
if (typeof onload === "function") {
|
|
285
|
+
// callback
|
|
286
|
+
onload();
|
|
287
|
+
}
|
|
288
|
+
|
|
262
289
|
}
|
|
263
290
|
};
|
|
264
291
|
httpReq.send();
|
|
@@ -278,15 +305,19 @@ function preloadJavascript(data, onload, onerror) {
|
|
|
278
305
|
}
|
|
279
306
|
script.defer = true;
|
|
280
307
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
308
|
+
if (typeof onload === "function") {
|
|
309
|
+
script.onload = () => {
|
|
310
|
+
// callback
|
|
311
|
+
onload();
|
|
312
|
+
};
|
|
313
|
+
}
|
|
285
314
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
315
|
+
if (typeof onerror === "function") {
|
|
316
|
+
script.onerror = () => {
|
|
317
|
+
// callback
|
|
318
|
+
onerror(data.name);
|
|
319
|
+
};
|
|
320
|
+
}
|
|
290
321
|
|
|
291
322
|
document.getElementsByTagName("body")[0].appendChild(script);
|
|
292
323
|
};
|
|
@@ -453,6 +484,8 @@ var loader = {
|
|
|
453
484
|
* {name: "tileset-platformer", type: "image", src: "data/map/tileset.png"},
|
|
454
485
|
* // PNG packed texture
|
|
455
486
|
* {name: "texture", type:"image", src: "data/gfx/texture.png"}
|
|
487
|
+
* // PNG base64 encoded image
|
|
488
|
+
* {name: "texture", type:"image", src: "data:image/png;base64,iVBORw0KAAAQAAAAEACA..."}
|
|
456
489
|
* // TSX file
|
|
457
490
|
* {name: "meta_tiles", type: "tsx", src: "data/map/meta_tiles.tsx"},
|
|
458
491
|
* // TMX level (XML & JSON)
|
|
@@ -463,6 +496,8 @@ var loader = {
|
|
|
463
496
|
* // audio resources
|
|
464
497
|
* {name: "bgmusic", type: "audio", src: "data/audio/"},
|
|
465
498
|
* {name: "cling", type: "audio", src: "data/audio/"},
|
|
499
|
+
* // base64 encoded audio resources
|
|
500
|
+
* {name: "band", type: "audio", src: "data:audio/wav;base64,..."},
|
|
466
501
|
* // binary file
|
|
467
502
|
* {name: "ymTrack", type: "binary", src: "data/audio/main.ym"},
|
|
468
503
|
* // JSON file (used for texturePacker)
|
|
@@ -509,13 +544,14 @@ var loader = {
|
|
|
509
544
|
* @param {string} res.type "audio", binary", "image", "json", "tmx", "tsx"
|
|
510
545
|
* @param {string} res.src path and/or file name of the resource (for audio assets only the path is required)
|
|
511
546
|
* @param {boolean} [res.stream] Set to true to force HTML5 Audio, which allows not to wait for large file to be downloaded before playing.
|
|
512
|
-
* @param {Function} onload function to be called when the resource is loaded
|
|
513
|
-
* @param {Function} onerror function to be called in case of error
|
|
547
|
+
* @param {Function} [onload] function to be called when the resource is loaded
|
|
548
|
+
* @param {Function} [onerror] function to be called in case of error
|
|
514
549
|
* @returns {number} the amount of corresponding resource to be preloaded
|
|
515
550
|
* @example
|
|
516
551
|
* // load an image asset
|
|
517
552
|
* me.loader.load({name: "avatar", type:"image", src: "data/avatar.png"}, this.onload.bind(this), this.onerror.bind(this));
|
|
518
|
-
*
|
|
553
|
+
* // load a base64 image asset
|
|
554
|
+
* me.loader.load({name: "avatar", type:"image", src: "data:image/png;base64,iVBORw0KAAAQAAAAEACA..."};
|
|
519
555
|
* // start loading music
|
|
520
556
|
* me.loader.load({
|
|
521
557
|
* name : "bgmusic",
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import game from "./../game.js";
|
|
2
2
|
import { renderer } from "./../video/video.js";
|
|
3
3
|
import * as event from "./../system/event.js";
|
|
4
|
-
import Renderable from "./../renderable/renderable.js";
|
|
5
4
|
import Sprite from "./../renderable/sprite.js";
|
|
5
|
+
import Renderable from "./../renderable/renderable.js";
|
|
6
6
|
import Stage from "./../state/stage.js";
|
|
7
|
-
import
|
|
7
|
+
import loader from "./loader.js";
|
|
8
|
+
import logo_url from "./melonjs_logo.png";
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
// a basic progress bar object
|
|
@@ -40,7 +41,7 @@ class ProgressBar extends Renderable {
|
|
|
40
41
|
* draw function
|
|
41
42
|
* @ignore
|
|
42
43
|
*/
|
|
43
|
-
draw
|
|
44
|
+
draw(renderer, viewport) {
|
|
44
45
|
// draw the progress bar
|
|
45
46
|
renderer.setColor("black");
|
|
46
47
|
renderer.fillRect(this.pos.x, viewport.centerY, renderer.getWidth(), this.barHeight / 2);
|
|
@@ -61,23 +62,6 @@ class ProgressBar extends Renderable {
|
|
|
61
62
|
|
|
62
63
|
};
|
|
63
64
|
|
|
64
|
-
/**
|
|
65
|
-
* the melonJS Logo
|
|
66
|
-
* @ignore
|
|
67
|
-
*/
|
|
68
|
-
class IconLogo extends Sprite {
|
|
69
|
-
constructor(x, y) {
|
|
70
|
-
// TODO: create a sprite or texture from a Base64 encoded image
|
|
71
|
-
var image = new Image();
|
|
72
|
-
image.src = melonjs_logo;
|
|
73
|
-
super(x, y, {
|
|
74
|
-
image : image,
|
|
75
|
-
framewidth : 256,
|
|
76
|
-
frameheight : 256
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
65
|
/**
|
|
82
66
|
* a default loading screen
|
|
83
67
|
* @ignore
|
|
@@ -91,22 +75,37 @@ class DefaultLoadingScreen extends Stage {
|
|
|
91
75
|
var barHeight = 8;
|
|
92
76
|
|
|
93
77
|
// set a background color
|
|
94
|
-
world.backgroundColor.parseCSS("#202020");
|
|
78
|
+
game.world.backgroundColor.parseCSS("#202020");
|
|
95
79
|
|
|
96
80
|
// progress bar
|
|
97
|
-
world.addChild(new ProgressBar(
|
|
81
|
+
game.world.addChild(new ProgressBar(
|
|
98
82
|
0,
|
|
99
83
|
renderer.getHeight() / 2,
|
|
100
84
|
renderer.getWidth(),
|
|
101
85
|
barHeight
|
|
102
86
|
), 1);
|
|
103
87
|
|
|
104
|
-
// melonJS logo
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
88
|
+
// load the melonJS logo
|
|
89
|
+
loader.load({name: "melonjs_logo", type: "image", src: logo_url}, () => {
|
|
90
|
+
// melonJS logo
|
|
91
|
+
game.world.addChild(new Sprite(
|
|
92
|
+
renderer.getWidth() / 2,
|
|
93
|
+
renderer.getHeight() / 2, {
|
|
94
|
+
image : "melonjs_logo",
|
|
95
|
+
framewidth : 256,
|
|
96
|
+
frameheight : 256
|
|
97
|
+
}), 2
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
108
101
|
|
|
109
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Called by engine before deleting the object
|
|
104
|
+
* @ignore
|
|
105
|
+
*/
|
|
106
|
+
onDestroyEvent() {
|
|
107
|
+
// cancel the callback
|
|
108
|
+
loader.unload({name: "melonjs_logo", type:"image"});
|
|
110
109
|
}
|
|
111
110
|
};
|
|
112
111
|
|
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
|
|