melonjs 14.0.2 → 14.1.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.
Files changed (219) hide show
  1. package/README.md +2 -0
  2. package/dist/melonjs.mjs/_virtual/_commonjsHelpers.js +10 -0
  3. package/dist/melonjs.mjs/_virtual/arraymultimap.js +10 -0
  4. package/dist/melonjs.mjs/_virtual/earcut.js +10 -0
  5. package/dist/melonjs.mjs/_virtual/howler.js +10 -0
  6. package/dist/melonjs.mjs/_virtual/index.js +10 -0
  7. package/dist/melonjs.mjs/_virtual/index2.js +10 -0
  8. package/dist/melonjs.mjs/_virtual/multimap.js +10 -0
  9. package/dist/melonjs.mjs/_virtual/setmultimap.js +10 -0
  10. package/dist/melonjs.mjs/application/application.js +238 -0
  11. package/dist/melonjs.mjs/audio/audio.js +536 -0
  12. package/dist/melonjs.mjs/camera/camera2d.js +731 -0
  13. package/dist/melonjs.mjs/entity/entity.js +247 -0
  14. package/dist/melonjs.mjs/game.js +29 -0
  15. package/dist/melonjs.mjs/geometries/ellipse.js +274 -0
  16. package/dist/melonjs.mjs/geometries/line.js +115 -0
  17. package/dist/melonjs.mjs/geometries/path2d.js +318 -0
  18. package/dist/melonjs.mjs/geometries/point.js +88 -0
  19. package/dist/melonjs.mjs/geometries/poly.js +498 -0
  20. package/dist/melonjs.mjs/geometries/rectangle.js +374 -0
  21. package/dist/melonjs.mjs/geometries/roundrect.js +167 -0
  22. package/dist/melonjs.mjs/index.js +248 -0
  23. package/dist/melonjs.mjs/input/gamepad.js +501 -0
  24. package/dist/melonjs.mjs/input/input.js +26 -0
  25. package/dist/melonjs.mjs/input/keyboard.js +470 -0
  26. package/dist/melonjs.mjs/input/pointer.js +393 -0
  27. package/dist/melonjs.mjs/input/pointerevent.js +818 -0
  28. package/dist/melonjs.mjs/lang/deprecated.js +157 -0
  29. package/dist/melonjs.mjs/level/level.js +297 -0
  30. package/dist/melonjs.mjs/level/tiled/TMXGroup.js +141 -0
  31. package/dist/melonjs.mjs/level/tiled/TMXLayer.js +446 -0
  32. package/dist/melonjs.mjs/level/tiled/TMXObject.js +355 -0
  33. package/dist/melonjs.mjs/level/tiled/TMXTile.js +193 -0
  34. package/dist/melonjs.mjs/level/tiled/TMXTileMap.js +636 -0
  35. package/dist/melonjs.mjs/level/tiled/TMXTileset.js +309 -0
  36. package/dist/melonjs.mjs/level/tiled/TMXTilesetGroup.js +81 -0
  37. package/dist/melonjs.mjs/level/tiled/TMXUtils.js +367 -0
  38. package/dist/melonjs.mjs/level/tiled/renderer/TMXHexagonalRenderer.js +504 -0
  39. package/dist/melonjs.mjs/level/tiled/renderer/TMXIsometricRenderer.js +218 -0
  40. package/dist/melonjs.mjs/level/tiled/renderer/TMXOrthogonalRenderer.js +155 -0
  41. package/dist/melonjs.mjs/level/tiled/renderer/TMXRenderer.js +124 -0
  42. package/dist/melonjs.mjs/level/tiled/renderer/TMXStaggeredRenderer.js +107 -0
  43. package/dist/melonjs.mjs/loader/loader.js +801 -0
  44. package/dist/melonjs.mjs/loader/loadingscreen.js +120 -0
  45. package/dist/melonjs.mjs/loader/melonjs_logo.png.js +11 -0
  46. package/dist/melonjs.mjs/math/color.js +616 -0
  47. package/dist/melonjs.mjs/math/math.js +218 -0
  48. package/dist/melonjs.mjs/math/matrix2.js +501 -0
  49. package/dist/melonjs.mjs/math/matrix3.js +679 -0
  50. package/dist/melonjs.mjs/math/observable_vector2.js +469 -0
  51. package/dist/melonjs.mjs/math/observable_vector3.js +559 -0
  52. package/dist/melonjs.mjs/math/vector2.js +526 -0
  53. package/dist/melonjs.mjs/math/vector3.js +567 -0
  54. package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/arraymultimap.js +73 -0
  55. package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/index.js +21 -0
  56. package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/multimap.js +324 -0
  57. package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/setmultimap.js +69 -0
  58. package/dist/melonjs.mjs/node_modules/earcut/src/earcut.js +691 -0
  59. package/dist/melonjs.mjs/node_modules/eventemitter3/index.js +350 -0
  60. package/dist/melonjs.mjs/node_modules/howler/dist/howler.js +3241 -0
  61. package/dist/melonjs.mjs/particles/emitter.js +265 -0
  62. package/dist/melonjs.mjs/particles/particle.js +186 -0
  63. package/dist/melonjs.mjs/particles/settings.js +319 -0
  64. package/dist/melonjs.mjs/physics/body.js +702 -0
  65. package/dist/melonjs.mjs/physics/bounds.js +459 -0
  66. package/dist/melonjs.mjs/physics/collision.js +132 -0
  67. package/dist/melonjs.mjs/physics/detector.js +194 -0
  68. package/dist/melonjs.mjs/physics/quadtree.js +394 -0
  69. package/dist/melonjs.mjs/physics/response.js +57 -0
  70. package/dist/melonjs.mjs/physics/sat.js +483 -0
  71. package/dist/melonjs.mjs/physics/world.js +219 -0
  72. package/dist/melonjs.mjs/plugin/plugin.js +141 -0
  73. package/dist/melonjs.mjs/renderable/collectable.js +60 -0
  74. package/dist/melonjs.mjs/renderable/colorlayer.js +78 -0
  75. package/dist/melonjs.mjs/renderable/container.js +1016 -0
  76. package/dist/melonjs.mjs/renderable/dragndrop.js +224 -0
  77. package/dist/melonjs.mjs/renderable/imagelayer.js +305 -0
  78. package/dist/melonjs.mjs/renderable/light2d.js +155 -0
  79. package/dist/melonjs.mjs/renderable/nineslicesprite.js +246 -0
  80. package/dist/melonjs.mjs/renderable/renderable.js +781 -0
  81. package/dist/melonjs.mjs/renderable/sprite.js +653 -0
  82. package/dist/melonjs.mjs/renderable/trigger.js +156 -0
  83. package/dist/melonjs.mjs/renderable/ui/uibaseelement.js +212 -0
  84. package/dist/melonjs.mjs/renderable/ui/uispriteelement.js +225 -0
  85. package/dist/melonjs.mjs/renderable/ui/uitextbutton.js +127 -0
  86. package/dist/melonjs.mjs/state/stage.js +236 -0
  87. package/dist/melonjs.mjs/state/state.js +596 -0
  88. package/dist/melonjs.mjs/system/device.js +909 -0
  89. package/dist/melonjs.mjs/system/dom.js +78 -0
  90. package/dist/melonjs.mjs/system/event.js +537 -0
  91. package/dist/melonjs.mjs/system/platform.js +41 -0
  92. package/dist/melonjs.mjs/system/pooling.js +209 -0
  93. package/dist/melonjs.mjs/system/save.js +157 -0
  94. package/dist/melonjs.mjs/system/timer.js +286 -0
  95. package/dist/melonjs.mjs/text/bitmaptext.js +363 -0
  96. package/dist/melonjs.mjs/text/bitmaptextdata.js +198 -0
  97. package/dist/melonjs.mjs/text/glyph.js +65 -0
  98. package/dist/melonjs.mjs/text/text.js +452 -0
  99. package/dist/melonjs.mjs/text/textmetrics.js +175 -0
  100. package/dist/melonjs.mjs/text/textstyle.js +23 -0
  101. package/dist/melonjs.mjs/tweens/easing.js +336 -0
  102. package/dist/melonjs.mjs/tweens/interpolation.js +112 -0
  103. package/dist/melonjs.mjs/tweens/tween.js +479 -0
  104. package/dist/melonjs.mjs/utils/agent.js +76 -0
  105. package/dist/melonjs.mjs/utils/array.js +63 -0
  106. package/dist/melonjs.mjs/utils/file.js +42 -0
  107. package/dist/melonjs.mjs/utils/function.js +70 -0
  108. package/dist/melonjs.mjs/utils/string.js +82 -0
  109. package/dist/melonjs.mjs/utils/utils.js +173 -0
  110. package/dist/melonjs.mjs/video/canvas/canvas_renderer.js +806 -0
  111. package/dist/melonjs.mjs/video/renderer.js +410 -0
  112. package/dist/melonjs.mjs/video/texture/atlas.js +519 -0
  113. package/dist/melonjs.mjs/video/texture/cache.js +143 -0
  114. package/dist/melonjs.mjs/video/texture/canvas_texture.js +144 -0
  115. package/dist/melonjs.mjs/video/video.js +462 -0
  116. package/dist/melonjs.mjs/video/webgl/buffer/vertex.js +142 -0
  117. package/dist/melonjs.mjs/video/webgl/glshader.js +167 -0
  118. package/dist/melonjs.mjs/video/webgl/shaders/primitive.frag.js +10 -0
  119. package/dist/melonjs.mjs/video/webgl/shaders/primitive.vert.js +10 -0
  120. package/dist/melonjs.mjs/video/webgl/shaders/quad.frag.js +10 -0
  121. package/dist/melonjs.mjs/video/webgl/shaders/quad.vert.js +10 -0
  122. package/dist/melonjs.mjs/video/webgl/utils/attributes.js +25 -0
  123. package/dist/melonjs.mjs/video/webgl/utils/precision.js +20 -0
  124. package/dist/melonjs.mjs/video/webgl/utils/program.js +67 -0
  125. package/dist/melonjs.mjs/video/webgl/utils/string.js +25 -0
  126. package/dist/melonjs.mjs/video/webgl/utils/uniforms.js +92 -0
  127. package/dist/melonjs.mjs/video/webgl/webgl_compositor.js +494 -0
  128. package/dist/melonjs.mjs/video/webgl/webgl_renderer.js +1035 -0
  129. package/dist/melonjs.module.d.ts +1298 -1359
  130. package/dist/melonjs.module.js +2072 -3520
  131. package/package.json +21 -16
  132. package/src/application/application.js +4 -5
  133. package/src/audio/audio.js +32 -32
  134. package/src/camera/camera2d.js +32 -33
  135. package/src/entity/entity.js +18 -19
  136. package/src/geometries/ellipse.js +17 -18
  137. package/src/geometries/line.js +6 -7
  138. package/src/geometries/path2d.js +33 -34
  139. package/src/geometries/point.js +1 -2
  140. package/src/geometries/poly.js +16 -18
  141. package/src/geometries/rectangle.js +19 -20
  142. package/src/geometries/roundrect.js +9 -10
  143. package/src/input/gamepad.js +15 -15
  144. package/src/input/keyboard.js +12 -12
  145. package/src/input/pointer.js +6 -6
  146. package/src/input/pointerevent.js +12 -12
  147. package/src/lang/deprecated.js +12 -12
  148. package/src/level/level.js +25 -25
  149. package/src/level/tiled/TMXLayer.js +23 -24
  150. package/src/level/tiled/TMXTile.js +6 -7
  151. package/src/level/tiled/TMXTileMap.js +8 -10
  152. package/src/level/tiled/TMXTileset.js +3 -4
  153. package/src/level/tiled/TMXTilesetGroup.js +1 -2
  154. package/src/level/tiled/TMXUtils.js +5 -5
  155. package/src/level/tiled/renderer/TMXHexagonalRenderer.js +3 -4
  156. package/src/level/tiled/renderer/TMXIsometricRenderer.js +3 -4
  157. package/src/level/tiled/renderer/TMXOrthogonalRenderer.js +2 -3
  158. package/src/level/tiled/renderer/TMXRenderer.js +20 -21
  159. package/src/level/tiled/renderer/TMXStaggeredRenderer.js +1 -2
  160. package/src/loader/loader.js +20 -20
  161. package/src/math/color.js +21 -22
  162. package/src/math/math.js +16 -16
  163. package/src/math/matrix2.js +17 -18
  164. package/src/math/matrix3.js +26 -27
  165. package/src/math/observable_vector2.js +15 -16
  166. package/src/math/observable_vector3.js +17 -18
  167. package/src/math/vector2.js +10 -11
  168. package/src/math/vector3.js +11 -12
  169. package/src/particles/emitter.js +7 -8
  170. package/src/particles/particle.js +3 -4
  171. package/src/physics/body.js +29 -30
  172. package/src/physics/bounds.js +10 -10
  173. package/src/physics/collision.js +2 -2
  174. package/src/physics/detector.js +6 -6
  175. package/src/physics/quadtree.js +18 -23
  176. package/src/physics/sat.js +31 -31
  177. package/src/physics/world.js +6 -7
  178. package/src/plugin/plugin.js +5 -5
  179. package/src/renderable/collectable.js +4 -6
  180. package/src/renderable/colorlayer.js +6 -8
  181. package/src/renderable/container.js +25 -27
  182. package/src/renderable/dragndrop.js +14 -14
  183. package/src/renderable/imagelayer.js +14 -15
  184. package/src/renderable/light2d.js +4 -5
  185. package/src/renderable/nineslicesprite.js +17 -18
  186. package/src/renderable/renderable.js +26 -28
  187. package/src/renderable/sprite.js +29 -30
  188. package/src/renderable/trigger.js +16 -17
  189. package/src/renderable/ui/uibaseelement.js +8 -9
  190. package/src/renderable/ui/uispriteelement.js +8 -8
  191. package/src/renderable/ui/uitextbutton.js +15 -15
  192. package/src/state/stage.js +8 -9
  193. package/src/state/state.js +17 -17
  194. package/src/system/device.js +11 -11
  195. package/src/system/event.js +10 -10
  196. package/src/system/pooling.js +9 -9
  197. package/src/system/save.js +2 -2
  198. package/src/system/timer.js +10 -10
  199. package/src/text/bitmaptext.js +19 -20
  200. package/src/text/bitmaptextdata.js +3 -4
  201. package/src/text/glyph.js +1 -2
  202. package/src/text/text.js +24 -25
  203. package/src/text/textmetrics.js +9 -10
  204. package/src/tweens/tween.js +20 -21
  205. package/src/utils/agent.js +5 -5
  206. package/src/utils/array.js +4 -4
  207. package/src/utils/file.js +2 -2
  208. package/src/utils/function.js +6 -6
  209. package/src/utils/string.js +5 -5
  210. package/src/utils/utils.js +4 -4
  211. package/src/video/canvas/canvas_renderer.js +72 -73
  212. package/src/video/renderer.js +27 -28
  213. package/src/video/texture/atlas.js +22 -22
  214. package/src/video/texture/canvas_texture.js +9 -9
  215. package/src/video/video.js +17 -17
  216. package/src/video/webgl/buffer/vertex.js +1 -2
  217. package/src/video/webgl/glshader.js +12 -12
  218. package/src/video/webgl/webgl_compositor.js +42 -43
  219. package/src/video/webgl/webgl_renderer.js +76 -77
