melonjs 10.4.0 → 10.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "melonjs",
3
- "version": "10.4.0",
3
+ "version": "10.5.0",
4
4
  "description": "melonJS Game Engine",
5
5
  "homepage": "http://www.melonjs.org/",
6
6
  "keywords": [
@@ -53,6 +53,7 @@
53
53
  "CHANGELOG"
54
54
  ],
55
55
  "dependencies": {
56
+ "@teppeis/multimaps": "^2.0.0",
56
57
  "earcut": "2.2.3",
57
58
  "eventemitter3": "^4.0.7",
58
59
  "howler": "2.2.3"
@@ -62,25 +63,25 @@
62
63
  "@rollup/plugin-commonjs": "^21.0.2",
63
64
  "@rollup/plugin-node-resolve": "^13.1.3",
64
65
  "@rollup/plugin-replace": "^4.0.0",
66
+ "@types/offscreencanvas": "^2019.6.4",
65
67
  "cheerio": "^1.0.0-rc.10",
66
68
  "del-cli": "^4.0.1",
67
- "eslint": "^8.10.0",
68
- "eslint-plugin-jsdoc": "^37.9.7",
69
+ "eslint": "^8.11.0",
70
+ "eslint-plugin-jsdoc": "^38.0.4",
69
71
  "jasmine-core": "^4.0.1",
70
72
  "jsdoc": "^3.6.10",
71
73
  "karma": "^6.3.17",
72
- "karma-chrome-launcher": "^3.1.0",
74
+ "karma-chrome-launcher": "^3.1.1",
73
75
  "karma-coverage": "^2.2.0",
74
76
  "karma-html-detailed-reporter": "^2.1.0",
75
77
  "karma-jasmine": "^4.0.1",
76
78
  "karma-nyan-reporter": "0.2.5",
77
79
  "qs": "^6.10.3",
78
- "rollup": "^2.70.0",
80
+ "rollup": "^2.70.1",
79
81
  "rollup-plugin-bundle-size": "^1.0.3",
80
82
  "rollup-plugin-string": "^3.0.0",
81
- "terser": "^5.12.0",
82
- "typescript": "^4.6.2",
83
- "@types/offscreencanvas": "^2019.6.4"
83
+ "terser": "^5.12.1",
84
+ "typescript": "^4.6.2"
84
85
  },
