melonjs 10.0.2 → 10.2.1

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * melonJS Game Engine - v10.0.2
2
+ * melonJS Game Engine - v10.2.1
3
3
  * http://www.melonjs.org
4
4
  * melonjs is licensed under the MIT License.
5
5
  * http://www.opensource.org/licenses/mit-license
@@ -1500,7 +1500,7 @@ class Color {
1500
1500
  }
1501
1501
 
1502
1502
  /**
1503
- * Color Red Component
1503
+ * Color Red Component [0 .. 255]
1504
1504
  * @type Number
1505
1505
  * @name r
1506
1506
  * @readonly
@@ -1522,7 +1522,7 @@ class Color {
1522
1522
 
1523
1523
 
1524
1524
  /**
1525
- * Color Green Component
1525
+ * Color Green Component [0 .. 255]
1526
1526
  * @type Number
1527
1527
  * @name g
1528
1528
  * @readonly
@@ -1544,7 +1544,7 @@ class Color {
1544
1544
 
1545
1545
 
1546
1546
  /**
1547
- * Color Blue Component
1547
+ * Color Blue Component [0 .. 255]
1548
1548
  * @type Number
1549
1549
  * @name b
1550
1550
  * @readonly
@@ -1564,7 +1564,7 @@ class Color {
1564
1564
  }
1565
1565
 
1566
1566
  /**
1567
- * Color Alpha Component
1567
+ * Color Alpha Component [0.0 .. 1.0]
1568
1568
  * @type Number
1569
1569
  * @name alpha
1570
1570
  * @readonly
@@ -1848,6 +1848,23 @@ class Color {
1848
1848
  );
1849
1849
  }
1850
1850
 
1851
+ /**
1852
+ * Pack this color into a Uint32 ARGB representation
1853
+ * @name toUint32
1854
+ * @memberOf me.Color
1855
+ * @function
1856
+ * @param {Number} [alpha=1.0] alpha value [0.0 .. 1.0]
1857
+ * @return {Uint32}
1858
+ */
1859
+ toUint32(alpha = this.alpha) {
1860
+ var ur = this.r & 0xff;
1861
+ var ug = this.g & 0xff;
1862
+ var ub = this.b & 0xff;
1863
+ var ua = (alpha * 255) & 0xff;
1864
+
1865
+ return (ua << 24) + (ur << 16) + (ug << 8) + ub;
1866
+ }
1867
+
1851
1868
  /**
1852
1869
  * return an array representation of this object
1853
1870
  * @name toArray
@@ -1859,6 +1876,7 @@ class Color {
1859
1876
  return this.glArray;
1860
1877
  }
1861
1878
 
1879
+
1862
1880
  /**
1863
1881
  * Get the color in "#RRGGBB" format
1864
1882
  * @name toHex
@@ -10807,20 +10825,481 @@ function unbindKey(keycode) {
10807
10825
  }
10808
10826
 
10809
10827
  /**
10810
- * cache value for the offset of the canvas position within the page
10828
+ * @classdesc
10829
+ * a bound object contains methods for creating and manipulating axis-aligned bounding boxes (AABB).
10830
+ * @class Bounds
10831
+ * @memberOf me
10832
+ * @constructor
10833
+ * @memberOf me
10834
+ * @param {me.Vector2d[]} [vertices] an array of me.Vector2d points
10835
+ * @return {me.Bounds} A new bounds object
10836
+ */
10837
+
10838
+ class Bounds$1 {
10839
+
10840
+ constructor(vertices) {
10841
+ this.onResetEvent(vertices);
10842
+ }
10843
+
10844
+ onResetEvent(vertices) {
10845
+ if (typeof this.min === "undefined") {
10846
+ this.min = { x: Infinity, y: Infinity };
10847
+ this.max = { x: -Infinity, y: -Infinity };
10848
+ } else {
10849
+ this.clear();
10850
+ }
10851
+ if (typeof vertices !== "undefined") {
10852
+ this.update(vertices);
10853
+ }
10854
+
10855
+ // @ignore
10856
+ this._center = new Vector2d();
10857
+ }
10858
+
10859
+ /**
10860
+ * reset the bound
10861
+ * @name clear
10862
+ * @memberOf me.Bounds
10863
+ * @function
10864
+ */
10865
+ clear() {
10866
+ this.setMinMax(Infinity, Infinity, -Infinity, -Infinity);
10867
+
10868
+ }
10869
+
10870
+ /**
10871
+ * sets the bounds to the given min and max value
10872
+ * @name setMinMax
10873
+ * @memberOf me.Bounds
10874
+ * @function
10875
+ * @param {Number} minX
10876
+ * @param {Number} minY
10877
+ * @param {Number} maxX
10878
+ * @param {Number} maxY
10879
+ */
10880
+ setMinMax(minX, minY, maxX, maxY) {
10881
+ this.min.x = minX;
10882
+ this.min.y = minY;
10883
+
10884
+ this.max.x = maxX;
10885
+ this.max.y = maxY;
10886
+ }
10887
+
10888
+ /**
10889
+ * x position of the bound
10890
+ * @public
10891
+ * @type {Number}
10892
+ * @name x
10893
+ * @memberOf me.Bounds
10894
+ */
10895
+ get x() {
10896
+ return this.min.x;
10897
+ }
10898
+
10899
+ set x(value) {
10900
+ var deltaX = this.max.x - this.min.x;
10901
+ this.min.x = value;
10902
+ this.max.x = value + deltaX;
10903
+ }
10904
+
10905
+ /**
10906
+ * y position of the bounds
10907
+ * @public
10908
+ * @type {Number}
10909
+ * @name y
10910
+ * @memberOf me.Bounds
10911
+ */
10912
+ get y() {
10913
+ return this.min.y;
10914
+ }
10915
+
10916
+ set y(value) {
10917
+ var deltaY = this.max.y - this.min.y;
10918
+
10919
+ this.min.y = value;
10920
+ this.max.y = value + deltaY;
10921
+ }
10922
+
10923
+ /**
10924
+ * width of the bounds
10925
+ * @public
10926
+ * @type {Number}
10927
+ * @name width
10928
+ * @memberOf me.Bounds
10929
+ */
10930
+ get width() {
10931
+ return this.max.x - this.min.x;
10932
+ }
10933
+
10934
+ set width(value) {
10935
+ this.max.x = this.min.x + value;
10936
+ }
10937
+
10938
+ /**
10939
+ * width of the bounds
10940
+ * @public
10941
+ * @type {Number}
10942
+ * @name width
10943
+ * @memberOf me.Bounds
10944
+ */
10945
+ get height() {
10946
+ return this.max.y - this.min.y;
10947
+ }
10948
+
10949
+ set height(value) {
10950
+ this.max.y = this.min.y + value;
10951
+ }
10952
+
10953
+ /**
10954
+ * left coordinate of the bound
10955
+ * @public
10956
+ * @type {Number}
10957
+ * @name left
10958
+ * @memberOf me.Bounds
10959
+ */
10960
+ get left() {
10961
+ return this.min.x;
10962
+ }
10963
+
10964
+ /**
10965
+ * right coordinate of the bound
10966
+ * @public
10967
+ * @type {Number}
10968
+ * @name right
10969
+ * @memberOf me.Bounds
10970
+ */
10971
+ get right() {
10972
+ return this.max.x;
10973
+ }
10974
+
10975
+ /**
10976
+ * top coordinate of the bound
10977
+ * @public
10978
+ * @type {Number}
10979
+ * @name top
10980
+ * @memberOf me.Bounds
10981
+ */
10982
+ get top() {
10983
+ return this.min.y;
10984
+ }
10985
+
10986
+ /**
10987
+ * bottom coordinate of the bound
10988
+ * @public
10989
+ * @type {Number}
10990
+ * @name bottom
10991
+ * @memberOf me.Bounds
10992
+ */
10993
+ get bottom() {
10994
+ return this.max.y;
10995
+ }
10996
+
10997
+ /**
10998
+ * center position of the bound on the x axis
10999
+ * @public
11000
+ * @type {Number}
11001
+ * @name centerX
11002
+ * @memberOf me.Bounds
11003
+ */
11004
+ get centerX() {
11005
+ return this.min.x + (this.width / 2);
11006
+ }
11007
+
11008
+ /**
11009
+ * center position of the bound on the y axis
11010
+ * @public
11011
+ * @type {Number}
11012
+ * @name centerY
11013
+ * @memberOf me.Bounds
11014
+ */
11015
+ get centerY() {
11016
+ return this.min.y + (this.height / 2);
11017
+ }
11018
+
11019
+ /**
11020
+ * return the center position of the bound
11021
+ * @public
11022
+ * @type {me.Vector2d}
11023
+ * @name center
11024
+ * @memberOf me.Bounds
11025
+ */
11026
+ get center() {
11027
+ return this._center.set(this.centerX, this.centerY);
11028
+ }
11029
+
11030
+ /**
11031
+ * Updates bounds using the given vertices
11032
+ * @name update
11033
+ * @memberOf me.Bounds
11034
+ * @function
11035
+ * @param {me.Vector2d[]} vertices an array of me.Vector2d points
11036
+ */
11037
+ update(vertices) {
11038
+ this.add(vertices, true);
11039
+ }
11040
+
11041
+ /**
11042
+ * add the given vertices to the bounds definition.
11043
+ * @name add
11044
+ * @memberOf me.Bounds
11045
+ * @function
11046
+ * @param {me.Vector2d[]} vertices an array of me.Vector2d points
11047
+ * @param {boolean} [clear=false] either to reset the bounds before adding the new vertices
11048
+ */
11049
+ add(vertices, clear = false) {
11050
+ if (clear === true) {
11051
+ this.clear();
11052
+ }
11053
+ for (var i = 0; i < vertices.length; i++) {
11054
+ var vertex = vertices[i];
11055
+ if (vertex.x > this.max.x) this.max.x = vertex.x;
11056
+ if (vertex.x < this.min.x) this.min.x = vertex.x;
11057
+ if (vertex.y > this.max.y) this.max.y = vertex.y;
11058
+ if (vertex.y < this.min.y) this.min.y = vertex.y;
11059
+ }
11060
+ }
11061
+
11062
+ /**
11063
+ * add the given bounds to the bounds definition.
11064
+ * @name addBounds
11065
+ * @memberOf me.Bounds
11066
+ * @function
11067
+ * @param {me.Bounds} bounds
11068
+ * @param {boolean} [clear=false] either to reset the bounds before adding the new vertices
11069
+ */
11070
+ addBounds(bounds, clear = false) {
11071
+ if (clear === true) {
11072
+ this.clear();
11073
+ }
11074
+
11075
+ if (bounds.max.x > this.max.x) this.max.x = bounds.max.x;
11076
+ if (bounds.min.x < this.min.x) this.min.x = bounds.min.x;
11077
+ if (bounds.max.y > this.max.y) this.max.y = bounds.max.y;
11078
+ if (bounds.min.y < this.min.y) this.min.y = bounds.min.y;
11079
+ }
11080
+
11081
+ /**
11082
+ * add the given point to the bounds definition.
11083
+ * @name addPoint
11084
+ * @memberOf me.Bounds
11085
+ * @function
11086
+ * @param {me.Vector2d} vector
11087
+ * @param {me.Matrix2d} [matrix] an optional transform to apply to the given point
11088
+ */
11089
+ addPoint(v, m) {
11090
+ if (typeof m !== "undefined") {
11091
+ v = m.apply(v);
11092
+ }
11093
+ this.min.x = Math.min(this.min.x, v.x);
11094
+ this.max.x = Math.max(this.max.x, v.x);
11095
+ this.min.y = Math.min(this.min.y, v.y);
11096
+ this.max.y = Math.max(this.max.y, v.y);
11097
+ }
11098
+
11099
+ /**
11100
+ * add the given quad coordinates to this bound definition, multiplied by the given matrix
11101
+ * @name addFrame
11102
+ * @memberOf me.Bounds
11103
+ * @function
11104
+ * @param {Number} x0 - left X coordinates of the quad
11105
+ * @param {Number} y0 - top Y coordinates of the quad
11106
+ * @param {Number} x1 - right X coordinates of the quad
11107
+ * @param {Number} y1 - bottom y coordinates of the quad
11108
+ * @param {me.Matrix2d} [matrix] an optional transform to apply to the given frame coordinates
11109
+ */
11110
+ addFrame(x0, y0, x1, y1, m) {
11111
+ var v = me.pool.pull("Vector2d");
11112
+
11113
+ // transform all points and add to the bound definition
11114
+ this.addPoint(v.set(x0, y0), m);
11115
+ this.addPoint(v.set(x1, y0), m);
11116
+ this.addPoint(v.set(x0, y1), m);
11117
+ this.addPoint(v.set(x1, y1), m);
11118
+
11119
+ me.pool.push(v);
11120
+ }
11121
+
11122
+ /**
11123
+ * Returns true if the bounds contains the given point.
11124
+ * @name contains
11125
+ * @memberOf me.Bounds
11126
+ * @function
11127
+ * @param {me.Vector2d} point
11128
+ * @return {boolean} True if the bounds contain the point, otherwise false
11129
+ */
11130
+ /**
11131
+ * Returns true if the bounds contains the given point.
11132
+ * @name contains
11133
+ * @memberOf me.Bounds
11134
+ * @function
11135
+ * @param {Number} x
11136
+ * @param {Number} y
11137
+ * @return {boolean} True if the bounds contain the point, otherwise false
11138
+ */
11139
+ contains() {
11140
+ var arg0 = arguments[0];
11141
+ var _x1, _x2, _y1, _y2;
11142
+ if (arguments.length === 2) {
11143
+ // x, y
11144
+ _x1 = _x2 = arg0;
11145
+ _y1 = _y2 = arguments[1];
11146
+ } else {
11147
+ if (arg0 instanceof Bounds$1) {
11148
+ // bounds
11149
+ _x1 = arg0.min.x;
11150
+ _x2 = arg0.max.x;
11151
+ _y1 = arg0.min.y;
11152
+ _y2 = arg0.max.y;
11153
+ } else {
11154
+ // vector
11155
+ _x1 = _x2 = arg0.x;
11156
+ _y1 = _y2 = arg0.y;
11157
+ }
11158
+ }
11159
+
11160
+ return _x1 >= this.min.x && _x2 <= this.max.x
11161
+ && _y1 >= this.min.y && _y2 <= this.max.y;
11162
+ }
11163
+
11164
+ /**
11165
+ * Returns true if the two bounds intersect.
11166
+ * @name overlaps
11167
+ * @memberOf me.Bounds
11168
+ * @function
11169
+ * @param {me.Bounds|me.Rect} bounds
11170
+ * @return {boolean} True if the bounds overlap, otherwise false
11171
+ */
11172
+ overlaps(bounds) {
11173
+ return !(this.right < bounds.left || this.left > bounds.right ||
11174
+ this.bottom < bounds.top || this.top > bounds.bottom);
11175
+ }
11176
+
11177
+ /**
11178
+ * determines whether all coordinates of this bounds are finite numbers.
11179
+ * @name isFinite
11180
+ * @memberOf me.Bounds
11181
+ * @function
11182
+ * @return {boolean} false if all coordinates are positive or negative Infinity or NaN; otherwise, true.
11183
+ */
11184
+ isFinite() {
11185
+ return (isFinite(this.min.x) && isFinite(this.max.x) && isFinite(this.min.y) && isFinite(this.max.y));
11186
+ }
11187
+
11188
+ /**
11189
+ * Translates the bounds by the given vector.
11190
+ * @name translate
11191
+ * @memberOf me.Bounds
11192
+ * @function
11193
+ * @param {me.Vector2d} vector
11194
+ */
11195
+ /**
11196
+ * Translates the bounds by x on the x axis, and y on the y axis
11197
+ * @name translate
11198
+ * @memberOf me.Bounds
11199
+ * @function
11200
+ * @param {Number} x
11201
+ * @param {Number} y
11202
+ */
11203
+ translate() {
11204
+ var _x, _y;
11205
+ if (arguments.length === 2) {
11206
+ // x, y
11207
+ _x = arguments[0];
11208
+ _y = arguments[1];
11209
+ } else {
11210
+ // vector
11211
+ _x = arguments[0].x;
11212
+ _y = arguments[0].y;
11213
+ }
11214
+ this.min.x += _x;
11215
+ this.max.x += _x;
11216
+ this.min.y += _y;
11217
+ this.max.y += _y;
11218
+ }
11219
+
11220
+ /**
11221
+ * Shifts the bounds to the given position vector.
11222
+ * @name shift
11223
+ * @memberOf me.Bounds
11224
+ * @function
11225
+ * @param {me.Vector2d} position
11226
+ */
11227
+ /**
11228
+ * Shifts the bounds to the given x, y position.
11229
+ * @name shift
11230
+ * @memberOf me.Bounds
11231
+ * @function
11232
+ * @param {Number} x
11233
+ * @param {Number} y
11234
+ */
11235
+ shift() {
11236
+ var _x, _y;
11237
+
11238
+ if (arguments.length === 2) {
11239
+ // x, y
11240
+ _x = arguments[0];
11241
+ _y = arguments[1];
11242
+ } else {
11243
+ // vector
11244
+ _x = arguments[0].x;
11245
+ _y = arguments[0].y;
11246
+ }
11247
+
11248
+ var deltaX = this.max.x - this.min.x,
11249
+ deltaY = this.max.y - this.min.y;
11250
+
11251
+ this.min.x = _x;
11252
+ this.max.x = _x + deltaX;
11253
+ this.min.y = _y;
11254
+ this.max.y = _y + deltaY;
11255
+ }
11256
+
11257
+ /**
11258
+ * clone this bounds
11259
+ * @name clone
11260
+ * @memberOf me.Bounds
11261
+ * @function
11262
+ * @return {me.Bounds}
11263
+ */
11264
+ clone() {
11265
+ var bounds = new Bounds$1();
11266
+ bounds.addBounds(this);
11267
+ return bounds;
11268
+ }
11269
+
11270
+ /**
11271
+ * Returns a polygon whose edges are the same as this bounds.
11272
+ * @name toPolygon
11273
+ * @memberOf me.Bounds
11274
+ * @function
11275
+ * @return {me.Polygon} a new Polygon that represents this bounds.
11276
+ */
11277
+ toPolygon () {
11278
+ return new Polygon(this.x, this.y, [
11279
+ new Vector2d(0, 0),
11280
+ new Vector2d(this.width, 0),
11281
+ new Vector2d(this.width, this.height),
11282
+ new Vector2d(0, this.height)
11283
+ ]);
11284
+ }
11285
+
11286
+ }
11287
+
11288
+ /**
11289
+ * a temporary vector object
10811
11290
  * @ignore
10812
11291
  */