@@ -0,0 +1,781 @@
1
+ /*!
2
+ * melonJS Game Engine - v14.1.1
3
+ * http://www.melonjs.org
4
+ * melonjs is licensed under the MIT License.
5
+ * http://www.opensource.org/licenses/mit-license
6
+ * @copyright (C) 2011 - 2022 Olivier Biot (AltByte Pte Ltd)
7
+ */
8
+ import ObservableVector2d from '../math/observable_vector2.js';
9
+ import ObservableVector3d from '../math/observable_vector3.js';
10
+ import Rect from '../geometries/rectangle.js';
11
+ import pool from '../system/pooling.js';
12
+ import { clamp } from '../math/math.js';
13
+ import Color from '../math/color.js';
14
+ import { releaseAllPointerEvents } from '../input/pointerevent.js';
15
+
16
+ /**
17
+ * @classdesc
18
+ * A base class for renderable objects.
19
+ * @augments Rect
20
+ */
21
+ class Renderable extends Rect {
22
+ /**
23
+ * @param {number} x - position of the renderable object (accessible through inherited pos.x property)
24
+ * @param {number} y - position of the renderable object (accessible through inherited pos.y property)
25
+ * @param {number} width - object width
26
+ * @param {number} height - object height
27
+ */
28
+ constructor(x, y, width, height) {
29
+
30
+ // parent constructor
31
+ super(x, y, width, height);
32
+
33
+ /**
34
+ * to identify the object as a renderable object
35
+ * @ignore
36
+ */
37
+ this.isRenderable = true;
38
+
39
+ /**
40
+ * If true then physic collision and input events will not impact this renderable
41
+ * @type {boolean}
42
+ * @default true
43
+ */
44
+ this.isKinematic = true;
45
+
46
+ /**
47
+ * the renderable physic body
48
+ * @type {Body}
49
+ * @example
50
+ * // define a new Player Class
51
+ * class PlayerEntity extends me.Sprite {
52
+ * // constructor
53
+ * constructor(x, y, settings) {
54
+ * // call the parent constructor
55
+ * super(x, y , settings);
56
+ *
57
+ * // define a basic walking animation
58
+ * this.addAnimation("walk", [...]);
59
+ * // define a standing animation (using the first frame)
60
+ * this.addAnimation("stand", [...]);
61
+ * // set the standing animation as default
62
+ * this.setCurrentAnimation("stand");
63
+ *
64
+ * // add a physic body
65
+ * this.body = new me.Body(this);
66
+ * // add a default collision shape
67
+ * this.body.addShape(new me.Rect(0, 0, this.width, this.height));
68
+ * // configure max speed, friction, and initial force to be applied
69
+ * this.body.setMaxVelocity(3, 15);
70
+ * this.body.setFriction(0.4, 0);
71
+ * this.body.force.set(3, 0);
72
+ *
73
+ * // set the display to follow our position on both axis
74
+ * me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH);
75
+ * }
76
+ *
77
+ * ...
78
+ *
79
+ * }
80
+ */
81
+ this.body = undefined;
82
+
83
+ if (typeof this.currentTransform === "undefined") {
84
+ /**
85
+ * the renderable default transformation matrix
86
+ * @type {Matrix2d}
87
+ */
88
+ this.currentTransform = pool.pull("Matrix2d");
89
+ }
90
+ this.currentTransform.identity();
91
+
92
+ /**
93
+ * (G)ame (U)nique (Id)entifier" <br>
94
+ * a GUID will be allocated for any renderable object added <br>
95
+ * to an object container (including the `me.game.world` container)
96
+ * @type {string}
97
+ */
98
+ this.GUID = undefined;
99
+
100
+ /**
101
+ * an event handler that is called when the renderable leave or enter a camera viewport
102
+ * @type {Function}
103
+ * @default undefined
104
+ * @example
105
+ * this.onVisibilityChange = function(inViewport) {
106
+ * if (inViewport === true) {
107
+ * console.log("object has entered the in a camera viewport!");
108
+ * }
109
+ * };
110
+ */
111
+ this.onVisibilityChange = undefined;
112
+
113
+ /**
114
+ * Whether the renderable object will always update, even when outside of the viewport<br>
115
+ * @type {boolean}
116
+ * @default false
117
+ */
118
+ this.alwaysUpdate = false;
119
+
120
+ /**
121
+ * Whether to update this object when the game is paused.
122
+ * @type {boolean}
123
+ * @default false
124
+ */
125
+ this.updateWhenPaused = false;
126
+
127
+ /**
128
+ * make the renderable object persistent over level changes<br>
129
+ * @type {boolean}
130
+ * @default false
131
+ */
132
+ this.isPersistent = false;
133
+
134
+ /**
135
+ * If true, this renderable will be rendered using screen coordinates,
136
+ * as opposed to world coordinates. Use this, for example, to define UI elements.
137
+ * @type {boolean}
138
+ * @default false
139
+ */
140
+ this.floating = false;
141
+
142
+ if (this.anchorPoint instanceof ObservableVector2d) {
143
+ this.anchorPoint.setMuted(0.5, 0.5).setCallback(this.onAnchorUpdate, this);
144
+ } else {
145
+ /**
146
+ * The anchor point is used for attachment behavior, and/or when applying transformations.<br>
147
+ * The coordinate system places the origin at the top left corner of the frame (0, 0) and (1, 1) means the bottom-right corner<br>
148
+ * <img src="images/anchor_point.png"/><br>
149
+ * a Renderable's anchor point defaults to (0.5,0.5), which corresponds to the center position.<br>
150
+ * <br>
151
+ * <i><b>Note:</b> Object created through Tiled will have their anchorPoint set to (0, 0) to match Tiled Level editor implementation.
152
+ * To specify a value through Tiled, use a json expression like `json:{"x":0.5,"y":0.5}`. </i>
153
+ * @type {ObservableVector2d}
154
+ * @default <0.5,0.5>
155
+ */
156
+ this.anchorPoint = pool.pull("ObservableVector2d", 0.5, 0.5, { onUpdate: this.onAnchorUpdate, scope: this });
157
+ }
158
+
159
+ /**
160
+ * When enabled, an object container will automatically apply
161
+ * any defined transformation before calling the child draw method.
162
+ * @type {boolean}
163
+ * @default true
164
+ * @example
165
+ * // enable "automatic" transformation when the object is activated
166
+ * onActivateEvent: function () {
167
+ * // reset the transformation matrix
168
+ * this.currentTransform.identity();
169
+ * // ensure the anchor point is the renderable center
170
+ * this.anchorPoint.set(0.5, 0.5);
171
+ * // enable auto transform
172
+ * this.autoTransform = true;
173
+ * ....
174
+ * }
175
+ */
176
+ this.autoTransform = true;
177
+
178
+ /**
179
+ * Define the renderable opacity<br>
180
+ * Set to zero if you do not wish an object to be drawn
181
+ * @see Renderable#setOpacity
182
+ * @see Renderable#getOpacity
183
+ * @type {number}
184
+ * @default 1.0
185
+ */
186
+ this.alpha = 1.0;
187
+
188
+ /**
189
+ * a reference to the parent object that contains this renderable
190
+ * @type {Container|Entity}
191
+ * @default undefined
192
+ */
193
+ this.ancestor = undefined;
194
+
195
+ /**
196
+ * A mask limits rendering elements to the shape and position of the given mask object.
197
+ * So, if the renderable is larger than the mask, only the intersecting part of the renderable will be visible.
198
+ * @type {Rect|RoundRect|Polygon|Line|Ellipse}
199
+ * @default undefined
200
+ * @example
201
+ * // apply a mask in the shape of a Star
202
+ * myNPCSprite.mask = new me.Polygon(myNPCSprite.width / 2, 0, [
203
+ * // draw a star
204
+ * {x: 0, y: 0},
205
+ * {x: 14, y: 30},
206
+ * {x: 47, y: 35},
207
+ * {x: 23, y: 57},
208
+ * {x: 44, y: 90},
209
+ * {x: 0, y: 62},
210
+ * {x: -44, y: 90},
211
+ * {x: -23, y: 57},
212
+ * {x: -47, y: 35},
213
+ * {x: -14, y: 30}
214
+ * ]);
215
+ */
216
+ this.mask = undefined;
217
+
218
+ /**
219
+ * the blend mode to be applied to this renderable (see renderer setBlendMode for available blend mode)
220
+ * @type {string}
221
+ * @default "normal"
222
+ * @see CanvasRenderer#setBlendMode
223
+ * @see WebGLRenderer#setBlendMode
224
+ */
225
+ this.blendMode = "normal";
226
+
227
+ /**
228
+ * The name of the renderable
229
+ * @type {string}
230
+ * @default ""
231
+ */
232
+ this.name = "";
233
+
234
+ if (this.pos instanceof ObservableVector3d) {
235
+ this.pos.setMuted(x, y, 0).setCallback(this.updateBoundsPos, this);
236
+ } else {
237
+ /**
238
+ * Position of the Renderable relative to its parent container
239
+ * @public
240
+ * @type {ObservableVector3d}
241
+ */
242
+ this.pos = pool.pull("ObservableVector3d", x, y, 0, { onUpdate: this.updateBoundsPos, scope: this});
243
+ }
244
+
245
+ /**
246
+ * when true the renderable will be redrawn during the next update cycle
247
+ * @type {boolean}
248
+ * @default false
249
+ */
250
+ this.isDirty = false;
251
+
252
+ // keep track of when we flip
253
+ this._flip = {
254
+ x : false,
255
+ y : false
256
+ };
257
+
258
+ // viewport flag
259
+ this._inViewport = false;
260
+
261
+ // ensure it's fully opaque by default
262
+ this.setOpacity(1.0);
263
+ }
264
+
265
+ /**
266
+ * Whether the renderable object is floating, or contained in a floating container
267
+ * @see Renderable#floating
268
+ * @type {boolean}
269
+ */
270
+ get isFloating() {
271
+ return this.floating === true || (typeof this.ancestor !== "undefined" && this.ancestor.floating === true);
272
+ }
273
+
274
+ /**
275
+ * define a tint for this renderable. a (255, 255, 255) r, g, b value will remove the tint effect.
276
+ * @type {Color}
277
+ * @default (255, 255, 255)
278
+ * @example
279
+ * // add a red tint to this renderable
280
+ * this.tint.setColor(255, 128, 128);
281
+ * // remove the tint
282
+ * this.tint.setColor(255, 255, 255);
283
+ */
284
+ get tint() {
285
+ if (typeof this._tint === "undefined") {
286
+ this._tint = pool.pull("Color", 255, 255, 255, 1.0);
287
+ }
288
+ return this._tint;
289
+ }
290
+ set tint(value) {
291
+ if (typeof this._tint === "undefined") {
292
+ this._tint = pool.pull("Color", 255, 255, 255, 1.0);
293
+ }
294
+ if (value instanceof Color) {
295
+ this._tint.copy(value);
296
+ } else {
297
+ // string (#RGB, #ARGB, #RRGGBB, #AARRGGBB)
298
+ this._tint.parseCSS(value);
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Whether the renderable object is visible and within the viewport
304
+ * @type {boolean}
305
+ * @default false
306
+ */
307
+ get inViewport() {
308
+ return this._inViewport;
309
+ }
310
+ set inViewport(value) {
311
+ if (this._inViewport !== value) {
312
+ this._inViewport = value;
313
+ if (typeof this.onVisibilityChange === "function") {
314
+ this.onVisibilityChange.call(this, value);
315
+ }
316
+ }
317
+ }
318
+
319
+ /**
320
+ * returns true if this renderable is flipped on the horizontal axis
321
+ * @public
322
+ * @see Renderable#flipX
323
+ * @type {boolean}
324
+ */
325
+ get isFlippedX() {
326
+ return this._flip.x === true;
327
+ }
328
+
329
+ /**
330
+ * returns true if this renderable is flipped on the vertical axis
331
+ * @public
332
+ * @see Renderable#flipY
333
+ * @type {boolean}
334
+ */
335
+ get isFlippedY() {
336
+ return this._flip.y === true;
337
+ }
338
+
339
+ /**
340
+ * returns the bounding box for this renderable
341
+ * @returns {Bounds} bounding box Rectangle object
342
+ */
343
+ getBounds() {
344
+ if (typeof this._bounds === "undefined") {
345
+ super.getBounds();
346
+ if (this.isFinite()) {
347
+ this._bounds.setMinMax(this.pos.x, this.pos.y, this.pos.x + this.width, this.pos.y + this.height);
348
+ } else {
349
+ // e.g. containers or game world can have infinite size
350
+ this._bounds.setMinMax(this.pos.x, this.pos.y, this.width, this.height);
351
+ }
352
+
353
+ }
354
+ return this._bounds;
355
+ }
356
+
357
+ /**
358
+ * get the renderable alpha channel value<br>
359
+ * @returns {number} current opacity value between 0 and 1
360
+ */
361
+ getOpacity() {
362
+ return this.alpha;
363
+ }
364
+
365
+ /**
366
+ * set the renderable alpha channel value<br>
367
+ * @param {number} alpha - opacity value between 0.0 and 1.0
368
+ */
369
+ setOpacity(alpha) {
370
+ if (typeof (alpha) === "number") {
371
+ this.alpha = clamp(alpha, 0.0, 1.0);
372
+ // Set to 1 if alpha is NaN
373
+ if (isNaN(this.alpha)) {
374
+ this.alpha = 1.0;
375
+ }
376
+ this.isDirty = true;
377
+ }
378
+ }
379
+
380
+ /**
381
+ * flip the renderable on the horizontal axis (around the center of the renderable)
382
+ * @see Matrix2d#scaleX
383
+ * @param {boolean} [flip=true] - `true` to flip this renderable.
384
+ * @returns {Renderable} Reference to this object for method chaining
385
+ */
386
+ flipX(flip = true) {
387
+ this._flip.x = !!flip;
388
+ this.isDirty = true;
389
+ return this;
390
+ }
391
+
392
+ /**
393
+ * flip the renderable on the vertical axis (around the center of the renderable)
394
+ * @see Matrix2d#scaleY
395
+ * @param {boolean} [flip=true] - `true` to flip this renderable.
396
+ * @returns {Renderable} Reference to this object for method chaining
397
+ */
398
+ flipY(flip = true) {
399
+ this._flip.y = !!flip;
400
+ this.isDirty = true;
401
+ return this;
402
+ }
403
+
404
+ /**
405
+ * multiply the renderable currentTransform with the given matrix
406
+ * @see Renderable#currentTransform
407
+ * @param {Matrix2d} m - the transformation matrix
408
+ * @returns {Renderable} Reference to this object for method chaining
409
+ */
410
+ transform(m) {
411
+ this.currentTransform.multiply(m);
412
+ //super.transform(m);
413
+ this.updateBoundsPos(this.pos.x, this.pos.y);
414
+ this.isDirty = true;
415
+ return this;
416
+ }
417
+
418
+ /**
419
+ * return the angle to the specified target
420
+ * @param {Renderable|Vector2d|Vector3d} target
421
+ * @returns {number} angle in radians
422
+ */
423
+ angleTo(target) {
424
+ var a = this.getBounds();
425
+ var ax, ay;
426
+
427
+ if (target instanceof Renderable) {
428
+ var b = target.getBounds();
429
+ ax = b.centerX - a.centerX;
430
+ ay = b.centerY - a.centerY;
431
+ } else { // vector object
432
+ ax = target.x - a.centerX;
433
+ ay = target.y - a.centerY;
434
+ }
435
+
436
+ return Math.atan2(ay, ax);
437
+ }
438
+
439
+ /**
440
+ * return the distance to the specified target
441
+ * @param {Renderable|Vector2d|Vector3d} target
442
+ * @returns {number} distance
443
+ */
444
+ distanceTo(target) {
445
+ var a = this.getBounds();
446
+ var dx, dy;
447
+
448
+ if (target instanceof Renderable) {
449
+ var b = target.getBounds();
450
+ dx = a.centerX - b.centerX;
451
+ dy = a.centerY - b.centerY;
452
+ } else { // vector object
453
+ dx = a.centerX - target.x;
454
+ dy = a.centerY - target.y;
455
+ }
456
+
457
+ return Math.sqrt(dx * dx + dy * dy);
458
+ }
459
+
460
+ /**
461
+ * Rotate this renderable towards the given target.
462
+ * @param {Renderable|Vector2d|Vector3d} target - the renderable or position to look at
463
+ * @returns {Renderable} Reference to this object for method chaining
464
+ */
465
+ lookAt(target) {
466
+ var position;
467
+
468
+ if (target instanceof Renderable) {
469
+ position = target.pos;
470
+ } else {
471
+ position = target;
472
+ }
473
+
474
+ var angle = this.angleTo(position);
475
+
476
+ this.rotate(angle);
477
+
478
+ return this;
479
+ }
480
+
481
+ /**
482
+ * Rotate this renderable by the specified angle (in radians).
483
+ * @param {number} angle - The angle to rotate (in radians)
484
+ * @param {Vector2d|ObservableVector2d} [v] - an optional point to rotate around
485
+ * @returns {Renderable} Reference to this object for method chaining
486
+ */
487
+ rotate(angle, v) {
488
+ if (!isNaN(angle)) {
489
+ this.currentTransform.rotate(angle, v);
490
+ //this.updateBoundsPos(this.pos.x, this.pos.y);
491
+ this.isDirty = true;
492
+ }
493
+ return this;
494
+ }
495
+
496
+ /**
497
+ * scale the renderable around his anchor point. Scaling actually applies changes
498
+ * to the currentTransform member wich is used by the renderer to scale the object
499
+ * when rendering. It does not scale the object itself. For example if the renderable
500
+ * is an image, the image.width and image.height properties are unaltered but the currentTransform
501
+ * member will be changed.
502
+ * @param {number} x - a number representing the abscissa of the scaling vector.
503
+ * @param {number} [y=x] - a number representing the ordinate of the scaling vector.
504
+ * @returns {Renderable} Reference to this object for method chaining
505
+ */
506
+ scale(x, y) {
507
+ this.currentTransform.scale(x, y);
508
+ super.scale(x, y);
509
+ this.isDirty = true;
510
+ return this;
511
+ }
512
+
513
+ /**
514
+ * scale the renderable around his anchor point
515
+ * @param {Vector2d} v - scaling vector
516
+ * @returns {Renderable} Reference to this object for method chaining
517
+ */
518
+ scaleV(v) {
519
+ this.scale(v.x, v.y);
520
+ return this;
521
+ }
522
+
523
+ /**
524
+ * update function (automatically called by melonJS).
525
+ * @param {number} dt - time since the last update in milliseconds.
526
+ * @returns {boolean} true if the renderable is dirty
527
+ */
528
+ update(dt) { // eslint-disable-line no-unused-vars
529
+ return this.isDirty;
530
+ }
531
+
532
+ /**
533
+ * update the bounding box for this shape.
534
+ * @ignore
535
+ * @returns {Bounds} this shape bounding box Rectangle object
536
+ */
537
+ updateBounds() {
538
+ super.updateBounds();
539
+ this.updateBoundsPos(this.pos.x, this.pos.y);
540
+ return this.getBounds();
541
+ }
542
+
543
+ /**
544
+ * update the renderable's bounding rect (private)
545
+ * @ignore
546
+ */
547
+ updateBoundsPos(newX, newY) {
548
+ var bounds = this.getBounds();
549
+
550
+ bounds.shift(newX, newY);
551
+
552
+ if (typeof this.anchorPoint !== "undefined" && bounds.isFinite()) {
553
+ bounds.translate(
554
+ -(this.anchorPoint.x * bounds.width),
555
+ -(this.anchorPoint.y * bounds.height)
556
+ );
557
+ }
558
+
559
+ /*
560
+ if (typeof this.body !== "undefined") {
561
+ var bodyBounds = this.body.getBounds();
562
+ bounds.translate(bodyBounds.x, bodyBounds.y);
563
+ }
564
+ */
565
+
566
+ // XXX: This is called from the constructor, before it gets an ancestor
567
+ if (typeof this.ancestor !== "undefined" && typeof this.ancestor.addChild === "function" && this.floating !== true) {
568
+ bounds.translate(this.ancestor.getAbsolutePosition());
569
+ }
570
+
571
+ this.isDirty = true;
572
+ }
573
+
574
+ /**
575
+ * return the renderable absolute position in the game world
576
+ * @returns {Vector2d}
577
+ */
578
+ getAbsolutePosition() {
579
+ if (typeof this._absPos === "undefined") {
580
+ this._absPos = pool.pull("Vector2d");
581
+ }
582
+ // XXX Cache me or something
583
+ this._absPos.set(this.pos.x, this.pos.y);
584
+ if (typeof this.ancestor !== "undefined" && typeof this.ancestor.addChild === "function" && this.floating !== true) {
585
+ this._absPos.add(this.ancestor.getAbsolutePosition());
586
+ }
587
+ return this._absPos;
588
+ }
589
+
590
+ /**
591
+ * called when the anchor point value is changed
592
+ * @private
593
+ * @param {number} x - the new X value to be set for the anchor
594
+ * @param {number} y - the new Y value to be set for the anchor
595
+ */
596
+ onAnchorUpdate(x, y) {
597
+ // since the callback is called before setting the new value
598
+ // manually update the anchor point (required for updateBoundsPos)
599
+ this.anchorPoint.setMuted(x, y);
600
+ // then call updateBounds
601
+ this.updateBoundsPos(this.pos.x, this.pos.y);
602
+ }
603
+
604
+ /**
605
+ * Prepare the rendering context before drawing (automatically called by melonJS).
606
+ * This will apply any defined transforms, anchor point, tint or blend mode and translate the context accordingly to this renderable position.
607
+ * @see Renderable#draw
608
+ * @see Renderable#postDraw
609
+ * @param {CanvasRenderer|WebGLRenderer} renderer - a renderer object
610
+ */
611
+ preDraw(renderer) {
612
+ var bounds = this.getBounds();
613
+ var ax = bounds.width * this.anchorPoint.x,
614
+ ay = bounds.height * this.anchorPoint.y;
615
+
616
+ // save renderer context
617
+ renderer.save();
618
+
619
+ // apply the defined alpha value
620
+ renderer.setGlobalAlpha(renderer.globalAlpha() * this.getOpacity());
621
+
622
+ // apply flip
623
+ if (this._flip.x || this._flip.y) {
624
+ var dx = this._flip.x ? this.centerX - ax : 0,
625
+ dy = this._flip.y ? this.centerY - ay : 0;
626
+
627
+ renderer.translate(dx, dy);
628
+ renderer.scale(this._flip.x ? -1 : 1, this._flip.y ? -1 : 1);
629
+ renderer.translate(-dx, -dy);
630
+ }
631
+
632
+ // apply stencil mask if defined
633
+ if (typeof this.mask !== "undefined") {
634
+ renderer.translate(this.pos.x, this.pos.y);
635
+ renderer.setMask(this.mask);
636
+ renderer.translate(-this.pos.x, -this.pos.y);
637
+ }
638
+
639
+ if ((this.autoTransform === true) && (!this.currentTransform.isIdentity())) {
640
+ // apply the renderable transformation matrix
641
+ renderer.translate(this.pos.x, this.pos.y);
642
+ renderer.transform(this.currentTransform);
643
+ renderer.translate(-this.pos.x, -this.pos.y);
644
+ }
645
+
646
+ // offset by the anchor point
647
+ renderer.translate(-ax, -ay);
648
+
649
+ // apply the current tint and opacity
650
+ renderer.setTint(this.tint, this.getOpacity());
651
+
652
+ // apply blending if different from "normal"
653
+ if (this.blendMode !== renderer.getBlendMode()) {
654
+ renderer.setBlendMode(this.blendMode);
655
+ }
656
+ }
657
+
658
+ /**
659
+ * Draw this renderable (automatically called by melonJS).
660
+ * All draw operations for renderable are made respectively
661
+ * to the position or transforms set or applied by the preDraw method.
662
+ * The main draw loop will first call preDraw() to prepare the context for drawing the renderable,
663
+ * then draw() to draw the renderable, and finally postDraw() to clear the context.
664
+ * If you override this method, be mindful about the drawing logic; for example if you draw a shape
665
+ * from the draw method, you should make sure that your draw it at the 0, 0 coordinates.
666
+ * @see Renderable#preDraw
667
+ * @see Renderable#postDraw
668
+ * @param {CanvasRenderer|WebGLRenderer} renderer - a renderer instance
669
+ * @param {Camera2d} [viewport] - the viewport to (re)draw
670
+ */
671
+ draw(renderer, viewport) { // eslint-disable-line no-unused-vars
672
+ // empty one !
673
+ }
674
+
675
+ /**
676
+ * restore the rendering context after drawing (automatically called by melonJS).
677
+ * @see Renderable#preDraw
678
+ * @see Renderable#draw
679
+ * @param {CanvasRenderer|WebGLRenderer} renderer - a renderer object
680
+ */
681
+ postDraw(renderer) {
682
+ // remove the previously applied tint
683
+ renderer.clearTint();
684
+
685
+ // clear the mask if set
686
+ if (typeof this.mask !== "undefined") {
687
+ renderer.clearMask();
688
+ }
689
+
690
+ // restore the context
691
+ renderer.restore();
692
+
693
+ // reset the dirty flag
694
+ this.isDirty = false;
695
+ }
696
+
697
+ /**
698
+ * onCollision callback, triggered in case of collision,
699
+ * when this renderable body is colliding with another one
700
+ * @param {ResponseObject} response - the collision response object
701
+ * @param {Renderable} other - the other renderable touching this one (a reference to response.a or response.b)
702
+ * @returns {boolean} true if the object should respond to the collision (its position and velocity will be corrected)
703
+ * @example
704
+ * // colision handler
705
+ * onCollision(response) {
706
+ * if (response.b.body.collisionType === me.collision.types.ENEMY_OBJECT) {
707
+ * // makes the other object solid, by substracting the overlap vector to the current position
708
+ * this.pos.sub(response.overlapV);
709
+ * this.hurt();
710
+ * // not solid
711
+ * return false;
712
+ * }
713
+ * // Make the object solid
714
+ * return true;
715
+ * },
716
+ */
717
+ onCollision(response, other) { // eslint-disable-line no-unused-vars
718
+ return false;
719
+ }
720
+
721
+ /**
722
+ * Destroy function<br>
723
+ * @ignore
724
+ */
725
+ destroy() {
726
+ // allow recycling object properties
727
+ pool.push(this.currentTransform);
728
+ this.currentTransform = undefined;
729
+
730
+ pool.push(this.anchorPoint);
731
+ this.anchorPoint = undefined;
732
+
733
+ pool.push(this.pos);
734
+ this.pos = undefined;
735
+
736
+ if (typeof this._absPos !== "undefined") {
737
+ pool.push(this._absPos);
738
+ this._absPos = undefined;
739
+ }
740
+
741
+ pool.push(this._bounds);
742
+ this._bounds = undefined;
743
+
744
+ this.onVisibilityChange = undefined;
745
+
746
+ if (typeof this.mask !== "undefined") {
747
+ pool.push(this.mask);
748
+ this.mask = undefined;
749
+ }
750
+
751
+ if (typeof this._tint !== "undefined") {
752
+ pool.push(this._tint);
753
+ this._tint = undefined;
754
+ }
755
+
756
+ this.ancestor = undefined;
757
+
758
+ // destroy the physic body if defined
759
+ if (typeof this.body !== "undefined") {
760
+ this.body.destroy.apply(this.body, arguments);
761
+ this.body = undefined;
762
+ }
763
+
764
+ // release all registered events
765
+ releaseAllPointerEvents(this);
766
+
767
+ // call the user defined destroy method
768
+ this.onDestroyEvent.apply(this, arguments);
769
+ }
770
+
771
+ /**
772
+ * OnDestroy Notification function<br>
773
+ * Called by engine before deleting the object
774
+ */
775
+ onDestroyEvent() {
776
+ // to be extended !
777
+ }
778
+
779
+ }
780
+
781
+ export { Renderable as default };