85
86
  "scripts": {
86
87
  "build": "npm run lint && rollup -c --silent",
package/src/index.js CHANGED
@@ -53,6 +53,7 @@ import NineSliceSprite from "./renderable/nineslicesprite.js";
53
53
  import GUI_Object from "./renderable/GUI.js";
54
54
  import Collectable from "./renderable/collectable.js";
55
55
  import Trigger from "./renderable/trigger.js";
56
+ import { Draggable, DropTarget } from "./renderable/dragndrop.js";
56
57
  import TMXRenderer from "./level/tiled/renderer/TMXRenderer.js";
57
58
  import TMXOrthogonalRenderer from "./level/tiled/renderer/TMXOrthogonalRenderer.js";
58
59
  import TMXIsometricRenderer from "./level/tiled/renderer/TMXIsometricRenderer.js";
@@ -71,14 +72,8 @@ import World from "./physics/world.js";
71
72
  import { ParticleEmitterSettings, ParticleEmitter } from "./particles/emitter.js";
72
73
  import Particle from "./particles/particle.js";
73
74
  import Entity from "./entity/entity.js";
74
- import DraggableEntity from "./entity/draggable.js";
75
- import DroptargetEntity from "./entity/droptarget.js";
76
75
 
77
76
 
78
-
79
- // alias and wrapper for deprecated API
80
- import * as deprecated from "./lang/deprecated.js";
81
-
82
77
  /**
83
78
  * current melonJS version
84
79
  * @static
@@ -143,6 +138,8 @@ export {
143
138
  GUI_Object,
144
139
  Collectable,
145
140
  Trigger,
141
+ Draggable,
142
+ DropTarget,
146
143
  TMXRenderer,
147
144
  TMXOrthogonalRenderer,
148
145
  TMXIsometricRenderer,
@@ -161,15 +158,11 @@ export {
161
158
  ParticleEmitter,
162
159
  ParticleEmitterSettings,
163
160
  Particle,
164
- Entity,
165
- DraggableEntity,
166
- DroptargetEntity
161
+ Entity
167
162
  };
168
163
 
169
164
  // Backward compatibility for deprecated method or properties
170
- export {
171
- deprecated
172
- };
165
+ export * from "./lang/deprecated.js";
173
166
 
174
167
 
175
168
  /**
@@ -2,6 +2,7 @@ import device from "./../system/device.js";
2
2
  import { requestPointerLock, exitPointerLock } from "./../input/input.js";
3
3
  import { TextureAtlas } from "./../video/texture.js";
4
4
  import Renderer from "./../video/renderer.js";
5
+ import { Draggable, DropTarget } from "./../renderable/dragndrop.js";
5
6
 
6
7
  /**
7
8
  * placeholder for all deprecated classes and corresponding alias for backward compatibility
@@ -86,3 +87,42 @@ Object.defineProperty(Renderer.prototype, "Texture", {
86
87
  return TextureAtlas;
87
88
  }
88
89
  });
90
+
91
+
92
+ /**
93
+ * @classdesc
94
+ * Used to make a game entity draggable
95
+ * @augments Entity
96
+ * @deprecated since 10.5.0
97
+ * @see Draggable
98
+ */
99
+ export class DraggableEntity extends Draggable {
100
+ /**
101
+ * @param {number} x the x coordinates of the draggable object
102
+ * @param {number} y the y coordinates of the draggable object
103
+ * @param {object} settings Entity properties (see {@link Entity})
104
+ */
105
+ constructor(x, y, settings) {
106
+ warning("DraggableEntity", "Draggable", "10.5.0");
107
+ super(x, y, settings.width, settings.height);
108
+ }
109
+ }
110
+
111
+ /**
112
+ * @classdesc
113
+ * Used to make a game entity a droptarget
114
+ * @augments Entity
115
+ * @deprecated since 10.5.0
116
+ * @see DropTarget
117
+ */
118
+ export class DroptargetEntity extends DropTarget {
119
+ /**
120
+ * @param {number} x the x coordinates of the draggable object
121
+ * @param {number} y the y coordinates of the draggable object
122
+ * @param {object} settings Entity properties (see {@link Entity})
123
+ */
124
+ constructor(x, y, settings) {
125
+ warning("DroptargetEntity", "DropTarget", "10.5.0");
126
+ super(x, y, settings.width, settings.height);
127
+ }
128
+ }
@@ -542,6 +542,8 @@ class TMXTileMap {
542
542
  if (isCollisionGroup && !settings.name && obj.body) {
543
543
  // configure the body accordingly
544
544
  obj.body.collisionType = collision.types.WORLD_SHAPE;
545
+ // mark collision shapes as static
546
+ obj.body.isStatic = true;
545
547
  }
546
548
 
547
549
  //apply group opacity value to the child objects if group are merged
@@ -154,7 +154,8 @@ class Body {
154
154
 
155
155
 
156
156
  /**
157
- * either this body is a static body or not
157
+ * Either this body is a static body or not.
158
+ * A static body is completely fixed and can never change position or angle.
158
159
  * @readonly
159
160
  * @public
160
161
  * @type {boolean}
@@ -27,7 +27,8 @@ var dummyObj = {
27
27
  function shouldCollide(a, b) {
28
28
  return (
29
29
  a.isKinematic !== true && b.isKinematic !== true &&
30
- a.body && b.body &&
30
+ typeof a.body === "object" && typeof b.body === "object" &&
31
+ !(a.body.isStatic === true && b.body.isStatic === true) &&
31
32
  (a.body.collisionMask & b.body.collisionType) !== 0 &&
32
33
  (a.body.collisionType & b.body.collisionMask) !== 0
33
34
  );
@@ -141,10 +142,10 @@ export function collisionCheck(objA, response = globalResponse) {
141
142
  response.indexShapeB = indexB;
142
143
 
143
144
  // execute the onCollision callback
144
- if (objA.onCollision && objA.onCollision(response, objB) !== false) {
145
+ if (objA.onCollision && objA.onCollision(response, objB) !== false && objA.body.isStatic === false) {
145
146
  objA.body.respondToCollision.call(objA.body, response);
146
147
  }
147
- if (objB.onCollision && objB.onCollision(response, objA) !== false) {
148
+ if (objB.onCollision && objB.onCollision(response, objA) !== false && objB.body.isStatic === false) {
148
149
  objB.body.respondToCollision.call(objB.body, response);
149
150
  }
150
151
  }
@@ -0,0 +1,224 @@
1
+ import Vector2d from "./../math/vector2.js";
2
+ import * as input from "./../input/input.js";
3
+ import * as event from "./../system/event.js";
4
+ import Renderable from "./../renderable/renderable.js";
5
+
6
+ /**
7
+ * @classdesc
8
+ * A Draggable base object
9
+ * @see DropTarget
10
+ * @augments Renderable
11
+ */
12
+ export class Draggable extends Renderable {
13
+ /**
14
+ * @param {number} x the x coordinates of the draggable object
15
+ * @param {number} y the y coordinates of the draggable object
16
+ * @param {number} width draggable object width
17
+ * @param {number} height draggable object height
18
+ */
19
+ constructor(x, y, width, height) {
20
+ super(x, y, width, height);
21
+ this.isKinematic = false;
22
+ this.dragging = false;
23
+ this.dragId = null;
24
+ this.grabOffset = new Vector2d(0, 0);
25
+ this.initEvents();
26
+ }
27
+
28
+ /**
29
+ * Initializes the events the modules needs to listen to
30
+ * It translates the pointer events to me.events
31
+ * in order to make them pass through the system and to make
32
+ * this module testable. Then we subscribe this module to the
33
+ * transformed events.
34
+ * @name initEvents
35
+ * @memberof Draggable
36
+ * @function
37
+ * @private
38
+ */
39
+ initEvents() {
40
+ input.registerPointerEvent("pointerdown", this, (e) => { event.emit(event.DRAGSTART, e, this); });
41
+ input.registerPointerEvent("pointerup", this, (e) => { event.emit(event.DRAGEND, e, this); });
42
+ input.registerPointerEvent("pointercancel", this, (e) => { event.emit(event.DRAGEND, e, this); });
43
+ event.on(event.POINTERMOVE, this.dragMove.bind(this));
44
+ event.on(event.DRAGSTART, (e, draggable) => {
45
+ if (draggable === this) {
46
+ this.dragStart(e);
47
+ }
48
+ });
49
+ event.on(event.DRAGEND, (e, draggable) => {
50
+ if (draggable === this) {
51
+ this.dragEnd(e);
52
+ }
53
+ });
54
+ }
55
+
56
+ /**
57
+ * Gets called when the user starts dragging the entity
58
+ * @name dragStart
59
+ * @memberof Draggable
60
+ * @function
61
+ * @param {object} e the pointer event
62
+ * @returns {boolean} false if the object is being dragged
63
+ */
64
+ dragStart(e) {
65
+ if (this.dragging === false) {
66
+ this.dragging = true;
67
+ this.grabOffset.set(e.gameX, e.gameY);
68
+ this.grabOffset.sub(this.pos);
69
+ return false;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Gets called when the user drags this entity around
75
+ * @name dragMove
76
+ * @memberof Draggable
77
+ * @function
78
+ * @param {object} e the pointer event
79
+ */
80
+ dragMove(e) {
81
+ if (this.dragging === true) {
82
+ this.pos.set(e.gameX, e.gameY, this.pos.z); //TODO : z ?
83
+ this.pos.sub(this.grabOffset);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Gets called when the user stops dragging the entity
89
+ * @name dragEnd
90
+ * @memberof Draggable
91
+ * @function
92
+ * @returns {boolean} false if the object stopped being dragged
93
+ */
94
+ dragEnd() {
95
+ if (this.dragging === true) {
96
+ this.dragging = false;
97
+ return false;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Destructor
103
+ * @name destroy
104
+ * @memberof Draggable
105
+ * @function
106
+ * @private
107
+ */
108
+ destroy() {
109
+ event.off(event.POINTERMOVE, this.dragMove);
110
+ event.off(event.DRAGSTART, this.dragStart);
111
+ event.off(event.DRAGEND, this.dragEnd);
112
+ input.releasePointerEvent("pointerdown", this);
113
+ input.releasePointerEvent("pointerup", this);
114
+ input.releasePointerEvent("pointercancel", this);
115
+ super.destroy();
116
+ }
117
+ };
118
+
119
+ /**
120
+ * @classdesc
121
+ * a base drop target object
122
+ * @see Draggable
123
+ * @augments Renderable
124
+ */
125
+ export class DropTarget extends Renderable {
126
+ /**
127
+ * @param {number} x the x coordinates of the drop target
128
+ * @param {number} y the y coordinates of the drop target
129
+ * @param {number} width drop target width
130
+ * @param {number} height drop target height
131
+ */
132
+ constructor(x, y, width, height) {
133
+ super(x, y, width, height);
134
+
135
+ this.isKinematic = false;
136
+
137
+ /**
138
+ * constant for the overlaps method
139
+ * @public
140
+ * @constant
141
+ * @type {string}
142
+ * @name CHECKMETHOD_OVERLAP
143
+ * @memberof DropTarget
144
+ */
145
+ this.CHECKMETHOD_OVERLAP = "overlaps";
146
+
147
+ /**
148
+ * constant for the contains method
149
+ * @public
150
+ * @constant
151
+ * @type {string}
152
+ * @name CHECKMETHOD_CONTAINS
153
+ * @memberof DropTarget
154
+ */
155
+ this.CHECKMETHOD_CONTAINS = "contains";
156
+
157
+ /**
158
+ * the checkmethod we want to use
159
+ * @public
160
+ * @constant
161
+ * @type {string}
162
+ * @name checkMethod
163
+ * @default "overlaps"
164
+ * @memberof DropTarget
165
+ */
166
+ this.checkMethod = this.CHECKMETHOD_OVERLAP;
167
+
168
+ event.on(event.DRAGEND, this.checkOnMe, this);
169
+
170
+ }
171
+
172
+ /**
173
+ * Sets the collision method which is going to be used to check a valid drop
174
+ * @name setCheckMethod
175
+ * @memberof DropTarget
176
+ * @function
177
+ * @param {string} checkMethod the checkmethod (defaults to CHECKMETHOD_OVERLAP)
178
+ */
179
+ setCheckMethod(checkMethod) {
180
+ // We can improve this check,
181
+ // because now you can use every method in theory
182
+ if (typeof(this.getBounds()[this.checkMethod]) === "function") {
183
+ this.checkMethod = checkMethod;
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Checks if a dropped entity is dropped on the current entity
189
+ * @name checkOnMe
190
+ * @memberof DropTarget
191
+ * @function
192
+ * @param {object} e the triggering event
193
+ * @param {Draggable} draggable the draggable object that is dropped
194
+ */
195
+ checkOnMe(e, draggable) {
196
+ if (draggable && this.getBounds()[this.checkMethod](draggable.getBounds())) {
197
+ // call the drop method on the current entity
198
+ this.drop(draggable);
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Gets called when a draggable entity is dropped on the current entity
204
+ * @name drop
205
+ * @memberof DropTarget
206
+ * @function
207
+ * @param {Draggable} draggable the draggable object that is dropped
208
+ */
209
+ drop() {
210
+
211
+ }
212
+
213
+ /**
214
+ * Destructor
215
+ * @name destroy
216
+ * @memberof DropTarget
217
+ * @function
218
+ * @private
219
+ */
220
+ destroy() {
221
+ event.off(event.DRAGEND, this.checkOnMe);
222
+ super.destroy();
223
+ }
224
+ };
@@ -2,6 +2,7 @@ import { renderer } from "./video.js";
2
2
  import * as fileUtil from "./../utils/file.js";
3
3
  import { TextureAtlas, createAtlas } from "./texture.js";
4
4
  import { isPowerOfTwo} from "./../math/math.js";
5
+ import {ArrayMultimap} from "@teppeis/multimaps";
5
6
 
6
7
 
7
8
  /**
@@ -14,7 +15,8 @@ class TextureCache {
14
15
  * @ignore
15
16
  */
16
17
  constructor(max_size) {
17
- this.cache = new Map();
18
+ // cache uses an array to allow for duplicated key
19
+ this.cache = new ArrayMultimap();
18
20
  this.tinted = new Map();
19
21
  this.units = new Map();
20
22
  this.max_size = max_size || Infinity;
@@ -48,13 +50,29 @@ class TextureCache {
48
50
  * @ignore
49
51
  */
50
52
  get(image, atlas) {
51
- if (!this.cache.has(image)) {
53
+ var entry;
54
+
55
+ if (typeof atlas === "undefined") {
56
+ entry = this.cache.get(image)[0];
57
+ } else {
58
+ // manage cases where a specific atlas is specified
59
+ this.cache.forEach((value, key) => {
60
+ var _atlas = value.getAtlas();
61
+ if (key === image && _atlas[0].width === atlas.framewidth && _atlas[0].height === atlas.frameheight) {
62
+ entry = value;
63
+ }
64
+ });
65
+ }
66
+
67
+ if (typeof entry === "undefined") {
52
68
  if (!atlas) {
53
69
  atlas = createAtlas(image.width, image.height, image.src ? fileUtil.getBasename(image.src) : undefined);
54
70
  }
55
- this.set(image, new TextureAtlas(atlas, image, false));
71
+ entry = new TextureAtlas(atlas, image, false);
72
+ this.set(image, entry);
56
73
  }
57
- return this.cache.get(image);
74
+
75
+ return entry;
58
76
  }
59
77
 
60
78
  /**
@@ -99,7 +117,7 @@ class TextureCache {
99
117
  "(" + width + "x" + height + ")"
100
118
  );
101
119
  }
102
- this.cache.set(image, texture);
120
+ return this.cache.put(image, texture);
103
121
  }
104
122
 
105
123
  /**
@@ -1,129 +0,0 @@
1
- import Vector2d from "./../math/vector2.js";
2
- import * as input from "./../input/input.js";
3
- import * as event from "./../system/event.js";
4
- import Entity from "./entity.js";
5
-
6
- /**
7
- * @classdesc
8
- * Used to make a game entity draggable
9
- * @augments Entity
10
- */
11
- class DraggableEntity extends Entity {
12
- /**
13
- * @param {number} x the x coordinates of the entity object
14
- * @param {number} y the y coordinates of the entity object
15
- * @param {object} settings Entity properties (see {@link Entity})
16
- */
17
- constructor(x, y, settings) {
18
- super(x, y, settings);
19
- this.dragging = false;
20
- this.dragId = null;
21
- this.grabOffset = new Vector2d(0, 0);
22
- this.onPointerEvent = input.registerPointerEvent;
23
- this.removePointerEvent = input.releasePointerEvent;
24
- this.initEvents();
25
- }
26
-
27
- /**
28
- * Initializes the events the modules needs to listen to
29
- * It translates the pointer events to me.events
30
- * in order to make them pass through the system and to make
31
- * this module testable. Then we subscribe this module to the
32
- * transformed events.
33
- * @name initEvents
34
- * @memberof DraggableEntity
35
- * @function
36
- */
37
- initEvents() {
38
- /**
39
- * @ignore
40
- */
41
- this.mouseDown = function (e) {
42
- this.translatePointerEvent(e, event.DRAGSTART);
43
- };
44
- /**
45
- * @ignore
46
- */
47
- this.mouseUp = function (e) {
48
- this.translatePointerEvent(e, event.DRAGEND);
49
- };
50
- this.onPointerEvent("pointerdown", this, this.mouseDown.bind(this));
51
- this.onPointerEvent("pointerup", this, this.mouseUp.bind(this));
52
- this.onPointerEvent("pointercancel", this, this.mouseUp.bind(this));
53
- event.on(event.POINTERMOVE, this.dragMove, this);
54
- event.on(event.DRAGSTART, this.dragStart, this);
55
- event.on(event.DRAGEND, this.dragEnd, this);
56
- }
57
-
58
- /**
59
- * Translates a pointer event to a me.event
60
- * @name translatePointerEvent
61
- * @memberof DraggableEntity
62
- * @function
63
- * @param {object} e the pointer event you want to translate
64
- * @param {string} translation the me.event you want to translate the event to
65
- */
66
- translatePointerEvent(e, translation) {
67
- event.emit(translation, e);
68
- }
69
-
70
- /**
71
- * Gets called when the user starts dragging the entity
72
- * @name dragStart
73
- * @memberof DraggableEntity
74
- * @function
75
- * @param {object} e the pointer event
76
- * @returns {boolean} false if the object is being dragged
77
- */
78
- dragStart(e) {
79
- if (this.dragging === false) {
80
- this.dragging = true;
81
- this.grabOffset.set(e.gameX, e.gameY);
82
- this.grabOffset.sub(this.pos);
83
- return false;
84
- }
85
- }
86
-
87
- /**
88
- * Gets called when the user drags this entity around
89
- * @name dragMove
90
- * @memberof DraggableEntity
91
- * @function
92
- * @param {object} e the pointer event
93
- */
94
- dragMove(e) {
95
- if (this.dragging === true) {
96
- this.pos.set(e.gameX, e.gameY, this.pos.z); //TODO : z ?
97
- this.pos.sub(this.grabOffset);
98
- }
99
- }
100
-
101
- /**
102
- * Gets called when the user stops dragging the entity
103
- * @name dragEnd
104
- * @memberof DraggableEntity
105
- * @function
106
- * @returns {boolean} false if the object stopped being dragged
107
- */
108
- dragEnd() {
109
- if (this.dragging === true) {
110
- this.dragging = false;
111
- return false;
112
- }
113
- }
114
-
115
- /**
116
- * Destructor
117
- * @name destroy
118
- * @memberof DraggableEntity
119
- * @function
120
- */
121
- destroy() {
122
- event.off(event.POINTERMOVE, this.dragMove);
123
- event.off(event.DRAGSTART, this.dragStart);
124
- event.off(event.DRAGEND, this.dragEnd);
125
- this.removePointerEvent("pointerdown", this);
126
- this.removePointerEvent("pointerup", this);
127
- }
128
- };
129
- export default DraggableEntity;