10813
- var viewportOffset = new Vector2d();
11292
+ var tmpVec = new Vector2d();
10814
11293
 
10815
11294
  /**
10816
11295
  * @classdesc
10817
11296
  * a pointer object, representing a single finger on a touch enabled device.
10818
11297
  * @class
10819
- * @extends me.Rect
11298
+ * @extends me.Bounds
10820
11299
  * @memberOf me
10821
11300
  * @constructor
10822
11301
  */
10823
- class Pointer extends Rect {
11302
+ class Pointer extends Bounds$1 {
10824
11303
 
10825
11304
  /**
10826
11305
  * @ignore
@@ -10828,7 +11307,10 @@ class Pointer extends Rect {
10828
11307
  constructor(x = 0, y = 0, w = 1, h = 1) {
10829
11308
 
10830
11309
  // parent constructor
10831
- super(x, y, w, h);
11310
+ super();
11311
+
11312
+ // initial coordinates/size
11313
+ this.setMinMax(x, y, x + w, y + h);
10832
11314
 
10833
11315
  /**
10834
11316
  * constant for left button
@@ -11081,9 +11563,6 @@ class Pointer extends Rect {
11081
11563
  * @param {Number} [pointedId=1] the Pointer, Touch or Mouse event Id (1)
11082
11564
  */
11083
11565
  setEvent(event, pageX = 0, pageY = 0, clientX = 0, clientY = 0, pointerId = 1) {
11084
- var width = 1;
11085
- var height = 1;
11086
-
11087
11566
  // the original event object
11088
11567
  this.event = event;
11089
11568
 
@@ -11093,7 +11572,9 @@ class Pointer extends Rect {
11093
11572
  this.clientY = clientY;
11094
11573
 
11095
11574
  // translate to local coordinates
11096
- globalToLocal(this.pageX, this.pageY, this.pos);
11575
+ globalToLocal(this.pageX, this.pageY, tmpVec);
11576
+ this.gameScreenX = this.x = tmpVec.x;
11577
+ this.gameScreenY = this.y = tmpVec.y;
11097
11578
 
11098
11579
  // true if not originally a pointer event
11099
11580
  this.isNormalized = !device$1.PointerEvent || (device$1.PointerEvent && !(event instanceof window.PointerEvent));
@@ -11119,30 +11600,29 @@ class Pointer extends Rect {
11119
11600
 
11120
11601
  this.type = event.type;
11121
11602
 
11122
- this.gameScreenX = this.pos.x;
11123
- this.gameScreenY = this.pos.y;
11603
+
11124
11604
 
11125
11605
  // get the current screen to game world offset
11126
11606
  if (typeof viewport !== "undefined") {
11127
- viewport.localToWorld(this.gameScreenX, this.gameScreenY, viewportOffset);
11607
+ viewport.localToWorld(this.gameScreenX, this.gameScreenY, tmpVec);
11128
11608
  }
11129
11609
 
11130
11610
  /* Initialize the two coordinate space properties. */
11131
- this.gameWorldX = viewportOffset.x;
11132
- this.gameWorldY = viewportOffset.y;
11611
+ this.gameWorldX = tmpVec.x;
11612
+ this.gameWorldY = tmpVec.y;
11133
11613
 
11134
11614
  // get the pointer size
11135
11615
  if (this.isNormalized === false) {
11136
11616
  // native PointerEvent
11137
- width = event.width || 1;
11138
- height = event.height || 1;
11617
+ this.width = event.width || 1;
11618
+ this.height = event.height || 1;
11139
11619
  } else if (typeof(event.radiusX) === "number") {
11140
11620
  // TouchEvent
11141
- width = (event.radiusX * 2) || 1;
11142
- height = (event.radiusY * 2) || 1;
11621
+ this.width = (event.radiusX * 2) || 1;
11622
+ this.height = (event.radiusY * 2) || 1;
11623
+ } else {
11624
+ this.width = this.height = 1;
11143
11625
  }
11144
- // resize the pointer object accordingly
11145
- this.resize(width, height);
11146
11626
  }
11147
11627
  }
11148
11628
 
@@ -11252,8 +11732,6 @@ function enablePointerEvent() {
11252
11732
  // the current pointer area
11253
11733
  currentPointer = new Rect(0, 0, 1, 1);
11254
11734
 
11255
- pointer = new Pointer(0, 0, 1, 1);
11256
-
11257
11735
  // instantiate a pool of pointer catched
11258
11736
  for (var v = 0; v < device$1.maxTouchPoints; v++) {
11259
11737
  T_POINTERS.push(new Pointer());
@@ -11543,15 +12021,15 @@ function dispatchEvent(normalizedEvents) {
11543
12021
  * @ignore
11544
12022
  */
11545
12023
  function normalizeEvent(originalEvent) {
11546
- var pointer;
12024
+ var _pointer;
11547
12025
 
11548
12026
  // PointerEvent or standard Mouse event
11549
12027
  if (device$1.TouchEvent && originalEvent.changedTouches) {
11550
12028
  // iOS/Android Touch event
11551
12029
  for (var i = 0, l = originalEvent.changedTouches.length; i < l; i++) {
11552
12030
  var touchEvent = originalEvent.changedTouches[i];
11553
- pointer = T_POINTERS.pop();
11554
- pointer.setEvent(
12031
+ _pointer = T_POINTERS.pop();
12032
+ _pointer.setEvent(
11555
12033
  originalEvent,
11556
12034
  touchEvent.pageX,
11557
12035
  touchEvent.pageY,
@@ -11559,12 +12037,12 @@ function normalizeEvent(originalEvent) {
11559
12037
  touchEvent.clientY,
11560
12038
  touchEvent.identifier
11561
12039
  );
11562
- normalizedEvents.push(pointer);
12040
+ normalizedEvents.push(_pointer);
11563
12041
  }
11564
12042
  } else {
11565
12043
  // Mouse or PointerEvent
11566
- pointer = T_POINTERS.pop();
11567
- pointer.setEvent(
12044
+ _pointer = T_POINTERS.pop();
12045
+ _pointer.setEvent(
11568
12046
  originalEvent,
11569
12047
  originalEvent.pageX,
11570
12048
  originalEvent.pageY,
@@ -11572,7 +12050,7 @@ function normalizeEvent(originalEvent) {
11572
12050
  originalEvent.clientY,
11573
12051
  originalEvent.pointerId
11574
12052
  );
11575
- normalizedEvents.push(pointer);
12053
+ normalizedEvents.push(_pointer);
11576
12054
  }
11577
12055
 
11578
12056
  // if event.isPrimary is defined and false, return
@@ -11644,7 +12122,7 @@ function onPointerEvent(e) {
11644
12122
  * @name pointer
11645
12123
  * @memberOf me.input
11646
12124
  */
11647
- var pointer;
12125
+ var pointer = new Pointer(0, 0, 1, 1);
11648
12126
 
11649
12127
  /**
11650
12128
  * time interval for event throttling in milliseconds<br>
@@ -11666,8 +12144,8 @@ var throttlingInterval;
11666
12144
  * @function
11667
12145
  * @param {Number} x the global x coordinate to be translated.
11668
12146
  * @param {Number} y the global y coordinate to be translated.
11669
- * @param {Number} [v] an optional vector object where to set the
11670
- * @return {me.Vector2d} A vector object with the corresponding translated coordinates.
12147
+ * @param {me.Vector2d} [v] an optional vector object where to set the translated coordinates
12148
+ * @return {me.Vector2d} A vector object with the corresponding translated coordinates
11671
12149
  * @example
11672
12150
  * onMouseEvent : function (pointer) {
11673
12151
  * // convert the given into local (viewport) relative coordinates
@@ -12404,7 +12882,7 @@ var input = /*#__PURE__*/Object.freeze({
12404
12882
  __proto__: null,
12405
12883
  preventDefault: preventDefault,
12406
12884
  get pointerEventTarget () { return pointerEventTarget; },
12407
- get pointer () { return pointer; },
12885
+ pointer: pointer,
12408
12886
  get throttlingInterval () { return throttlingInterval; },
12409
12887
  globalToLocal: globalToLocal,
12410
12888
  setTouchAction: setTouchAction,
@@ -12473,7 +12951,6 @@ class Renderable extends Rect {
12473
12951
  * @public
12474
12952
  * @type {me.Body}
12475
12953
  * @see me.Body
12476
- * @see me.collision#check
12477
12954
  * @name body
12478
12955
  * @memberOf me.Renderable#
12479
12956
  * @example
@@ -12846,6 +13323,7 @@ class Renderable extends Rect {
12846
13323
  if (isNaN(this.alpha)) {
12847
13324
  this.alpha = 1.0;
12848
13325
  }
13326
+ this.isDirty = true;
12849
13327
  }
12850
13328
  }
12851
13329
 
@@ -13163,8 +13641,8 @@ class Renderable extends Rect {
13163
13641
  // offset by the anchor point
13164
13642
  renderer.translate(-ax, -ay);
13165
13643
 
13166
- // apply the defined tint, if any
13167
- renderer.setTint(this.tint);
13644
+ // apply the current tint and opacity
13645
+ renderer.setTint(this.tint, this.getOpacity());
13168
13646
  }
13169
13647
 
13170
13648
  /**
@@ -13575,467 +14053,6 @@ class Ellipse {
13575
14053
  }
13576
14054
  }
13577
14055
 
13578
- /**
13579
- * @classdesc
13580
- * a bound object contains methods for creating and manipulating axis-aligned bounding boxes (AABB).
13581
- * @class Bounds
13582
- * @memberOf me
13583
- * @constructor
13584
- * @memberOf me
13585
- * @param {me.Vector2d[]} [vertices] an array of me.Vector2d points
13586
- * @return {me.Bounds} A new bounds object
13587
- */
13588
-
13589
- class Bounds$1 {
13590
-
13591
- constructor(vertices) {
13592
- this.onResetEvent(vertices);
13593
- }
13594
-
13595
- onResetEvent(vertices) {
13596
- if (typeof this.min === "undefined") {
13597
- this.min = { x: Infinity, y: Infinity };
13598
- this.max = { x: -Infinity, y: -Infinity };
13599
- } else {
13600
- this.clear();
13601
- }
13602
- if (typeof vertices !== "undefined") {
13603
- this.update(vertices);
13604
- }
13605
-
13606
- // @ignore
13607
- this._center = new Vector2d();
13608
- }
13609
-
13610
- /**
13611
- * reset the bound
13612
- * @name clear
13613
- * @memberOf me.Bounds
13614
- * @function
13615
- */
13616
- clear() {
13617
- this.setMinMax(Infinity, Infinity, -Infinity, -Infinity);
13618
-
13619
- }
13620
-
13621
- /**
13622
- * sets the bounds to the given min and max value
13623
- * @name setMinMax
13624
- * @memberOf me.Bounds
13625
- * @function
13626
- * @param {Number} minX
13627
- * @param {Number} minY
13628
- * @param {Number} maxX
13629
- * @param {Number} maxY
13630
- */
13631
- setMinMax(minX, minY, maxX, maxY) {
13632
- this.min.x = minX;
13633
- this.min.y = minY;
13634
-
13635
- this.max.x = maxX;
13636
- this.max.y = maxY;
13637
- }
13638
-
13639
- /**
13640
- * x position of the bound
13641
- * @public
13642
- * @type {Number}
13643
- * @name x
13644
- * @memberOf me.Bounds
13645
- */
13646
- get x() {
13647
- return this.min.x;
13648
- }
13649
-
13650
- set x(value) {
13651
- var deltaX = this.max.x - this.min.x;
13652
- this.min.x = value;
13653
- this.max.x = value + deltaX;
13654
- }
13655
-
13656
- /**
13657
- * y position of the bounds
13658
- * @public
13659
- * @type {Number}
13660
- * @name y
13661
- * @memberOf me.Bounds
13662
- */
13663
- get y() {
13664
- return this.min.y;
13665
- }
13666
-
13667
- set y(value) {
13668
- var deltaY = this.max.y - this.min.y;
13669
-
13670
- this.min.y = value;
13671
- this.max.y = value + deltaY;
13672
- }
13673
-
13674
- /**
13675
- * width of the bounds
13676
- * @public
13677
- * @type {Number}
13678
- * @name width
13679
- * @memberOf me.Bounds
13680
- */
13681
- get width() {
13682
- return this.max.x - this.min.x;
13683
- }
13684
-
13685
- set width(value) {
13686
- this.max.x = this.min.x + value;
13687
- }
13688
-
13689
- /**
13690
- * width of the bounds
13691
- * @public
13692
- * @type {Number}
13693
- * @name width
13694
- * @memberOf me.Bounds
13695
- */
13696
- get height() {
13697
- return this.max.y - this.min.y;
13698
- }
13699
-
13700
- set height(value) {
13701
- this.max.y = this.min.y + value;
13702
- }
13703
-
13704
- /**
13705
- * left coordinate of the bound
13706
- * @public
13707
- * @type {Number}
13708
- * @name left
13709
- * @memberOf me.Bounds
13710
- */
13711
- get left() {
13712
- return this.min.x;
13713
- }
13714
-
13715
- /**
13716
- * right coordinate of the bound
13717
- * @public
13718
- * @type {Number}
13719
- * @name right
13720
- * @memberOf me.Bounds
13721
- */
13722
- get right() {
13723
- return this.max.x;
13724
- }
13725
-
13726
- /**
13727
- * top coordinate of the bound
13728
- * @public
13729
- * @type {Number}
13730
- * @name top
13731
- * @memberOf me.Bounds
13732
- */
13733
- get top() {
13734
- return this.min.y;
13735
- }
13736
-
13737
- /**
13738
- * bottom coordinate of the bound
13739
- * @public
13740
- * @type {Number}
13741
- * @name bottom
13742
- * @memberOf me.Bounds
13743
- */
13744
- get bottom() {
13745
- return this.max.y;
13746
- }
13747
-
13748
- /**
13749
- * center position of the bound on the x axis
13750
- * @public
13751
- * @type {Number}
13752
- * @name centerX
13753
- * @memberOf me.Bounds
13754
- */
13755
- get centerX() {
13756
- return this.min.x + (this.width / 2);
13757
- }
13758
-
13759
- /**
13760
- * center position of the bound on the y axis
13761
- * @public
13762
- * @type {Number}
13763
- * @name centerY
13764
- * @memberOf me.Bounds
13765
- */
13766
- get centerY() {
13767
- return this.min.y + (this.height / 2);
13768
- }
13769
-
13770
- /**
13771
- * return the center position of the bound
13772
- * @public
13773
- * @type {me.Vector2d}
13774
- * @name center
13775
- * @memberOf me.Bounds
13776
- */
13777
- get center() {
13778
- return this._center.set(this.centerX, this.centerY);
13779
- }
13780
-
13781
- /**
13782
- * Updates bounds using the given vertices
13783
- * @name update
13784
- * @memberOf me.Bounds
13785
- * @function
13786
- * @param {me.Vector2d[]} vertices an array of me.Vector2d points
13787
- */
13788
- update(vertices) {
13789
- this.add(vertices, true);
13790
- }
13791
-
13792
- /**
13793
- * add the given vertices to the bounds definition.
13794
- * @name add
13795
- * @memberOf me.Bounds
13796
- * @function
13797
- * @param {me.Vector2d[]} vertices an array of me.Vector2d points
13798
- * @param {boolean} [clear=false] either to reset the bounds before adding the new vertices
13799
- */
13800
- add(vertices, clear = false) {
13801
- if (clear === true) {
13802
- this.clear();
13803
- }
13804
- for (var i = 0; i < vertices.length; i++) {
13805
- var vertex = vertices[i];
13806
- if (vertex.x > this.max.x) this.max.x = vertex.x;
13807
- if (vertex.x < this.min.x) this.min.x = vertex.x;
13808
- if (vertex.y > this.max.y) this.max.y = vertex.y;
13809
- if (vertex.y < this.min.y) this.min.y = vertex.y;
13810
- }
13811
- }
13812
-
13813
- /**
13814
- * add the given bounds to the bounds definition.
13815
- * @name addBounds
13816
- * @memberOf me.Bounds
13817
- * @function
13818
- * @param {me.Bounds} bounds
13819
- * @param {boolean} [clear=false] either to reset the bounds before adding the new vertices
13820
- */
13821
- addBounds(bounds, clear = false) {
13822
- if (clear === true) {
13823
- this.clear();
13824
- }
13825
-
13826
- if (bounds.max.x > this.max.x) this.max.x = bounds.max.x;
13827
- if (bounds.min.x < this.min.x) this.min.x = bounds.min.x;
13828
- if (bounds.max.y > this.max.y) this.max.y = bounds.max.y;
13829
- if (bounds.min.y < this.min.y) this.min.y = bounds.min.y;
13830
- }
13831
-
13832
- /**
13833
- * add the given point to the bounds definition.
13834
- * @name addPoint
13835
- * @memberOf me.Bounds
13836
- * @function
13837
- * @param {me.Vector2d} vector
13838
- * @param {me.Matrix2d} [matrix] an optional transform to apply to the given point
13839
- */
13840
- addPoint(v, m) {
13841
- if (typeof m !== "undefined") {
13842
- v = m.apply(v);
13843
- }
13844
- this.min.x = Math.min(this.min.x, v.x);
13845
- this.max.x = Math.max(this.max.x, v.x);
13846
- this.min.y = Math.min(this.min.y, v.y);
13847
- this.max.y = Math.max(this.max.y, v.y);
13848
- }
13849
-
13850
- /**
13851
- * add the given quad coordinates to this bound definition, multiplied by the given matrix
13852
- * @name addFrame
13853
- * @memberOf me.Bounds
13854
- * @function
13855
- * @param {Number} x0 - left X coordinates of the quad
13856
- * @param {Number} y0 - top Y coordinates of the quad
13857
- * @param {Number} x1 - right X coordinates of the quad
13858
- * @param {Number} y1 - bottom y coordinates of the quad
13859
- * @param {me.Matrix2d} [matrix] an optional transform to apply to the given frame coordinates
13860
- */
13861
- addFrame(x0, y0, x1, y1, m) {
13862
- var v = me.pool.pull("Vector2d");
13863
-
13864
- // transform all points and add to the bound definition
13865
- this.addPoint(v.set(x0, y0), m);
13866
- this.addPoint(v.set(x1, y0), m);
13867
- this.addPoint(v.set(x0, y1), m);
13868
- this.addPoint(v.set(x1, y1), m);
13869
-
13870
- me.pool.push(v);
13871
- }
13872
-
13873
- /**
13874
- * Returns true if the bounds contains the given point.
13875
- * @name contains
13876
- * @memberOf me.Bounds
13877
- * @function
13878
- * @param {me.Vector2d} point
13879
- * @return {boolean} True if the bounds contain the point, otherwise false
13880
- */
13881
- /**
13882
- * Returns true if the bounds contains the given point.
13883
- * @name contains
13884
- * @memberOf me.Bounds
13885
- * @function
13886
- * @param {Number} x
13887
- * @param {Number} y
13888
- * @return {boolean} True if the bounds contain the point, otherwise false
13889
- */
13890
- contains() {
13891
- var arg0 = arguments[0];
13892
- var _x1, _x2, _y1, _y2;
13893
- if (arguments.length === 2) {
13894
- // x, y
13895
- _x1 = _x2 = arg0;
13896
- _y1 = _y2 = arguments[1];
13897
- } else {
13898
- if (arg0 instanceof Bounds$1) {
13899
- // bounds
13900
- _x1 = arg0.min.x;
13901
- _x2 = arg0.max.x;
13902
- _y1 = arg0.min.y;
13903
- _y2 = arg0.max.y;
13904
- } else {
13905
- // vector
13906
- _x1 = _x2 = arg0.x;
13907
- _y1 = _y2 = arg0.y;
13908
- }
13909
- }
13910
-
13911
- return _x1 >= this.min.x && _x2 <= this.max.x
13912
- && _y1 >= this.min.y && _y2 <= this.max.y;
13913
- }
13914
-
13915
- /**
13916
- * Returns true if the two bounds intersect.
13917
- * @name overlaps
13918
- * @memberOf me.Bounds
13919
- * @function
13920
- * @param {me.Bounds|me.Rect} bounds
13921
- * @return {boolean} True if the bounds overlap, otherwise false
13922
- */
13923
- overlaps(bounds) {
13924
- return (this.left <= bounds.right && this.right >= bounds.left
13925
- && this.bottom >= bounds.top && this.top <= bounds.bottom);
13926
- }
13927
-
13928
- /**
13929
- * determines whether all coordinates of this bounds are finite numbers.
13930
- * @name isFinite
13931
- * @memberOf me.Bounds
13932
- * @function
13933
- * @return {boolean} false if all coordinates are positive or negative Infinity or NaN; otherwise, true.
13934
- */
13935
- isFinite() {
13936
- return (isFinite(this.min.x) && isFinite(this.max.x) && isFinite(this.min.y) && isFinite(this.max.y));
13937
- }
13938
-
13939
- /**
13940
- * Translates the bounds by the given vector.
13941
- * @name translate
13942
- * @memberOf me.Bounds
13943
- * @function
13944
- * @param {me.Vector2d} vector
13945
- */
13946
- /**
13947
- * Translates the bounds by x on the x axis, and y on the y axis
13948
- * @name translate
13949
- * @memberOf me.Bounds
13950
- * @function
13951
- * @param {Number} x
13952
- * @param {Number} y
13953
- */
13954
- translate() {
13955
- var _x, _y;
13956
- if (arguments.length === 2) {
13957
- // x, y
13958
- _x = arguments[0];
13959
- _y = arguments[1];
13960
- } else {
13961
- // vector
13962
- _x = arguments[0].x;
13963
- _y = arguments[0].y;
13964
- }
13965
- this.min.x += _x;
13966
- this.max.x += _x;
13967
- this.min.y += _y;
13968
- this.max.y += _y;
13969
- }
13970
-
13971
- /**
13972
- * Shifts the bounds to the given position vector.
13973
- * @name shift
13974
- * @memberOf me.Bounds
13975
- * @function
13976
- * @param {me.Vector2d} position
13977
- */
13978
- /**
13979
- * Shifts the bounds to the given x, y position.
13980
- * @name shift
13981
- * @memberOf me.Bounds
13982
- * @function
13983
- * @param {Number} x
13984
- * @param {Number} y
13985
- */
13986
- shift() {
13987
- var _x, _y;
13988
-
13989
- if (arguments.length === 2) {
13990
- // x, y
13991
- _x = arguments[0];
13992
- _y = arguments[1];
13993
- } else {
13994
- // vector
13995
- _x = arguments[0].x;
13996
- _y = arguments[0].y;
13997
- }
13998
-
13999
- var deltaX = this.max.x - this.min.x,
14000
- deltaY = this.max.y - this.min.y;
14001
-
14002
- this.min.x = _x;
14003
- this.max.x = _x + deltaX;
14004
- this.min.y = _y;
14005
- this.max.y = _y + deltaY;
14006
- }
14007
-
14008
- /**
14009
- * clone this bounds
14010
- * @name clone
14011
- * @memberOf me.Bounds
14012
- * @function
14013
- * @return {me.Bounds}
14014
- */
14015
- clone() {
14016
- var bounds = new Bounds$1();
14017
- bounds.addBounds(this);
14018
- return bounds;
14019
- }
14020
-
14021
- /**
14022
- * Returns a polygon whose edges are the same as this bounds.
14023
- * @name toPolygon
14024
- * @memberOf me.Bounds
14025
- * @function
14026
- * @return {me.Polygon} a new Polygon that represents this bounds.
14027
- */
14028
- toPolygon () {
14029
- return new Polygon(this.x, this.y, [
14030
- new Vector2d(0, 0),
14031
- new Vector2d(this.width, 0),
14032
- new Vector2d(this.width, this.height),
14033
- new Vector2d(0, this.height)
14034
- ]);
14035
- }
14036
-
14037
- }
14038
-
14039
14056
  /*
14040
14057
  * Separating Axis Theorem implementation, based on the SAT.js library by Jim Riecken <jimr@jimr.ca>
14041
14058
  * Available under the MIT License - https://github.com/jriecken/sat-js
@@ -14562,7 +14579,6 @@ function shouldCollide(a, b) {
14562
14579
  * @name ResponseObject
14563
14580
  * @memberOf me.collision
14564
14581
  * @public
14565
- * @see me.collision.check
14566
14582
  */
14567
14583
  class ResponseObject {
14568
14584
  constructor() {
@@ -14882,13 +14898,7 @@ var collision = {
14882
14898
  };
14883
14899
 
14884
14900
  /**
14885
- * a Generic Body Object with some physic properties and behavior functionality<br>
14886
- The body object is attached as a member of a Renderable. The Body object can handle movements of the parent with
14887
- the body.update call. It is important to know that when body.update is called there are several things that happen related to
14888
- the movement and positioning of the parent renderable object. 1) The force/gravity/friction parameters are used
14889
- to calculate a new velocity and 2) the parent position is updated by adding this to the parent.pos (position me.Vector2d)
14890
- value. Thus Affecting the movement of the parent. Look at the source code for /src/physics/body.js:update (me.Body.update) for
14891
- a better understanding.
14901
+ * a Generic Physic Body Object with some physic properties and behavior functionality, to as a member of a Renderable.
14892
14902
  * @class Body
14893
14903
  * @memberOf me
14894
14904
  * @constructor
@@ -15679,6 +15689,7 @@ var deferredRemove = function (child, keepalive) {
15679
15689
  var globalFloatingCounter = 0;
15680
15690
 
15681
15691
  /**
15692
+ * @classdesc
15682
15693
  * me.Container represents a collection of child objects
15683
15694
  * @class Container
15684
15695
  * @extends me.Renderable
@@ -17007,8 +17018,9 @@ class QuadTree {
17007
17018
  }
17008
17019
 
17009
17020
  /**
17021
+ * @classdesc
17010
17022
  * an object representing the physic world, and responsible for managing and updating all childs and physics
17011
- * @class
17023
+ * @class World
17012
17024
  * @extends me.Container
17013
17025
  * @memberOf me
17014
17026
  * @constructor
@@ -17310,7 +17322,7 @@ function reset () {
17310
17322
  * Update the renderer framerate using the system config variables.
17311
17323
  * @function me.game.updateFrameRate
17312
17324
  * @see me.timer.maxfps
17313
- * @see me.game.world.fps
17325
+ * @see me.World.fps
17314
17326
  */
17315
17327
  function updateFrameRate() {
17316
17328
  // reset the frame counter
@@ -17643,10 +17655,10 @@ class Camera2d extends Renderable {
17643
17655
  * @param {Number} [x=0]
17644
17656
  * @param {Number} [y=0]
17645
17657
  */
17646
- reset(x, y) {
17658
+ reset(x = 0, y = 0) {
17647
17659
  // reset the initial camera position to 0,0
17648
- this.pos.x = x || 0;
17649
- this.pos.y = y || 0;
17660
+ this.pos.x = x;
17661
+ this.pos.y = y;
17650
17662
 
17651
17663
  // reset the target
17652
17664
  this.unfollow();
@@ -18209,7 +18221,7 @@ var default_settings = {
18209
18221
  * @memberOf me
18210
18222
  * @constructor
18211
18223
  * @param {Object} [options] The stage` parameters
18212
- * @param {Boolean} [options.cameras=[new me.Camera2d()]] a list of cameras (experimental)
18224
+ * @param {me.Camera2d[]} [options.cameras=[new me.Camera2d()]] a list of cameras (experimental)
18213
18225
  * @param {Function} [options.onResetEvent] called by the state manager when reseting the object
18214
18226
  * @param {Function} [options.onDestroyEvent] called by the state manager before switching to another state
18215
18227
  * @see me.state
@@ -18246,7 +18258,7 @@ class Stage {
18246
18258
  * @ignore
18247
18259
  */
18248
18260
  reset() {
18249
-
18261
+
18250
18262
  // add all defined cameras
18251
18263
  this.settings.cameras.forEach((camera) => {
18252
18264
  this.cameras.set(camera.name, camera);
@@ -18526,82 +18538,19 @@ class IconLogo extends Renderable {
18526
18538
  renderer.drawImage(this.iconCanvas, renderer.getWidth() / 2, this.pos.y);
18527
18539
  }
18528
18540
  }
18529
- // the melonJS Text Logo
18530
- class TextLogo extends Renderable {
18531
- /**
18532
- * @ignore
18533
- */
18534
- constructor(w, h) {
18535
- super(0, 0, w, h);
18536
-
18537
- this.textWidth = 0;
18538
-
18539
- // offscreen cache canvas
18540
- this.fontCanvas = createCanvas(256, 64, true);
18541
- this.drawFont(renderer.getContext2d(this.fontCanvas));
18542
-
18543
- this.anchorPoint.set(0, 0.5);
18544
- }
18545
-
18546
- drawFont(context) {
18547
- var logo1 = pool.pull("Text", 0, 0, {
18548
- font: "century gothic",
18549
- size: 32,
18550
- fillStyle: "white",
18551
- textAlign: "middle",
18552
- textBaseline : "top",
18553
- text: "melon"
18554
- });
18555
- var logo2 = pool.pull("Text", 0, 0, {
18556
- font: "century gothic",
18557
- size: 32,
18558
- fillStyle: "#55aa00",
18559
- textAlign: "middle",
18560
- textBaseline : "top",
18561
- bold: true,
18562
- text: "JS"
18563
- });
18564
-
18565
18541
 
18566
- // compute both logo respective size
18567
- var logo1_width = logo1.measureText(context).width;
18568
- var logo2_width = logo2.measureText(context).width;
18569
-
18570
- this.textWidth = logo1_width + logo2_width;
18571
-
18572
- // calculate the final rendering position
18573
- this.pos.x = Math.round(this.width - this.textWidth / 2);
18574
- this.pos.y = Math.round(this.height + 16);
18575
-
18576
- // use the private _drawFont method to directly draw on the canvas context
18577
- logo1._drawFont(context, ["melon"], 0, 0);
18578
- logo2._drawFont(context, ["JS"], logo1_width, 0);
18579
-
18580
- // put them back into the object pool
18581
- pool.push(logo1);
18582
- pool.push(logo2);
18583
- }
18584
-
18585
- /**
18586
- * @ignore
18587
- */
18588
- draw(renderer) {
18589
- renderer.drawImage(this.fontCanvas, Math.round((renderer.getWidth() - this.textWidth) / 2), this.pos.y);
18590
- }
18591
-
18592
- }
18593
18542
  /**
18594
18543
  * a default loading screen
18595
18544
  * @memberOf me
18596
18545
  * @ignore
18597
18546
  * @constructor
18598
18547
  */
18599
- var defaultLoadingScreen = new Stage({
18548
+ class DefaultLoadingScreen extends Stage {
18600
18549
  /**
18601
18550
  * call when the loader is resetted
18602
18551
  * @ignore
18603
18552
  */
18604
- onResetEvent : function () {
18553
+ onResetEvent() {
18605
18554
  var barHeight = 8;
18606
18555
 
18607
18556
  // clear the background
@@ -18622,13 +18571,45 @@ var defaultLoadingScreen = new Stage({
18622
18571
 
18623
18572
  ), 2);
18624
18573
 
18574
+ var logo1 = pool.pull("Text",
18575
+ renderer.getWidth() / 2,
18576
+ (renderer.getHeight() / 2) + 16, {
18577
+ font: "century gothic",
18578
+ size: 32,
18579
+ fillStyle: "white",
18580
+ textAlign: "left",
18581
+ textBaseline : "top",
18582
+ text: "melon",
18583
+ offScreenCanvas: true
18584
+ }
18585
+ );
18586
+ logo1.anchorPoint.set(0, 0);
18587
+
18588
+ var logo2 = pool.pull("Text",
18589
+ renderer.getWidth() / 2,
18590
+ (renderer.getHeight() / 2) + 16, {
18591
+ font: "century gothic",
18592
+ size: 32,
18593
+ fillStyle: "#55aa00",
18594
+ textAlign: "left",
18595
+ textBaseline : "top",
18596
+ bold: true,
18597
+ text: "JS",
18598
+ offScreenCanvas: true
18599
+ }
18600
+ );
18601
+ logo2.anchorPoint.set(0, 0);
18602
+
18603
+ // adjust position of both text
18604
+ var text_width = logo1.getBounds().width + logo2.getBounds().width;
18605
+ logo1.pos.x = renderer.getWidth() / 2 - text_width / 2;
18606
+ logo2.pos.x = logo1.pos.x + logo1.getBounds().width;
18607
+
18625
18608
  // melonJS text
18626
- world.addChild(new TextLogo(
18627
- renderer.getWidth(),
18628
- renderer.getHeight()
18629
- ), 2);
18609
+ world.addChild(logo1, 2);
18610
+ world.addChild(logo2, 2);
18630
18611
  }
18631
- });
18612
+ }
18632
18613
 
18633
18614
  // current state
18634
18615
  var _state = -1;
@@ -18760,7 +18741,7 @@ function _switchState(state) {
18760
18741
  // initialize me.state on system boot
18761
18742
  on(BOOT, () => {
18762
18743
  // set the built-in loading stage
18763
- state.set(state.LOADING, defaultLoadingScreen);
18744
+ state.set(state.LOADING, new DefaultLoadingScreen());
18764
18745
  // set and enable the default stage
18765
18746
  state.set(state.DEFAULT, new Stage());
18766
18747
  // enable by default as soon as the display is initialized
@@ -19581,6 +19562,17 @@ class TextureCache {
19581
19562
  return this.cache.get(image);
19582
19563
  }
19583
19564
 
19565
+ /**
19566
+ * @ignore
19567
+ */
19568
+ remove(image) {
19569
+ if (!this.cache.has(image)) {
19570
+ if (this.cache.remove(image) === true) {
19571
+ this.length--;
19572
+ }
19573
+ }
19574
+ }
19575
+
19584
19576
  /**
19585
19577
  * @ignore
19586
19578
  */
@@ -19904,10 +19896,10 @@ class Texture {
19904
19896
  var sh = atlas[frame].height;
19905
19897
 
19906
19898
  atlas[frame].uvs = new Float32Array([
19907
- s.x / w, // Left
19908
- s.y / h, // Top
19909
- (s.x + sw) / w, // Right
19910
- (s.y + sh) / h // Bottom
19899
+ s.x / w, // u0 (left)
19900
+ s.y / h, // v0 (top)
19901
+ (s.x + sw) / w, // u1 (right)
19902
+ (s.y + sh) / h // v1 (bottom)
19911
19903
  ]);
19912
19904
  // Cache source coordinates
19913
19905
  // TODO: Remove this when the Batcher only accepts a region name
@@ -20043,7 +20035,8 @@ class Texture {
20043
20035
  * @function
20044
20036
  * @param {String} name name of the sprite
20045
20037
  * @param {Object} [settings] Additional settings passed to the {@link me.Sprite} contructor
20046
- * @return {me.Sprite}
20038
+ * @param {Boolean} [nineSlice=false] if true returns a 9-slice sprite
20039
+ * @return {me.Sprite|me.NineSliceSprite}
20047
20040
  * @example
20048
20041
  * // create a new texture object under the `game` namespace
20049
20042
  * game.texture = new me.video.renderer.Texture(
@@ -20056,11 +20049,20 @@ class Texture {
20056
20049
  * var sprite = game.texture.createSpriteFromName("coin.png");
20057
20050
  * // set the renderable position to bottom center
20058
20051
  * sprite.anchorPoint.set(0.5, 1.0);
20052
+ * ...
20053
+ * ...
20054
+ * // create a 9-slice sprite
20055
+ * var dialogPanel = game.texture.createSpriteFromName(
20056
+ * "rpg_dialo.png",
20057
+ * // width & height are mandatory for 9-slice sprites
20058
+ * { width: this.width, height: this.height },
20059
+ * true
20060
+ * );
20059
20061
  */
20060
- createSpriteFromName(name, settings) {
20062
+ createSpriteFromName(name, settings, nineSlice = false) {
20061
20063
  // instantiate a new sprite object
20062
20064
  return pool.pull(
20063
- "me.Sprite",
20065
+ nineSlice === true ? "me.NineSliceSprite" : "me.Sprite",
20064
20066
  0, 0,
20065
20067
  Object.assign({
20066
20068
  image: this,
@@ -20149,7 +20151,7 @@ class Texture {
20149
20151
  * @param {String} [settings.region] region name of a specific region to use when using a texture atlas, see {@link me.Renderer.Texture}
20150
20152
  * @param {Number} [settings.framewidth] Width of a single frame within the spritesheet
20151
20153
  * @param {Number} [settings.frameheight] Height of a single frame within the spritesheet
20152
- * @param {String|Color} [settings.tint] a tint to be applied to this sprite
20154
+ * @param {String|me.Color} [settings.tint] a tint to be applied to this sprite
20153
20155
  * @param {Number} [settings.flipX] flip the sprite on the horizontal axis
20154
20156
  * @param {Number} [settings.flipY] flip the sprite on the vertical axis
20155
20157
  * @param {me.Vector2d} [settings.anchorPoint={x:0.5, y:0.5}] Anchor point to draw the frame at (defaults to the center of the frame).
@@ -20310,7 +20312,7 @@ class Sprite extends Renderable {
20310
20312
  // set the default rotation angle is defined in the settings
20311
20313
  // * WARNING: rotating sprites decreases performance with Canvas Renderer
20312
20314
  if (typeof (settings.rotation) !== "undefined") {
20313
- this.currentTransform.rotate(settings.rotation);
20315
+ this.rotate(settings.rotation);
20314
20316
  }
20315
20317
 
20316
20318
  // update anchorPoint
@@ -21232,7 +21234,7 @@ class Renderer {
21232
21234
  * @function
21233
21235
  * @param {HTMLCanvasElement} canvas
21234
21236
  * @param {Boolean} [transparent=true] use false to disable transparency
21235
- * @return {Context2d}
21237
+ * @return {CanvasRenderingContext2D}
21236
21238
  */
21237
21239
  getContext2d(c, transparent) {
21238
21240
  if (typeof c === "undefined" || c === null) {
@@ -21474,11 +21476,13 @@ class Renderer {
21474
21476
  * @name setTint
21475
21477
  * @memberOf me.Renderer.prototype
21476
21478
  * @function
21477
- * @param {me.Color} [tint] the tint color
21479
+ * @param {me.Color} tint the tint color
21480
+ * @param {Number} [alpha] an alpha value to be applied to the tint
21478
21481
  */
21479
- setTint(tint) {
21482
+ setTint(tint, alpha = tint.alpha) {
21480
21483
  // global tint color
21481
21484
  this.currentTint.copy(tint);
21485
+ this.currentTint.alpha *= alpha;
21482
21486
  }
21483
21487
 
21484
21488
  /**
@@ -22534,7 +22538,7 @@ class TMXLayer extends Renderable {
22534
22538
  * // get the TMX Map Layer called "Front layer"
22535
22539
  * var layer = me.game.world.getChildByName("Front Layer")[0];
22536
22540
  * // get the tile object corresponding to the latest pointer position
22537
- * var tile = layer.getTile(me.input.pointer.pos.x, me.input.pointer.pos.y);
22541
+ * var tile = layer.getTile(me.input.pointer.x, me.input.pointer.y);
22538
22542
  */
22539
22543
  getTile(x, y) {
22540
22544
  var tile = null;
@@ -23021,8 +23025,8 @@ class Bounds {
23021
23025
  * @return {boolean} True if the bounds overlap, otherwise false
23022
23026
  */
23023
23027
  overlaps(bounds) {
23024
- return (this.left <= bounds.right && this.right >= bounds.left
23025
- && this.bottom >= bounds.top && this.top <= bounds.bottom);
23028
+ return !(this.right < bounds.left || this.left > bounds.right ||
23029
+ this.bottom < bounds.top || this.top > bounds.bottom);
23026
23030
  }
23027
23031
 
23028
23032
  /**
@@ -26351,7 +26355,7 @@ var loader = {
26351
26355
  * // set all resources to be loaded
26352
26356
  * me.loader.preload(game.resources, this.loaded.bind(this));
26353
26357
  */
26354
- preload(res, onload, switchToLoadState) {
26358
+ preload(res, onload, switchToLoadState = true) {
26355
26359
  // parse the resources
26356
26360
  for (var i = 0; i < res.length; i++) {
26357
26361
  resourceCount += this.load(
@@ -26365,7 +26369,7 @@ var loader = {
26365
26369
  this.onload = onload;
26366
26370
  }
26367
26371
 
26368
- if (switchToLoadState !== false) {
26372
+ if (switchToLoadState === true) {
26369
26373
  // swith to the loading screen
26370
26374
  state.change(state.LOADING);
26371
26375
  }
@@ -27415,6 +27419,10 @@ function _checkCapabilities() {
27415
27419
  device.hasDeviceOrientation = !!window.DeviceOrientationEvent;
27416
27420
  device.hasAccelerometer = !!window.DeviceMotionEvent;
27417
27421
 
27422
+ // support the ScreenOrientation API
27423
+ device.ScreenOrientation = (typeof screen !== "undefined") &&
27424
+ (typeof screen.orientation !== "undefined");
27425
+
27418
27426
  // fullscreen api detection & polyfill when possible
27419
27427
  device.hasFullscreenSupport = prefixed("fullscreenEnabled", document) ||
27420
27428
  document.mozFullScreenEnabled;
@@ -27557,6 +27565,16 @@ let device = {
27557
27565
  */
27558
27566
  hasDeviceOrientation : false,
27559
27567
 
27568
+ /**
27569
+ * Supports the ScreenOrientation API
27570
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation/onchange
27571
+ * @type Boolean
27572
+ * @readonly
27573
+ * @name ScreenOrientation
27574
+ * @memberOf me.device
27575
+ */
27576
+ ScreenOrientation : false,
27577
+
27560
27578
  /**
27561
27579
  * Browser full screen support
27562
27580
  * @type Boolean
@@ -27989,7 +28007,7 @@ let device = {
27989
28007
  var screen = window.screen;
27990
28008
 
27991
28009
  // first try using "standard" values
27992
- if (typeof screen !== "undefined") {
28010
+ if (this.ScreenOrientation === true) {
27993
28011
  var orientation = prefixed("orientation", screen);
27994
28012
  if (typeof orientation !== "undefined" && typeof orientation.type === "string") {
27995
28013
  // Screen Orientation API specification
@@ -28818,14 +28836,151 @@ class GLShader {
28818
28836
  }
28819
28837
  }
28820
28838
 
28839
+ /**
28840
+ * @classdesc
28841
+ * a Vertex Buffer object
28842
+ * @class VertexArrayBuffer
28843
+ * @private
28844
+ */
28845
+
28846
+ class VertexArrayBuffer {
28847
+
28848
+ constructor(vertex_size, vertex_per_quad) {
28849
+ // the size of one vertex
28850
+ this.vertexSize = vertex_size;
28851
+ // size of a quad in vertex
28852
+ this.quadSize = vertex_per_quad;
28853
+ // the maximum number of vertices the vertex array buffer can hold
28854
+ this.maxVertex = 256;
28855
+ // the current number of vertices added to the vertex array buffer
28856
+ this.vertexCount = 0;
28857
+
28858
+ // the actual vertex data buffer
28859
+ this.buffer = new ArrayBuffer(this.maxVertex * this.vertexSize * this.quadSize);
28860
+ // Float32 and Uint32 view of the vertex data array buffer
28861
+ this.bufferF32 = new Float32Array(this.buffer);
28862
+ this.bufferU32 = new Uint32Array(this.buffer);
28863
+
28864
+
28865
+ return this;
28866
+ }
28867
+
28868
+ /**
28869
+ * clear the vertex array buffer
28870
+ */
28871
+ clear() {
28872
+ this.vertexCount = 0;
28873
+ }
28874
+
28875
+
28876
+ /**
28877
+ * return true if full
28878
+ */
28879
+ isFull(vertex = 0) {
28880
+ return (this.vertexCount + vertex >= this.maxVertex);
28881
+ }
28882
+
28883
+ /**
28884
+ * resize the vertex buffer, retaining its original contents
28885
+ */
28886
+ resize() {
28887
+ // double the vertex size
28888
+ this.maxVertex <<= 1;
28889
+ // save a reference to the previous data
28890
+ var data = this.bufferF32;
28891
+
28892
+ // recreate ArrayBuffer and views
28893
+ this.buffer = new ArrayBuffer(this.maxVertex * this.vertexSize * this.quadSize);
28894
+ this.bufferF32 = new Float32Array(this.buffer);
28895
+ this.bufferU32 = new Uint32Array(this.buffer);
28896
+
28897
+ // copy previous data
28898
+ this.bufferF32.set(data);
28899
+
28900
+ return this;
28901
+ }
28902
+
28903
+ /**
28904
+ * push a new vertex to the buffer
28905
+ */
28906
+ push(x, y, u, v, tint) {
28907
+ var offset = this.vertexCount * this.vertexSize;
28908
+
28909
+ if (this.vertexCount >= this.maxVertex) {
28910
+ this.resize();
28911
+ }
28912
+
28913
+ this.bufferF32[offset + 0] = x;
28914
+ this.bufferF32[offset + 1] = y;
28915
+
28916
+ if (typeof u !== "undefined") {
28917
+ this.bufferF32[offset + 2] = u;
28918
+ this.bufferF32[offset + 3] = v;
28919
+ }
28920
+
28921
+ if (typeof tint !== "undefined") {
28922
+ this.bufferU32[offset + 4] = tint;
28923
+ }
28924
+
28925
+ this.vertexCount++;
28926
+
28927
+ return this;
28928
+ }
28929
+
28930
+ /**
28931
+ * return a reference to the data in Float32 format
28932
+ */
28933
+ toFloat32(begin, end) {
28934
+ if (typeof end !== "undefined") {
28935
+ return this.bufferF32.subarray(begin, end);
28936
+ } else {
28937
+ return this.bufferF32;
28938
+ }
28939
+ }
28940
+
28941
+ /**
28942
+ * return a reference to the data in Uint32 format
28943
+ */
28944
+ toUint32(begin, end) {
28945
+ if (typeof end !== "undefined") {
28946
+ return this.bufferU32.subarray(begin, end);
28947
+ } else {
28948
+ return this.bufferU32;
28949
+ }
28950
+ }
28951
+
28952
+ /**
28953
+ * return the size of the vertex in vertex
28954
+ */
28955
+ length() {
28956
+ return this.vertexCount;
28957
+ }
28958
+
28959
+ /**
28960
+ * return true if empty
28961
+ */
28962
+ isEmpty() {
28963
+ return this.vertexCount === 0;
28964
+ }
28965
+
28966
+ }
28967
+
28821
28968
  var primitiveVertex = "// Current vertex point\nattribute vec2 aVertex;\n\n// Projection matrix\nuniform mat4 uProjectionMatrix;\n\n// Vertex color\nuniform vec4 uColor;\n\n// Fragment color\nvarying vec4 vColor;\n\nvoid main(void) {\n // Transform the vertex position by the projection matrix\n gl_Position = uProjectionMatrix * vec4(aVertex, 0.0, 1.0);\n // Pass the remaining attributes to the fragment shader\n vColor = vec4(uColor.rgb * uColor.a, uColor.a);\n}\n";
28822
28969
 
28823
28970
  var primitiveFragment = "varying vec4 vColor;\n\nvoid main(void) {\n gl_FragColor = vColor;\n}\n";
28824
28971
 
28825
- var quadVertex = "attribute vec2 aVertex;\nattribute vec2 aRegion;\nattribute vec4 aColor;\n\nuniform mat4 uProjectionMatrix;\n\nvarying vec2 vRegion;\nvarying vec4 vColor;\n\nvoid main(void) {\n // Transform the vertex position by the projection matrix\n gl_Position = uProjectionMatrix * vec4(aVertex, 0.0, 1.0);\n // Pass the remaining attributes to the fragment shader\n vColor = vec4(aColor.rgb * aColor.a, aColor.a);\n vRegion = aRegion;\n}\n";
28972
+ var quadVertex = "attribute vec2 aVertex;\nattribute vec2 aRegion;\nattribute vec4 aColor;\n\nuniform mat4 uProjectionMatrix;\n\nvarying vec2 vRegion;\nvarying vec4 vColor;\n\nvoid main(void) {\n // Transform the vertex position by the projection matrix\n gl_Position = uProjectionMatrix * vec4(aVertex, 0.0, 1.0);\n // Pass the remaining attributes to the fragment shader\n vColor = vec4(aColor.bgr * aColor.a, aColor.a);\n vRegion = aRegion;\n}\n";
28826
28973
 
28827
28974
  var quadFragment = "uniform sampler2D uSampler;\nvarying vec4 vColor;\nvarying vec2 vRegion;\n\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vRegion) * vColor;\n}\n";
28828
28975
 
28976
+ // a pool of resuable vectors
28977
+ var V_ARRAY = [
28978
+ new Vector2d(),
28979
+ new Vector2d(),
28980
+ new Vector2d(),
28981
+ new Vector2d()
28982
+ ];
28983
+
28829
28984
  // Handy constants
28830
28985
  var VERTEX_SIZE = 2;
28831
28986
  var REGION_SIZE = 2;
@@ -28834,15 +28989,31 @@ var COLOR_SIZE = 4;
28834
28989
  var ELEMENT_SIZE = VERTEX_SIZE + REGION_SIZE + COLOR_SIZE;
28835
28990
  var ELEMENT_OFFSET = ELEMENT_SIZE * Float32Array.BYTES_PER_ELEMENT;
28836
28991
 
28837
- var VERTEX_ELEMENT = 0;
28838
- var REGION_ELEMENT = VERTEX_ELEMENT + VERTEX_SIZE;
28839
- var COLOR_ELEMENT = REGION_ELEMENT + REGION_SIZE;
28840
-
28841
28992
  var ELEMENTS_PER_QUAD = 4;
28842
28993
  var INDICES_PER_QUAD = 6;
28843
28994
 
28844
28995
  var MAX_LENGTH = 16000;
28845
28996
 
28997
+ /**
28998
+ * Create a full index buffer for the element array
28999
+ * @ignore
29000
+ */
29001
+ function createIB() {
29002
+ var indices = [
29003
+ 0, 1, 2,
29004
+ 2, 1, 3
29005
+ ];
29006
+
29007
+ // ~384KB index buffer
29008
+ var data = new Array(MAX_LENGTH * INDICES_PER_QUAD);
29009
+ for (var i = 0; i < data.length; i++) {
29010
+ data[i] = indices[i % INDICES_PER_QUAD] +
29011
+ ~~(i / INDICES_PER_QUAD) * ELEMENTS_PER_QUAD;
29012
+ }
29013
+
29014
+ return new Uint16Array(data);
29015
+ }
29016
+
28846
29017
  /**
28847
29018
  * @classdesc
28848
29019
  * A WebGL Compositor object. This class handles all of the WebGL state<br>
@@ -28873,20 +29044,12 @@ class WebGLCompositor {
28873
29044
  * @type Number
28874
29045
  * @readonly
28875
29046
  */
28876
- this.length = 0;
29047
+ //this.length = 0;
28877
29048
 
28878
29049
  // list of active texture units
28879
29050
  this.currentTextureUnit = -1;
28880
29051
  this.boundTextures = [];
28881
29052
 
28882
- // Vector pool
28883
- this.v = [
28884
- new Vector2d(),
28885
- new Vector2d(),
28886
- new Vector2d(),
28887
- new Vector2d()
28888
- ];
28889
-
28890
29053
  // the associated renderer
28891
29054
  this.renderer = renderer;
28892
29055
 
@@ -28896,9 +29059,6 @@ class WebGLCompositor {
28896
29059
  // Global fill color
28897
29060
  this.color = renderer.currentColor;
28898
29061
 
28899
- // Global tint color
28900
- this.tint = renderer.currentTint;
28901
-
28902
29062
  // Global transformation matrix
28903
29063
  this.viewMatrix = renderer.currentTransform;
28904
29064
 
@@ -28934,9 +29094,9 @@ class WebGLCompositor {
28934
29094
  /// define all vertex attributes
28935
29095
  this.addAttribute("aVertex", 2, gl.FLOAT, false, 0 * Float32Array.BYTES_PER_ELEMENT); // 0
28936
29096
  this.addAttribute("aRegion", 2, gl.FLOAT, false, 2 * Float32Array.BYTES_PER_ELEMENT); // 1
28937
- this.addAttribute("aColor", 4, gl.FLOAT, false, 4 * Float32Array.BYTES_PER_ELEMENT); // 2
29097
+ this.addAttribute("aColor", 4, gl.UNSIGNED_BYTE, true, 4 * Float32Array.BYTES_PER_ELEMENT); // 2
28938
29098
 
28939
- // Stream buffer
29099
+ // vertex buffer
28940
29100
  gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
28941
29101
  gl.bufferData(
28942
29102
  gl.ARRAY_BUFFER,
@@ -28944,17 +29104,11 @@ class WebGLCompositor {
28944
29104
  gl.STREAM_DRAW
28945
29105
  );
28946
29106
 
28947
- this.sbSize = 256;
28948
- this.sbIndex = 0;
29107
+ this.vertexBuffer = new VertexArrayBuffer(ELEMENT_SIZE, ELEMENTS_PER_QUAD);
28949
29108
 
28950
- // Quad stream buffer
28951
- this.stream = new Float32Array(
28952
- this.sbSize * ELEMENT_SIZE * ELEMENTS_PER_QUAD
28953
- );
28954
-
28955
- // Index buffer
29109
+ // Cache index buffer (TODO Remove use for cache by replacing drawElements by drawArrays)
28956
29110
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
28957
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.createIB(), gl.STATIC_DRAW);
29111
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, createIB(), gl.STATIC_DRAW);
28958
29112
 
28959
29113
  // register to the CANVAS resize channel
28960
29114
  on(CANVAS_ONRESIZE, (width, height) => {
@@ -28970,9 +29124,6 @@ class WebGLCompositor {
28970
29124
  * @ignore
28971
29125
  */
28972
29126
  reset() {
28973
- this.sbIndex = 0;
28974
- this.length = 0;
28975
-
28976
29127
  // WebGL context
28977
29128
  this.gl = this.renderer.gl;
28978
29129
 
@@ -29010,7 +29161,7 @@ class WebGLCompositor {
29010
29161
  * @param {String} name name of the attribute in the vertex shader
29011
29162
  * @param {Number} size number of components per vertex attribute. Must be 1, 2, 3, or 4.
29012
29163
  * @param {GLenum} type data type of each component in the array
29013
- * @param {Boolean} normalized whether integer data values should be normalized into a certain
29164
+ * @param {Boolean} normalized whether integer data values should be normalized into a certain range when being cast to a float
29014
29165
  * @param {Number} offset offset in bytes of the first component in the vertex attribute array
29015
29166
  */
29016
29167
  addAttribute(name, size, type, normalized, offset) {
@@ -29058,10 +29209,10 @@ class WebGLCompositor {
29058
29209
  var gl = this.gl;
29059
29210
  var isPOT = isPowerOfTwo(w || image.width) && isPowerOfTwo(h || image.height);
29060
29211
  var texture = gl.createTexture();
29061
- var rs = (repeat.search(/^repeat(-x)?$/) === 0) && (isPOT || this.renderer.WebGLVersion === 2) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
29062
- var rt = (repeat.search(/^repeat(-y)?$/) === 0) && (isPOT || this.renderer.WebGLVersion === 2) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
29212
+ var rs = (repeat.search(/^repeat(-x)?$/) === 0) && (isPOT || this.renderer.WebGLVersion > 1) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
29213
+ var rt = (repeat.search(/^repeat(-y)?$/) === 0) && (isPOT || this.renderer.WebGLVersion > 1) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
29063
29214
 
29064
- this.setTexture2D(texture, unit);
29215
+ this.bindTexture2D(texture, unit);
29065
29216
 
29066
29217
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, rs);
29067
29218
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, rt);
@@ -29085,13 +29236,13 @@ class WebGLCompositor {
29085
29236
 
29086
29237
  /**
29087
29238
  * assign the given WebGL texture to the current batch
29088
- * @name setTexture2D
29239
+ * @name bindTexture2D
29089
29240
  * @memberOf me.WebGLCompositor
29090
29241
  * @function
29091
29242
  * @param {WebGLTexture} a WebGL texture
29092
29243
  * @param {Number} unit Texture unit to which the given texture is bound
29093
29244
  */
29094
- setTexture2D(texture, unit) {
29245
+ bindTexture2D(texture, unit) {
29095
29246
  var gl = this.gl;
29096
29247
 
29097
29248
  if (texture !== this.boundTextures[unit]) {
@@ -29111,6 +29262,17 @@ class WebGLCompositor {
29111
29262
  }
29112
29263
  }
29113
29264
 
29265
+ /**
29266
+ * unbind the given WebGL texture, forcing it to be reuploaded
29267
+ * @name unbindTexture2D
29268
+ * @memberOf me.WebGLCompositor
29269
+ * @function
29270
+ * @param {WebGLTexture} a WebGL texture
29271
+ */
29272
+ unbindTexture2D(texture) {
29273
+ var unit = this.renderer.cache.getUnit(texture);
29274
+ this.boundTextures[unit] = null;
29275
+ }
29114
29276
 
29115
29277
  /**
29116
29278
  * @ignore
@@ -29131,43 +29293,12 @@ class WebGLCompositor {
29131
29293
  texture.premultipliedAlpha
29132
29294
  );
29133
29295
  } else {
29134
- this.setTexture2D(texture2D, unit);
29296
+ this.bindTexture2D(texture2D, unit);
29135
29297
  }
29136
29298
 
29137
29299
  return this.currentTextureUnit;
29138
29300
  }
29139
29301
 
29140
- /**
29141
- * Create a full index buffer for the element array
29142
- * @ignore
29143
- */
29144
- createIB() {
29145
- var indices = [
29146
- 0, 1, 2,
29147
- 2, 1, 3
29148
- ];
29149
-
29150
- // ~384KB index buffer
29151
- var data = new Array(MAX_LENGTH * INDICES_PER_QUAD);
29152
- for (var i = 0; i < data.length; i++) {
29153
- data[i] = indices[i % INDICES_PER_QUAD] +
29154
- ~~(i / INDICES_PER_QUAD) * ELEMENTS_PER_QUAD;
29155
- }
29156
-
29157
- return new Uint16Array(data);
29158
- }
29159
-
29160
- /**
29161
- * Resize the stream buffer, retaining its original contents
29162
- * @ignore
29163
- */
29164
- resizeSB() {
29165
- this.sbSize <<= 1;
29166
- var stream = new Float32Array(this.sbSize * ELEMENT_SIZE * ELEMENTS_PER_QUAD);
29167
- stream.set(this.stream);
29168
- this.stream = stream;
29169
- }
29170
-
29171
29302
  /**
29172
29303
  * Select the shader to use for compositing
29173
29304
  * @name useShader
@@ -29205,33 +29336,29 @@ class WebGLCompositor {
29205
29336
  * @memberOf me.WebGLCompositor
29206
29337
  * @function
29207
29338
  * @param {me.Renderer.Texture} texture Source texture
29208
- * @param {String} key Source texture region name
29209
29339
  * @param {Number} x Destination x-coordinate
29210
29340
  * @param {Number} y Destination y-coordinate
29211
29341
  * @param {Number} w Destination width
29212
29342
  * @param {Number} h Destination height
29343
+ * @param {number} u0 Texture UV (u0) value.
29344
+ * @param {number} v0 Texture UV (v0) value.
29345
+ * @param {number} u1 Texture UV (u1) value.
29346
+ * @param {number} v1 Texture UV (v1) value.
29347
+ * @param {number} tint tint color to be applied to the texture in UINT32 format
29213
29348
  */
29214
- addQuad(texture, key, x, y, w, h) {
29215
- //var gl = this.gl;
29216
- var color = this.color.toArray();
29217
- var tint = this.tint.toArray();
29349
+ addQuad(texture, x, y, w, h, u0, v0, u1, v1, tint) {
29218
29350
 
29219
- if (color[3] < 1 / 255) {
29351
+ if (this.color.alpha < 1 / 255) {
29220
29352
  // Fast path: don't send fully transparent quads
29221
29353
  return;
29222
- } else {
29223
- // use the global alpha
29224
- tint[3] = color[3];
29225
29354
  }
29226
29355
 
29227
- if (this.length >= MAX_LENGTH) {
29356
+ this.useShader(this.quadShader);
29357
+
29358
+ if (this.vertexBuffer.isFull(4)) {
29359
+ // is the vertex buffer full if we add 4 more vertices
29228
29360
  this.flush();
29229
29361
  }
29230
- if (this.length >= this.sbSize) {
29231
- this.resizeSB();
29232
- }
29233
-
29234
- this.useShader(this.quadShader);
29235
29362
 
29236
29363
  // upload and activate the texture if necessary
29237
29364
  var unit = this.uploadTexture(texture);
@@ -29240,56 +29367,22 @@ class WebGLCompositor {
29240
29367
 
29241
29368
  // Transform vertices
29242
29369
  var m = this.viewMatrix,
29243
- v0 = this.v[0].set(x, y),
29244
- v1 = this.v[1].set(x + w, y),
29245
- v2 = this.v[2].set(x, y + h),
29246
- v3 = this.v[3].set(x + w, y + h);
29370
+ vec0 = V_ARRAY[0].set(x, y),
29371
+ vec1 = V_ARRAY[1].set(x + w, y),
29372
+ vec2 = V_ARRAY[2].set(x, y + h),
29373
+ vec3 = V_ARRAY[3].set(x + w, y + h);
29247
29374
 
29248
29375
  if (!m.isIdentity()) {
29249
- m.apply(v0);
29250
- m.apply(v1);
29251
- m.apply(v2);
29252
- m.apply(v3);
29253
- }
29254
-
29255
- // Array index computation
29256
- var idx0 = this.sbIndex,
29257
- idx1 = idx0 + ELEMENT_SIZE,
29258
- idx2 = idx1 + ELEMENT_SIZE,
29259
- idx3 = idx2 + ELEMENT_SIZE;
29260
-
29261
- // Fill vertex buffer
29262
- // FIXME: Pack each vertex vector into single float
29263
- this.stream[idx0 + VERTEX_ELEMENT + 0] = v0.x;
29264
- this.stream[idx0 + VERTEX_ELEMENT + 1] = v0.y;
29265
- this.stream[idx1 + VERTEX_ELEMENT + 0] = v1.x;
29266
- this.stream[idx1 + VERTEX_ELEMENT + 1] = v1.y;
29267
- this.stream[idx2 + VERTEX_ELEMENT + 0] = v2.x;
29268
- this.stream[idx2 + VERTEX_ELEMENT + 1] = v2.y;
29269
- this.stream[idx3 + VERTEX_ELEMENT + 0] = v3.x;
29270
- this.stream[idx3 + VERTEX_ELEMENT + 1] = v3.y;
29271
-
29272
- // Fill texture coordinates buffer
29273
- var uvs = texture.getUVs(key);
29274
- // FIXME: Pack each texture coordinate into single floats
29275
- this.stream[idx0 + REGION_ELEMENT + 0] = uvs[0];
29276
- this.stream[idx0 + REGION_ELEMENT + 1] = uvs[1];
29277
- this.stream[idx1 + REGION_ELEMENT + 0] = uvs[2];
29278
- this.stream[idx1 + REGION_ELEMENT + 1] = uvs[1];
29279
- this.stream[idx2 + REGION_ELEMENT + 0] = uvs[0];
29280
- this.stream[idx2 + REGION_ELEMENT + 1] = uvs[3];
29281
- this.stream[idx3 + REGION_ELEMENT + 0] = uvs[2];
29282
- this.stream[idx3 + REGION_ELEMENT + 1] = uvs[3];
29283
-
29284
- // Fill color buffer
29285
- // FIXME: Pack color vector into single float
29286
- this.stream.set(tint, idx0 + COLOR_ELEMENT);
29287
- this.stream.set(tint, idx1 + COLOR_ELEMENT);
29288
- this.stream.set(tint, idx2 + COLOR_ELEMENT);
29289
- this.stream.set(tint, idx3 + COLOR_ELEMENT);
29290
-
29291
- this.sbIndex += ELEMENT_SIZE * ELEMENTS_PER_QUAD;
29292
- this.length++;
29376
+ m.apply(vec0);
29377
+ m.apply(vec1);
29378
+ m.apply(vec2);
29379
+ m.apply(vec3);
29380
+ }
29381
+
29382
+ this.vertexBuffer.push(vec0.x, vec0.y, u0, v0, tint);
29383
+ this.vertexBuffer.push(vec1.x, vec1.y, u1, v0, tint);
29384
+ this.vertexBuffer.push(vec2.x, vec2.y, u0, v1, tint);
29385
+ this.vertexBuffer.push(vec3.x, vec3.y, u1, v1, tint);
29293
29386
  }
29294
29387
 
29295
29388
  /**
@@ -29298,28 +29391,32 @@ class WebGLCompositor {
29298
29391
  * @memberOf me.WebGLCompositor
29299
29392
  * @function
29300
29393
  */
29301
- flush() {
29302
- if (this.length) {
29394
+ flush(mode = this.mode) {
29395
+ var vertex = this.vertexBuffer;
29396
+ var vertexCount = vertex.vertexCount;
29397
+
29398
+ if (vertexCount > 0) {
29303
29399
  var gl = this.gl;
29400
+ var vertexSize = vertex.vertexSize;
29304
29401
 
29305
29402
  // Copy data into stream buffer
29306
- var len = this.length * ELEMENT_SIZE * ELEMENTS_PER_QUAD;
29307
- gl.bufferData(
29308
- gl.ARRAY_BUFFER,
29309
- this.stream.subarray(0, len),
29310
- gl.STREAM_DRAW
29311
- );
29403
+ if (this.renderer.WebGLVersion > 1) {
29404
+ gl.bufferData(gl.ARRAY_BUFFER, vertex.toFloat32(), gl.STREAM_DRAW, 0, vertexCount * vertexSize);
29405
+ } else {
29406
+ gl.bufferData(gl.ARRAY_BUFFER, vertex.toFloat32(0, vertexCount * vertexSize), gl.STREAM_DRAW);
29407
+ }
29312
29408
 
29313
29409
  // Draw the stream buffer
29314
- gl.drawElements(
29315
- this.mode,
29316
- this.length * INDICES_PER_QUAD,
29317
- gl.UNSIGNED_SHORT,
29318
- 0
29319
- );
29410
+ // TODO : finalize the WebGLCompositor implementation (splitting this one into two)
29411
+ // so that different compositor with different attributes/uniforms & drawing method can be used
29412
+ if (this.activeShader === this.primitiveShader) {
29413
+ gl.drawArrays(mode, 0, vertexCount);
29414
+ } else {
29415
+ gl.drawElements(mode, vertexCount / vertex.quadSize * INDICES_PER_QUAD, gl.UNSIGNED_SHORT, 0);
29416
+ }
29320
29417
 
29321
- this.sbIndex = 0;
29322
- this.length = 0;
29418
+ // clear the vertex buffer
29419
+ vertex.clear();
29323
29420
  }
29324
29421
  }
29325
29422
 
@@ -29328,43 +29425,29 @@ class WebGLCompositor {
29328
29425
  * @name drawVertices
29329
29426
  * @memberOf me.WebGLCompositor
29330
29427
  * @function
29331
- * @param {GLENUM} [mode=gl.TRIANGLES] primitive type to render (gl.POINTS, gl.LINE_STRIP, gl.LINE_LOOP, gl.LINES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, gl.TRIANGLES)
29332
- * @param {me.Vector2d[]} [verts=[]] vertices
29428
+ * @param {GLENUM} mode primitive type to render (gl.POINTS, gl.LINE_STRIP, gl.LINE_LOOP, gl.LINES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, gl.TRIANGLES)
29429
+ * @param {me.Vector2d[]} verts vertices
29333
29430
  * @param {Number} [vertexCount=verts.length] amount of points defined in the points array
29334
29431
  */
29335
- drawVertices(mode, verts, vertexCount) {
29336
- var gl = this.gl;
29337
-
29338
- vertexCount = vertexCount || verts.length;
29339
-
29432
+ drawVertices(mode, verts, vertexCount = verts.length) {
29340
29433
  // use the primitive shader
29341
29434
  this.useShader(this.primitiveShader);
29342
-
29343
29435
  // Set the line color
29344
29436
  this.primitiveShader.setUniform("uColor", this.color);
29345
29437
 
29346
- // Put vertex data into the stream buffer
29347
- var offset = 0;
29348
29438
  var m = this.viewMatrix;
29439
+ var vertex = this.vertexBuffer;
29349
29440
  var m_isIdentity = m.isIdentity();
29441
+
29350
29442
  for (var i = 0; i < vertexCount; i++) {
29351
29443
  if (!m_isIdentity) {
29352
29444
  m.apply(verts[i]);
29353
29445
  }
29354
- this.stream[offset + 0] = verts[i].x;
29355
- this.stream[offset + 1] = verts[i].y;
29356
- offset += ELEMENT_SIZE;
29446
+ vertex.push(verts[i].x, verts[i].y);
29357
29447
  }
29358
29448
 
29359
- // Copy data into the stream buffer
29360
- gl.bufferData(
29361
- gl.ARRAY_BUFFER,
29362
- this.stream.subarray(0, vertexCount * ELEMENT_SIZE),
29363
- gl.STREAM_DRAW
29364
- );
29365
-
29366
- // Draw the stream buffer
29367
- gl.drawArrays(mode, 0, vertexCount);
29449
+ // flush
29450
+ this.flush(mode);
29368
29451
  }
29369
29452
 
29370
29453
  /**
@@ -29421,14 +29504,6 @@ class WebGLRenderer extends Renderer {
29421
29504
  // parent contructor
29422
29505
  super(options);
29423
29506
 
29424
- /**
29425
- * The WebGL context
29426
- * @name gl
29427
- * @memberOf me.WebGLRenderer
29428
- * type {WebGLRenderingContext}
29429
- */
29430
- this.context = this.gl = this.getContextGL(this.getScreenCanvas(), options.transparent);
29431
-
29432
29507
  /**
29433
29508
  * The WebGL version used by this renderer (1 or 2)
29434
29509
  * @name WebGLVersion
@@ -29437,7 +29512,7 @@ class WebGLRenderer extends Renderer {
29437
29512
  * @default 1
29438
29513
  * @readonly
29439
29514
  */
29440
- this.webGLVersion = 1;
29515
+ this.WebGLVersion = 1;
29441
29516
 
29442
29517
  /**
29443
29518
  * The vendor string of the underlying graphics driver.
@@ -29459,6 +29534,14 @@ class WebGLRenderer extends Renderer {
29459
29534
  */
29460
29535
  this.GPURenderer = null;
29461
29536
 
29537
+ /**
29538
+ * The WebGL context
29539
+ * @name gl
29540
+ * @memberOf me.WebGLRenderer
29541
+ * type {WebGLRenderingContext}
29542
+ */
29543
+ this.context = this.gl = this.getContextGL(this.getScreenCanvas(), options.transparent);
29544
+
29462
29545
  /**
29463
29546
  * Maximum number of texture unit supported under the current context
29464
29547
  * @name maxTextures
@@ -29735,14 +29818,18 @@ class WebGLRenderer extends Renderer {
29735
29818
  this.currentCompositor.uploadTexture(this.fontTexture, 0, 0, 0, true);
29736
29819
 
29737
29820
  // Add the new quad
29738
- var key = bounds.left + "," + bounds.top + "," + bounds.width + "," + bounds.height;
29821
+ var uvs = this.fontTexture.getUVs(bounds.left + "," + bounds.top + "," + bounds.width + "," + bounds.height);
29739
29822
  this.currentCompositor.addQuad(
29740
29823
  this.fontTexture,
29741
- key,
29742
29824
  bounds.left,
29743
29825
  bounds.top,
29744
29826
  bounds.width,
29745
- bounds.height
29827
+ bounds.height,
29828
+ uvs[0],
29829
+ uvs[1],
29830
+ uvs[2],
29831
+ uvs[3],
29832
+ this.currentTint.toUint32()
29746
29833
  );
29747
29834
 
29748
29835
  // Clear font context2D
@@ -29802,8 +29889,9 @@ class WebGLRenderer extends Renderer {
29802
29889
  dy |= 0;
29803
29890
  }
29804
29891
 
29805
- var key = sx + "," + sy + "," + sw + "," + sh;
29806
- this.currentCompositor.addQuad(this.cache.get(image), key, dx, dy, dw, dh);
29892
+ var texture = this.cache.get(image);
29893
+ var uvs = texture.getUVs(sx + "," + sy + "," + sw + "," + sh);
29894
+ this.currentCompositor.addQuad(texture, dx, dy, dw, dh, uvs[0], uvs[1], uvs[2], uvs[3], this.currentTint.toUint32());
29807
29895
  }
29808
29896
 
29809
29897
  /**
@@ -29819,8 +29907,8 @@ class WebGLRenderer extends Renderer {
29819
29907
  * @see me.WebGLRenderer#createPattern
29820
29908
  */
29821
29909
  drawPattern(pattern, x, y, width, height) {
29822
- var key = "0,0," + width + "," + height;
29823
- this.currentCompositor.addQuad(pattern, key, x, y, width, height);
29910
+ var uvs = pattern.getUVs("0,0," + width + "," + height);
29911
+ this.currentCompositor.addQuad(pattern, x, y, width, height, uvs[0], uvs[1], uvs[2], uvs[3], this.currentTint.toUint32());
29824
29912
  }
29825
29913
 
29826
29914
 
@@ -30034,7 +30122,7 @@ class WebGLRenderer extends Renderer {
30034
30122
  * @param {Number} alpha 0.0 to 1.0 values accepted.
30035
30123
  */
30036
30124
  setGlobalAlpha(a) {
30037
- this.currentColor.glArray[3] = a;
30125
+ this.currentColor.alpha = a;
30038
30126
  }
30039
30127
 
30040
30128
  /**
@@ -30046,9 +30134,9 @@ class WebGLRenderer extends Renderer {
30046
30134
  * @param {me.Color|String} color css color string.
30047
30135
  */
30048
30136
  setColor(color) {
30049
- var alpha = this.currentColor.glArray[3];
30137
+ var alpha = this.currentColor.alpha;
30050
30138
  this.currentColor.copy(color);
30051
- this.currentColor.glArray[3] *= alpha;
30139
+ this.currentColor.alpha *= alpha;
30052
30140
  }
30053
30141
 
30054
30142
  /**
@@ -30305,7 +30393,7 @@ class WebGLRenderer extends Renderer {
30305
30393
  }
30306
30394
 
30307
30395
  // calculate all vertices
30308
- for (i = 0; i < indices.length; i ++ ) {
30396
+ for (i = 0; i < indices.length; i++ ) {
30309
30397
  glPoints[i].set(x + points[indices[i]].x, y + points[indices[i]].y);
30310
30398
  }
30311
30399
 
@@ -30804,9 +30892,9 @@ function init(game_width, game_height, options) {
30804
30892
  },
30805
30893
  false
30806
30894
  );
30807
- if (typeof window.screen !== "undefined") {
30808
- // is this one required ?
30809
- window.screen.onorientationchange = function (e) {
30895
+
30896
+ if (device$1.ScreenOrientation === true) {
30897
+ window.screen.orientation.onchange = function (e) {
30810
30898
  emit(WINDOW_ONORIENTATION_CHANGE, e);
30811
30899
  };
30812
30900
  }
@@ -31445,10 +31533,10 @@ class BasePlugin {
31445
31533
  * this can be overridden by the plugin
31446
31534
  * @public
31447
31535
  * @type String
31448
- * @default "10.0.2"
31536
+ * @default "10.2.1"
31449
31537
  * @name me.plugin.Base#version
31450
31538
  */
31451
- this.version = "10.0.2";
31539
+ this.version = "10.2.1";
31452
31540
  }
31453
31541
  }
31454
31542
 
@@ -32481,7 +32569,7 @@ var toPX = [12, 24, 0.75, 1];
32481
32569
  * apply the current font style to the given context
32482
32570
  * @ignore
32483
32571
  */
32484
- var setContextStyle = function(context, font, stroke) {
32572
+ var setContextStyle = function(context, font, stroke = false) {
32485
32573
  context.font = font.font;
32486
32574
  context.fillStyle = font.fillStyle.toRGBA();
32487
32575
  if (stroke === true) {
@@ -32511,7 +32599,8 @@ var setContextStyle = function(context, font, stroke) {
32511
32599
  * @param {String} [settings.textBaseline="top"] the text baseline
32512
32600
  * @param {Number} [settings.lineHeight=1.0] line spacing height
32513
32601
  * @param {me.Vector2d} [settings.anchorPoint={x:0.0, y:0.0}] anchor point to draw the text at
32514
- * @param {(String|String[])} [settings.text] a string, or an array of strings
32602
+ * @param {Boolean} [settings.offScreenCanvas=false] whether to draw the font to an individual "cache" texture first
32603
+ * @param {(String|String[])} [settings.text=""] a string, or an array of strings
32515
32604
  * @example
32516
32605
  * var font = new me.Text(0, 0, {font: "Arial", size: 8, fillStyle: this.color});
32517
32606
  */
@@ -32602,6 +32691,17 @@ class Text extends Renderable {
32602
32691
  */
32603
32692
  this.lineHeight = settings.lineHeight || 1.0;
32604
32693
 
32694
+ /**
32695
+ * whether to draw the font to a indidividual offscreen canvas texture first <br>
32696
+ * Note: this will improve performances when using WebGL, but will impact
32697
+ * memory consumption as every text element will have its own canvas texture
32698
+ * @public
32699
+ * @type Boolean
32700
+ * @default false
32701
+ * @name me.Text#offScreenCanvas
32702
+ */
32703
+ this.offScreenCanvas = false;
32704
+
32605
32705
  /**
32606
32706
  * the text to be displayed
32607
32707
  * @private
@@ -32644,8 +32744,31 @@ class Text extends Renderable {
32644
32744
  this.italic();
32645
32745
  }
32646
32746
 
32747
+ if (settings.offScreenCanvas === true) {
32748
+ this.offScreenCanvas = true;
32749
+ this.canvas = createCanvas(2, 2, true);
32750
+ this.context = this.canvas.getContext("2d");
32751
+ }
32752
+
32647
32753
  // set the text
32648
32754
  this.setText(settings.text);
32755
+
32756
+ // force update bounds on object creation
32757
+ this.update(0);
32758
+ }
32759
+
32760
+ /** @ignore */
32761
+ onDeactivateEvent() {
32762
+ // free the canvas and potential corresponding texture when deactivated
32763
+ if (this.offScreenCanvas === true) {
32764
+ if (renderer instanceof WebGLRenderer) {
32765
+ renderer.currentCompositor.unbindTexture2D(renderer.cache.get(this.canvas));
32766
+ renderer.cache.remove(this.canvas);
32767
+ }
32768
+ this.canvas.width = this.canvas.height = 0;
32769
+ this.context = undefined;
32770
+ this.canvas = undefined;
32771
+ }
32649
32772
  }
32650
32773
 
32651
32774
  /**
@@ -32726,11 +32849,7 @@ class Text extends Renderable {
32726
32849
  * @param {Number|String|String[]} value a string, or an array of strings
32727
32850
  * @return this object for chaining
32728
32851
  */
32729
- setText(value) {
32730
- if (typeof value === "undefined") {
32731
- value = "";
32732
- }
32733
-
32852
+ setText(value = "") {
32734
32853
  if (this._text.toString() !== value.toString()) {
32735
32854
  if (!Array.isArray(value)) {
32736
32855
  this._text = ("" + value).split("\n");
@@ -32748,28 +32867,25 @@ class Text extends Renderable {
32748
32867
  * @name measureText
32749
32868
  * @memberOf me.Text.prototype
32750
32869
  * @function
32751
- * @param {me.CanvasRenderer|me.WebGLRenderer} [renderer] reference a renderer instance
32870
+ * @param {me.CanvasRenderer|me.WebGLRenderer} [renderer] reference to the active renderer
32752
32871
  * @param {String} [text] the text to be measured
32753
32872
  * @param {me.Rect|me.Bounds} [ret] a object in which to store the text metrics
32754
32873
  * @returns {TextMetrics} a TextMetrics object with two properties: `width` and `height`, defining the output dimensions
32755
32874
  */
32756
32875
  measureText(_renderer, text, ret) {
32757
32876
  var context;
32877
+ var textMetrics = ret || this.getBounds();
32878
+ var lineHeight = this.fontSize * this.lineHeight;
32879
+ var strings = typeof text !== "undefined" ? ("" + (text)).split("\n") : this._text;
32758
32880
 
32759
- if (typeof _renderer === "undefined") {
32760
- context = renderer.getFontContext();
32881
+ if (this.offScreenCanvas === true) {
32882
+ context = this.context;
32761
32883
  } else if (_renderer instanceof Renderer) {
32762
32884
  context = _renderer.getFontContext();
32763
32885
  } else {
32764
- // else it's a 2d rendering context object
32765
- context = _renderer;
32886
+ context = renderer.getFontContext();
32766
32887
  }
32767
32888
 
32768
- var textMetrics = ret || this.getBounds();
32769
- var lineHeight = this.fontSize * this.lineHeight;
32770
-
32771
- var strings = typeof text !== "undefined" ? ("" + (text)).split("\n") : this._text;
32772
-
32773
32889
  // save the previous context
32774
32890
  context.save();
32775
32891
 
@@ -32805,7 +32921,33 @@ class Text extends Renderable {
32805
32921
  */
32806
32922
  update(/* dt */) {
32807
32923
  if (this.isDirty === true) {
32808
- this.measureText();
32924
+ var bounds = this.measureText(renderer);
32925
+ if (this.offScreenCanvas === true) {
32926
+ var width = Math.round(bounds.width),
32927
+ height = Math.round(bounds.height);
32928
+
32929
+ if (renderer instanceof WebGLRenderer) {
32930
+ // invalidate the previous corresponding texture so that it can reuploaded once changed
32931
+ renderer.currentCompositor.unbindTexture2D(renderer.cache.get(this.canvas));
32932
+
32933
+ if (renderer.WebGLVersion === 1) {
32934
+ // round size to next Pow2
32935
+ width = nextPowerOfTwo(bounds.width);
32936
+ height = nextPowerOfTwo(bounds.height);
32937
+ }
32938
+ }
32939
+
32940
+ // resize the cache canvas if necessary
32941
+ if (this.canvas.width < width || this.canvas.height < height) {
32942
+ this.canvas.width = width;
32943
+ this.canvas.height = height;
32944
+ // resizing the canvas will automatically clear its content
32945
+ } else {
32946
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
32947
+ }
32948
+ this._drawFont(this.context, this._text, this.pos.x - bounds.x, this.pos.y - bounds.y, false);
32949
+
32950
+ }
32809
32951
  }
32810
32952
  return this.isDirty;
32811
32953
  }
@@ -32855,7 +32997,12 @@ class Text extends Renderable {
32855
32997
  }
32856
32998
 
32857
32999
  // draw the text
32858
- renderer.drawFont(this._drawFont(renderer.getFontContext(), this._text, x, y, stroke || false));
33000
+ if (this.offScreenCanvas === true) {
33001
+ renderer.drawImage(this.canvas, this.getBounds().x, this.getBounds().y);
33002
+ } else {
33003
+ renderer.drawFont(this._drawFont(renderer.getFontContext(), this._text, x, y, stroke));
33004
+ }
33005
+
32859
33006
 
32860
33007
  // for backward compatibilty
32861
33008
  if (typeof this.ancestor === "undefined") {
@@ -32887,7 +33034,7 @@ class Text extends Renderable {
32887
33034
  /**
32888
33035
  * @ignore
32889
33036
  */
32890
- _drawFont(context, text, x, y, stroke) {
33037
+ _drawFont(context, text, x, y, stroke = false) {
32891
33038
  setContextStyle(context, this, stroke);
32892
33039
 
32893
33040
  var lineHeight = this.fontSize * this.lineHeight;
@@ -33793,6 +33940,8 @@ class ImageLayer extends Sprite {
33793
33940
  else {
33794
33941
  this.pos.y = y;
33795
33942
  }
33943
+
33944
+ this.isDirty = true;
33796
33945
  }
33797
33946
 
33798
33947
  /*
@@ -33860,6 +34009,214 @@ class ImageLayer extends Sprite {
33860
34009
 
33861
34010
  }
33862
34011
 
34012
+ /**
34013
+ * @classdesc
34014
+ * A NineSliceSprite is similar to a Sprite, but it uses 9-slice scaling to strech its inner area to fit the size of the Renderable,
34015
+ * by proportionally scaling a sprite by splitting it in a grid of nine parts (with only parts 1, 3, 7, 9 not being scaled). <br>
34016
+ * <img src="images/9-slice-scaling.png"/><br>
34017
+ * @see https://en.wikipedia.org/wiki/9-slice_scaling
34018
+ * @class NineSliceSprite
34019
+ * @extends me.Sprite
34020
+ * @memberOf me
34021
+ * @constructor
34022
+ * @param {Number} x the x coordinates of the sprite object
34023
+ * @param {Number} y the y coordinates of the sprite object
34024
+ * @param {Object} settings Configuration parameters for the Sprite object
34025
+ * @param {Number} settings.width the width of the Renderable over which the sprite needs to be stretched
34026
+ * @param {Number} settings.height the height of the Renderable over which the sprite needs to be stretched
34027
+ * @param {me.Renderer.Texture|HTMLImageElement|HTMLCanvasElement|String} settings.image reference to a texture, spritesheet image or to a texture atlas
34028
+ * @param {String} [settings.name=""] name of this object
34029
+ * @param {String} [settings.region] region name of a specific region to use when using a texture atlas, see {@link me.Renderer.Texture}
34030
+ * @param {Number} [settings.framewidth] Width of a single frame within the spritesheet
34031
+ * @param {Number} [settings.frameheight] Height of a single frame within the spritesheet
34032
+ * @param {String|me.Color} [settings.tint] a tint to be applied to this sprite
34033
+ * @param {Number} [settings.flipX] flip the sprite on the horizontal axis
34034
+ * @param {Number} [settings.flipY] flip the sprite on the vertical axis
34035
+ * @param {me.Vector2d} [settings.anchorPoint={x:0.5, y:0.5}] Anchor point to draw the frame at (defaults to the center of the frame).
34036
+ * @example
34037
+ * this.panelSprite = new me.NineSliceSprite(0, 0, {
34038
+ * image : game.texture,
34039
+ * region : "grey_panel",
34040
+ * width : this.width,
34041
+ * height : this.height
34042
+ * });
34043
+ */
34044
+
34045
+ class NineSliceSprite extends Sprite {
34046
+
34047
+ /**
34048
+ * @ignore
34049
+ */
34050
+ constructor(x, y, settings) {
34051
+ // call the super constructor
34052
+ super(x, y, settings);
34053
+
34054
+ // ensure mandatory properties are defined
34055
+ if ((typeof settings.width !== "number") || (typeof settings.height !== "number")) {
34056
+ throw new Error("height and width properties are mandatory");
34057
+ }
34058
+
34059
+ // override the renderable sprite with the given one
34060
+ // resize based on the active frame
34061
+ this.width = settings.width;
34062
+ this.height = settings.height;
34063
+ }
34064
+
34065
+ /**
34066
+ * @ignore
34067
+ */
34068
+ draw(renderer) {
34069
+ // the frame to draw
34070
+ var frame = this.current;
34071
+
34072
+ // cache the current position and size
34073
+ var dx = this.pos.x,
34074
+ dy = this.pos.y;
34075
+
34076
+ var w = frame.width,
34077
+ h = frame.height;
34078
+
34079
+ // frame offset in the texture/atlas
34080
+ var frame_offset = frame.offset;
34081
+ var g_offset = this.offset;
34082
+
34083
+
34084
+ // remove image's TexturePacker/ShoeBox rotation
34085
+ if (frame.angle !== 0) {
34086
+ renderer.translate(-dx, -dy);
34087
+ renderer.rotate(frame.angle);
34088
+ dx -= h;
34089
+ w = frame.height;
34090
+ h = frame.width;
34091
+ }
34092
+
34093
+ var sx = g_offset.x + frame_offset.x,
34094
+ sy = g_offset.y + frame_offset.y;
34095
+
34096
+ // should this be configurable ?
34097
+ var corner_width = frame.width / 4,
34098
+ corner_height = frame.height / 4;
34099
+
34100
+ // OPTIMIZE ME !
34101
+
34102
+ // DRAW CORNERS
34103
+
34104
+ // Top Left
34105
+ renderer.drawImage(
34106
+ this.image,
34107
+ sx, // sx
34108
+ sy, // sy
34109
+ corner_width, corner_height, // sw,sh
34110
+ dx, dy, // dx,dy
34111
+ corner_width, corner_height // dw,dh
34112
+ );
34113
+
34114
+ // Top Right
34115
+ renderer.drawImage(
34116
+ this.image,
34117
+ sx + w - corner_width, // sx
34118
+ sy, // sy
34119
+ corner_width, corner_height, // sw,sh
34120
+ dx + this.width - corner_width, // dx
34121
+ dy, // dy
34122
+ corner_width, corner_height // dw,dh
34123
+ );
34124
+ // Bottom Left
34125
+ renderer.drawImage(
34126
+ this.image,
34127
+ sx, // sx
34128
+ sy + h - corner_height, // sy
34129
+ corner_width, corner_height, // sw,sh
34130
+ dx, // dx
34131
+ dy + this.height - corner_height, // dy
34132
+ corner_width, corner_height // dw,dh
34133
+ );
34134
+ // Bottom Right
34135
+ renderer.drawImage(
34136
+ this.image,
34137
+ sx + w - corner_width, // sx
34138
+ sy + h - corner_height, // sy
34139
+ corner_width, corner_height, // sw,sh
34140
+ dx + this.width - corner_width, //dx
34141
+ dy + this.height - corner_height, // dy
34142
+ corner_width, corner_height // dw,dh
34143
+ );
34144
+
34145
+
34146
+ // DRAW SIDES and CENTER
34147
+ var image_center_width = w - (corner_width << 1);
34148
+ var image_center_height = h - (corner_height << 1);
34149
+
34150
+ var target_center_width = this.width - (corner_width << 1);
34151
+ var target_center_height = this.height - (corner_height << 1);
34152
+
34153
+ //Top center
34154
+ renderer.drawImage(
34155
+ this.image,
34156
+ sx + corner_width, // sx
34157
+ sy, // sy
34158
+ image_center_width, // sw
34159
+ corner_height, // sh
34160
+ dx + corner_width, // dx
34161
+ dy, // dy
34162
+ target_center_width, // dw
34163
+ corner_height // dh
34164
+ );
34165
+
34166
+ //Bottom center
34167
+ renderer.drawImage(
34168
+ this.image,
34169
+ sx + corner_width, // sx
34170
+ sy + h - corner_height, // sy
34171
+ image_center_width, // sw
34172
+ corner_height, // sh
34173
+ dx + corner_width, // dx
34174
+ dy + this.height - corner_height, // dx
34175
+ target_center_width, // dw
34176
+ corner_height // dh
34177
+ );
34178
+
34179
+ // Middle Left
34180
+ renderer.drawImage(
34181
+ this.image,
34182
+ sx, // sx
34183
+ sy + corner_height, // sy
34184
+ corner_width, // sw
34185
+ image_center_height, // sh
34186
+ dx, // dx
34187
+ dy + corner_height, // dy
34188
+ corner_width, // dw
34189
+ target_center_height // dh
34190
+ );
34191
+
34192
+ // Middle Right
34193
+ renderer.drawImage(
34194
+ this.image,
34195
+ sx + w - corner_width, // sx
34196
+ sy + corner_height, // sy
34197
+ corner_width, // sw
34198
+ image_center_height, // sh
34199
+ dx + this.width - corner_width, // dx
34200
+ dy + corner_height, // dy
34201
+ corner_width, // dw
34202
+ target_center_height // dh
34203
+ );
34204
+
34205
+ // Middle Center
34206
+ renderer.drawImage(
34207
+ this.image,
34208
+ sx + corner_width, // sx
34209
+ sy + corner_height, // sy
34210
+ image_center_width, // sw
34211
+ image_center_height, // sh
34212
+ dx + corner_width, // dx
34213
+ dy + corner_height, // dy
34214
+ target_center_width, // dw
34215
+ target_center_height // dh
34216
+ );
34217
+ }
34218
+ }
34219
+
33863
34220
  /**
33864
34221
  * @classdesc
33865
34222
  * GUI Object<br>
@@ -35688,7 +36045,7 @@ var deprecated = /*#__PURE__*/Object.freeze({
35688
36045
  * @name version
35689
36046
  * @type {string}
35690
36047
  */
35691
- const version = "10.0.2";
36048
+ const version = "10.2.1";
35692
36049
 
35693
36050
 
35694
36051
  /**
@@ -35733,6 +36090,7 @@ function boot() {
35733
36090
  pool.register("me.Color", Color, true);
35734
36091
  pool.register("me.Particle", Particle, true);
35735
36092
  pool.register("me.Sprite", Sprite);
36093
+ pool.register("me.NineSliceSprite", NineSliceSprite);
35736
36094
  pool.register("me.Renderable", Renderable);
35737
36095
  pool.register("me.Text", Text, true);
35738
36096
  pool.register("me.BitmapText", BitmapText);
@@ -35759,6 +36117,7 @@ function boot() {
35759
36117
  pool.register("Color", Color, true);
35760
36118
  pool.register("Particle", Particle, true);
35761
36119
  pool.register("Sprite", Sprite);
36120
+ pool.register("NineSliceSprite", NineSliceSprite);
35762
36121
  pool.register("Renderable", Renderable);
35763
36122
  pool.register("Text", Text, true);
35764
36123
  pool.register("BitmapText", BitmapText);
@@ -35796,4 +36155,4 @@ device$1.onReady(function () {
35796
36155
  }
35797
36156
  });
35798
36157
 
35799
- export { BitmapText, BitmapTextData, Body, Bounds$1 as Bounds, Camera2d, CanvasRenderer, Collectable, Color, ColorLayer, Container, DraggableEntity, DroptargetEntity, Ellipse, Entity, GLShader, GUI_Object, ImageLayer, Line, math as Math, Matrix2d, Matrix3d, ObservableVector2d, ObservableVector3d, Particle, ParticleEmitter, ParticleEmitterSettings, Pointer, Polygon, QuadTree, Rect, Renderable, Renderer, Sprite, Stage, TMXHexagonalRenderer, TMXIsometricRenderer, TMXLayer, TMXOrthogonalRenderer, TMXRenderer, TMXStaggeredRenderer, TMXTileMap, TMXTileset, TMXTilesetGroup, Text, Tile, Trigger, Tween, Vector2d, Vector3d, WebGLCompositor, WebGLRenderer, World, audio, boot, collision, deprecated, device$1 as device, event, game, initialized, input, level, loader, plugin, plugins, pool, save, skipAutoInit, state, timer$1 as timer, utils, version, video };
36158
+ export { BitmapText, BitmapTextData, Body, Bounds$1 as Bounds, Camera2d, CanvasRenderer, Collectable, Color, ColorLayer, Container, DraggableEntity, DroptargetEntity, Ellipse, Entity, GLShader, GUI_Object, ImageLayer, Line, math as Math, Matrix2d, Matrix3d, NineSliceSprite, ObservableVector2d, ObservableVector3d, Particle, ParticleEmitter, ParticleEmitterSettings, Pointer, Polygon, QuadTree, Rect, Renderable, Renderer, Sprite, Stage, TMXHexagonalRenderer, TMXIsometricRenderer, TMXLayer, TMXOrthogonalRenderer, TMXRenderer, TMXStaggeredRenderer, TMXTileMap, TMXTileset, TMXTilesetGroup, Text, Tile, Trigger, Tween, Vector2d, Vector3d, WebGLCompositor, WebGLRenderer, World, audio, boot, collision, deprecated, device$1 as device, event, game, initialized, input, level, loader, plugin, plugins, pool, save, skipAutoInit, state, timer$1 as timer, utils, version, video };