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,731 @@
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 Vector2d from '../math/vector2.js';
9
+ import Vector3d from '../math/vector3.js';
10
+ import ObservableVector2d from '../math/observable_vector2.js';
11
+ import ObservableVector3d from '../math/observable_vector3.js';
12
+ import Matrix2d from '../math/matrix2.js';
13
+ import Matrix3d from '../math/matrix3.js';
14
+ import Rect from '../geometries/rectangle.js';
15
+ import { renderer } from '../video/video.js';
16
+ import { on, GAME_RESET, CANVAS_ONRESIZE, emit, VIEWPORT_ONRESIZE, VIEWPORT_ONCHANGE } from '../system/event.js';
17
+ import pool from '../system/pooling.js';
18
+ import Renderable from '../renderable/renderable.js';
19
+ import { clamp, toBeCloseTo } from '../math/math.js';
20
+ import game from '../game.js';
21
+
22
+ // some ref shortcut
23
+ const MIN = Math.min, MAX = Math.max;
24
+
25
+ var targetV = new Vector2d();
26
+
27
+ /**
28
+ * @classdesc
29
+ * a 2D orthographic camera
30
+ * @augments Renderable
31
+ */
32
+ class Camera2d extends Renderable {
33
+ /**
34
+ * @param {number} minX - start x offset
35
+ * @param {number} minY - start y offset
36
+ * @param {number} maxX - end x offset
37
+ * @param {number} maxY - end y offset
38
+ */
39
+ constructor(minX, minY, maxX, maxY) {
40
+ super(minX, minY, maxX - minX, maxY - minY);
41
+
42
+ /**
43
+ * Axis definition
44
+ * @enum {number}
45
+ * @property {number} NONE no axis
46
+ * @property {number} HORIZONTAL horizontal axis only
47
+ * @property {number} VERTICAL vertical axis only
48
+ * @property {number} BOTH both axis
49
+ * @readonly
50
+ * @name AXIS
51
+ * @memberof Camera2d
52
+ */
53
+ this.AXIS = {
54
+ NONE : 0,
55
+ HORIZONTAL : 1,
56
+ VERTICAL : 2,
57
+ BOTH : 3
58
+ };
59
+
60
+ /**
61
+ * Camera bounds
62
+ * @public
63
+ * @type {Bounds}
64
+ * @name bounds
65
+ * @memberof Camera2d
66
+ */
67
+ this.bounds = pool.pull("Bounds");
68
+
69
+ /**
70
+ * enable or disable damping
71
+ * @private
72
+ * @default true
73
+ */
74
+ this.smoothFollow = true;
75
+
76
+ /**
77
+ * Camera damping for smooth transition [0 .. 1].
78
+ * 1 being the maximum value and will snap the camera to the target position
79
+ * @public
80
+ * @type {number}
81
+ * @name damping
82
+ * @default 1.0
83
+ * @memberof Camera2d
84
+ */
85
+ this.damping = 1.0;
86
+
87
+ /**
88
+ * the closest point relative to the camera
89
+ * @public
90
+ * @type {number}
91
+ * @name near
92
+ * @default -1000
93
+ * @memberof Camera2d
94
+ */
95
+ this.near = -1000;
96
+
97
+ /**
98
+ * the furthest point relative to the camera.
99
+ * @public
100
+ * @type {number}
101
+ * @name far
102
+ * @default 1000
103
+ * @memberof Camera2d
104
+ */
105
+ this.far = 1000;
106
+
107
+ /**
108
+ * the default camera projection matrix
109
+ * (2d cameras use an orthographic projection by default).
110
+ * @public
111
+ * @type {Matrix3d}
112
+ * @name projectionMatrix
113
+ * @memberof Camera2d
114
+ */
115
+ this.projectionMatrix = new Matrix3d();
116
+
117
+ /**
118
+ * the invert camera transform used to unproject points
119
+ * @ignore
120
+ * @type {Matrix2d}
121
+ * @name invCurrentTransform
122
+ * @memberof Camera2d
123
+ */
124
+ this.invCurrentTransform = new Matrix2d();
125
+
126
+ // offset for shake effect
127
+ this.offset = new Vector2d();
128
+
129
+ // target to follow
130
+ this.target = null;
131
+
132
+ // default value follow
133
+ this.follow_axis = this.AXIS.NONE;
134
+
135
+ // shake variables
136
+ this._shake = {
137
+ intensity : 0,
138
+ duration : 0,
139
+ axis : this.AXIS.BOTH,
140
+ onComplete : null
141
+ };
142
+
143
+ // flash variables
144
+ this._fadeOut = {
145
+ color : null,
146
+ tween : null
147
+ };
148
+ // fade variables
149
+ this._fadeIn = {
150
+ color : null,
151
+ tween : null
152
+ };
153
+
154
+ // default camera name
155
+ this.name = "default";
156
+
157
+ // set a default deadzone
158
+ this.setDeadzone(this.width / 6, this.height / 6);
159
+
160
+ // for backward "compatiblity" (in terms of behavior)
161
+ this.anchorPoint.set(0, 0);
162
+
163
+ // enable event detection on the camera
164
+ this.isKinematic = false;
165
+
166
+ this.bounds.setMinMax(minX, minY, maxX, maxY);
167
+
168
+ // update the projection matrix
169
+ this._updateProjectionMatrix();
170
+
171
+ // subscribe to the game reset event
172
+ on(GAME_RESET, this.reset, this);
173
+ // subscribe to the canvas resize event
174
+ on(CANVAS_ONRESIZE, this.resize, this);
175
+ }
176
+
177
+ // -- some private function ---
178
+
179
+ /** @ignore */
180
+ // update the projection matrix based on the projection frame (a rectangle)
181
+ _updateProjectionMatrix() {
182
+ this.projectionMatrix.ortho(0, this.width, this.height, 0, this.near, this.far);
183
+ }
184
+
185
+ /** @ignore */
186
+ _followH(target) {
187
+ var targetX = this.pos.x;
188
+ if ((target.x - this.pos.x) > (this.deadzone.right)) {
189
+ targetX = MIN((target.x) - (this.deadzone.right), this.bounds.width - this.width);
190
+ }
191
+ else if ((target.x - this.pos.x) < (this.deadzone.pos.x)) {
192
+ targetX = MAX((target.x) - this.deadzone.pos.x, this.bounds.left);
193
+ }
194
+ return targetX;
195
+
196
+ }
197
+
198
+ /** @ignore */
199
+ _followV(target) {
200
+ var targetY = this.pos.y;
201
+ if ((target.y - this.pos.y) > (this.deadzone.bottom)) {
202
+ targetY = MIN((target.y) - (this.deadzone.bottom), this.bounds.height - this.height);
203
+ }
204
+ else if ((target.y - this.pos.y) < (this.deadzone.pos.y)) {
205
+ targetY = MAX((target.y) - this.deadzone.pos.y, this.bounds.top);
206
+ }
207
+ return targetY;
208
+ }
209
+
210
+ // -- public function ---
211
+
212
+ /**
213
+ * reset the camera position to specified coordinates
214
+ * @name reset
215
+ * @memberof Camera2d
216
+ * @param {number} [x=0]
217
+ * @param {number} [y=0]
218
+ */
219
+ reset(x = 0, y = 0) {
220
+ // reset the initial camera position to 0,0
221
+ this.pos.x = x;
222
+ this.pos.y = y;
223
+
224
+ // reset the target
225
+ this.unfollow();
226
+
227
+ // damping default value
228
+ this.smoothFollow = true;
229
+ this.damping = 1.0;
230
+
231
+ // reset the transformation matrix
232
+ this.currentTransform.identity();
233
+ this.invCurrentTransform.identity().invert();
234
+
235
+ // update the projection matrix
236
+ this._updateProjectionMatrix();
237
+ }
238
+
239
+ /**
240
+ * change the deadzone settings.
241
+ * the "deadzone" defines an area within the current camera in which
242
+ * the followed renderable can move without scrolling the camera.
243
+ * @name setDeadzone
244
+ * @see Camera2d.follow
245
+ * @memberof Camera2d
246
+ * @param {number} w - deadzone width
247
+ * @param {number} h - deadzone height
248
+ */
249
+ setDeadzone(w, h) {
250
+ if (typeof(this.deadzone) === "undefined") {
251
+ this.deadzone = new Rect(0, 0, 0, 0);
252
+ }
253
+
254
+ // reusing the old code for now...
255
+ this.deadzone.pos.set(
256
+ ~~((this.width - w) / 2),
257
+ ~~((this.height - h) / 2 - h * 0.25)
258
+ );
259
+ this.deadzone.resize(w, h);
260
+
261
+ this.smoothFollow = false;
262
+
263
+ // force a camera update
264
+ this.updateTarget();
265
+
266
+ this.smoothFollow = true;
267
+ }
268
+
269
+ /**
270
+ * resize the camera
271
+ * @name resize
272
+ * @memberof Camera2d
273
+ * @param {number} w - new width of the camera
274
+ * @param {number} h - new height of the camera
275
+ * @returns {Camera2d} this camera
276
+ */
277
+ resize(w, h) {
278
+ // parent consctructor, resize camera rect
279
+ super.resize(w, h);
280
+
281
+ // disable damping while resizing
282
+ this.smoothFollow = false;
283
+
284
+ // reset everything
285
+ this.setBounds(0, 0, w, h);
286
+ this.setDeadzone(w / 6, h / 6);
287
+ this.update();
288
+ this.smoothFollow = true;
289
+
290
+ // update the projection matrix
291
+ this._updateProjectionMatrix();
292
+
293
+ // publish the viewport resize event
294
+ emit(VIEWPORT_ONRESIZE, this.width, this.height, this);
295
+
296
+ return this;
297
+ }
298
+
299
+ /**
300
+ * set the camera boundaries (set to the world limit by default).
301
+ * the camera is bound to the given coordinates and cannot move/be scrolled outside of it.
302
+ * @name setBounds
303
+ * @memberof Camera2d
304
+ * @param {number} x - world left limit
305
+ * @param {number} y - world top limit
306
+ * @param {number} w - world width limit
307
+ * @param {number} h - world height limit
308
+ */
309
+ setBounds(x, y, w, h) {
310
+ this.smoothFollow = false;
311
+ this.bounds.setMinMax(x, y, w + x, h + y);
312
+ this.moveTo(this.pos.x, this.pos.y);
313
+ this.update();
314
+ this.smoothFollow = true;
315
+ }
316
+
317
+ /**
318
+ * set the camera to follow the specified renderable. <br>
319
+ * (this will put the camera center around the given target)
320
+ * @name follow
321
+ * @memberof Camera2d
322
+ * @param {Renderable|Vector2d} target - renderable or position vector to follow
323
+ * @param {number} [axis=me.game.viewport.AXIS.BOTH] - Which axis to follow (see {@link Camera2d.AXIS})
324
+ * @param {number} [damping=1] - default damping value
325
+ * @example
326
+ * // set the camera to follow this renderable on both axis, and enable damping
327
+ * me.game.viewport.follow(this, me.game.viewport.AXIS.BOTH, 0.1);
328
+ */
329
+ follow(target, axis, damping) {
330
+ if (target instanceof Renderable) {
331
+ this.target = target.pos;
332
+ }
333
+ else if ((target instanceof Vector2d) || (target instanceof Vector3d) ||
334
+ (target instanceof ObservableVector2d) || (target instanceof ObservableVector3d)) {
335
+ this.target = target;
336
+ }
337
+ else {
338
+ throw new Error("invalid target for me.Camera2d.follow");
339
+ }
340
+ // if axis is null, camera is moved on target center
341
+ this.follow_axis = (
342
+ typeof(axis) === "undefined" ? this.AXIS.BOTH : axis
343
+ );
344
+
345
+ this.smoothFollow = false;
346
+
347
+ if (typeof damping !== "number") {
348
+ this.damping = 1;
349
+ } else {
350
+ this.damping = clamp(damping, 0.0, 1.0);
351
+ }
352
+
353
+ // force a camera update
354
+ this.updateTarget();
355
+
356
+ this.smoothFollow = true;
357
+ }
358
+
359
+ /**
360
+ * unfollow the current target
361
+ * @name unfollow
362
+ * @memberof Camera2d
363
+ */
364
+ unfollow() {
365
+ this.target = null;
366
+ this.follow_axis = this.AXIS.NONE;
367
+ }
368
+
369
+ /**
370
+ * move the camera upper-left position by the specified offset.
371
+ * @name move
372
+ * @memberof Camera2d
373
+ * @see Camera2d.focusOn
374
+ * @param {number} x
375
+ * @param {number} y
376
+ * @example
377
+ * // Move the camera up by four pixels
378
+ * me.game.viewport.move(0, -4);
379
+ */
380
+ move(x, y) {
381
+ this.moveTo(this.pos.x + x, this.pos.y + y);
382
+ }
383
+
384
+ /**
385
+ * move the camera upper-left position to the specified coordinates
386
+ * @name moveTo
387
+ * @memberof Camera2d
388
+ * @see Camera2d.focusOn
389
+ * @param {number} x
390
+ * @param {number} y
391
+ */
392
+ moveTo(x, y) {
393
+ var _x = this.pos.x;
394
+ var _y = this.pos.y;
395
+
396
+ this.pos.x = clamp(
397
+ x,
398
+ this.bounds.left,
399
+ this.bounds.width
400
+ );
401
+ this.pos.y = clamp(
402
+ y,
403
+ this.bounds.top,
404
+ this.bounds.height
405
+ );
406
+
407
+ //publish the VIEWPORT_ONCHANGE event if necessary
408
+ if (_x !== this.pos.x || _y !== this.pos.y) {
409
+ this.isDirty = true;
410
+ }
411
+ }
412
+
413
+ /** @ignore */
414
+ updateTarget() {
415
+ if (this.target) {
416
+
417
+ targetV.setV(this.pos);
418
+
419
+ switch (this.follow_axis) {
420
+ case this.AXIS.NONE:
421
+ //this.focusOn(this.target);
422
+ break;
423
+
424
+ case this.AXIS.HORIZONTAL:
425
+ targetV.x = this._followH(this.target);
426
+ break;
427
+
428
+ case this.AXIS.VERTICAL:
429
+ targetV.y = this._followV(this.target);
430
+ break;
431
+
432
+ case this.AXIS.BOTH:
433
+ targetV.x = this._followH(this.target);
434
+ targetV.y = this._followV(this.target);
435
+ break;
436
+ }
437
+
438
+ if (!this.pos.equals(targetV)) {
439
+ // update the camera position
440
+ if (this.smoothFollow === true && this.damping < 1.0) {
441
+ // account for floating precision and check if we are close "enough"
442
+ if (toBeCloseTo(targetV.x, this.pos.x, 2) &&
443
+ toBeCloseTo(targetV.y, this.pos.y, 2)) {
444
+ this.pos.setV(targetV);
445
+ return;
446
+ } else {
447
+ this.pos.lerp(targetV, this.damping);
448
+ }
449
+ } else {
450
+ this.pos.setV(targetV);
451
+ }
452
+ this.isDirty = true;
453
+ }
454
+ }
455
+ }
456
+
457
+ /** @ignore */
458
+ update(dt) {
459
+ // update the camera position
460
+ this.updateTarget(dt);
461
+
462
+ if (this._shake.duration > 0) {
463
+ this._shake.duration -= dt;
464
+ if (this._shake.duration <= 0) {
465
+ this._shake.duration = 0;
466
+ this.offset.setZero();
467
+ if (typeof(this._shake.onComplete) === "function") {
468
+ this._shake.onComplete();
469
+ }
470
+ }
471
+ else {
472
+ if (this._shake.axis === this.AXIS.BOTH ||
473
+ this._shake.axis === this.AXIS.HORIZONTAL) {
474
+ this.offset.x = (Math.random() - 0.5) * this._shake.intensity;
475
+ }
476
+ if (this._shake.axis === this.AXIS.BOTH ||
477
+ this._shake.axis === this.AXIS.VERTICAL) {
478
+ this.offset.y = (Math.random() - 0.5) * this._shake.intensity;
479
+ }
480
+ }
481
+ // updated!
482
+ this.isDirty = true;
483
+ }
484
+
485
+ if (this.isDirty === true) {
486
+ //publish the corresponding message
487
+ emit(VIEWPORT_ONCHANGE, this.pos);
488
+ }
489
+
490
+ // check for fade/flash effect
491
+ if ((this._fadeIn.tween != null) || (this._fadeOut.tween != null)) {
492
+ this.isDirty = true;
493
+ }
494
+
495
+ if (!this.currentTransform.isIdentity()) {
496
+ this.invCurrentTransform.copy(this.currentTransform).invert();
497
+ } else {
498
+ // reset to default
499
+ this.invCurrentTransform.identity();
500
+ }
501
+
502
+ return super.update(dt);
503
+ }
504
+
505
+ /**
506
+ * shake the camera
507
+ * @name shake
508
+ * @memberof Camera2d
509
+ * @param {number} intensity - maximum offset that the screen can be moved
510
+ * while shaking
511
+ * @param {number} duration - expressed in milliseconds
512
+ * @param {number} [axis=me.game.viewport.AXIS.BOTH] - specify on which axis to apply the shake effect (see {@link Camera2d.AXIS})
513
+ * @param {Function} [onComplete] - callback once shaking effect is over
514
+ * @param {boolean} [force] - if true this will override the current effect
515
+ * @example
516
+ * // shake it baby !
517
+ * me.game.viewport.shake(10, 500, me.game.viewport.AXIS.BOTH);
518
+ */
519
+ shake(intensity, duration, axis, onComplete, force) {
520
+ if (this._shake.duration === 0 || force === true) {
521
+ this._shake.intensity = intensity;
522
+ this._shake.duration = duration;
523
+ this._shake.axis = axis || this.AXIS.BOTH;
524
+ this._shake.onComplete = typeof (onComplete) === "function" ? onComplete : undefined;
525
+ }
526
+ }
527
+
528
+ /**
529
+ * fadeOut(flash) effect<p>
530
+ * screen is filled with the specified color and slowly goes back to normal
531
+ * @name fadeOut
532
+ * @memberof Camera2d
533
+ * @param {Color|string} color - a CSS color value
534
+ * @param {number} [duration=1000] - expressed in milliseconds
535
+ * @param {Function} [onComplete] - callback once effect is over
536
+ * @example
537
+ * // fade the camera to white upon dying, reload the level, and then fade out back
538
+ * me.game.viewport.fadeIn("#fff", 150, function() {
539
+ * me.audio.play("die", false);
540
+ * me.level.reload();
541
+ * me.game.viewport.fadeOut("#fff", 150);
542
+ * });
543
+ */
544
+ fadeOut(color, duration = 1000, onComplete) {
545
+ this._fadeOut.color = pool.pull("Color").copy(color);
546
+ this._fadeOut.tween = pool.pull("Tween", this._fadeOut.color)
547
+ .to({ alpha: 0.0 }, duration)
548
+ .onComplete(onComplete || null);
549
+ this._fadeOut.tween.isPersistent = true;
550
+ this._fadeOut.tween.start();
551
+ }
552
+
553
+ /**
554
+ * fadeIn effect <p>
555
+ * fade to the specified color
556
+ * @name fadeIn
557
+ * @memberof Camera2d
558
+ * @param {Color|string} color - a CSS color value
559
+ * @param {number} [duration=1000] - expressed in milliseconds
560
+ * @param {Function} [onComplete] - callback once effect is over
561
+ * @example
562
+ * // flash the camera to white for 75ms
563
+ * me.game.viewport.fadeIn("#FFFFFF", 75);
564
+ */
565
+ fadeIn(color, duration = 1000, onComplete) {
566
+ this._fadeIn.color = pool.pull("Color").copy(color);
567
+ var _alpha = this._fadeIn.color.alpha;
568
+ this._fadeIn.color.alpha = 0.0;
569
+ this._fadeIn.tween = pool.pull("Tween", this._fadeIn.color)
570
+ .to({ alpha: _alpha }, duration)
571
+ .onComplete(onComplete || null);
572
+ this._fadeIn.tween.isPersistent = true;
573
+ this._fadeIn.tween.start();
574
+ }
575
+
576
+ /**
577
+ * set the camera position around the specified object
578
+ * @name focusOn
579
+ * @memberof Camera2d
580
+ * @param {Renderable} target - the renderable to focus the camera on
581
+ */
582
+ focusOn(target) {
583
+ var bounds = target.getBounds();
584
+ this.moveTo(
585
+ target.pos.x + bounds.left + (bounds.width / 2),
586
+ target.pos.y + bounds.top + (bounds.height / 2)
587
+ );
588
+ }
589
+
590
+ /**
591
+ * check if the specified renderable is in the camera
592
+ * @name isVisible
593
+ * @memberof Camera2d
594
+ * @param {Renderable} obj - to be checked against
595
+ * @param {boolean} [floating = obj.floating] - if visibility check should be done against screen coordinates
596
+ * @returns {boolean}
597
+ */
598
+ isVisible(obj, floating = obj.floating) {
599
+ if (floating === true || obj.floating === true) {
600
+ // check against screen coordinates
601
+ return renderer.overlaps(obj.getBounds());
602
+ } else {
603
+ // check if within the current camera
604
+ return obj.getBounds().overlaps(this);
605
+ }
606
+ }
607
+
608
+ /**
609
+ * convert the given "local" (screen) coordinates into world coordinates
610
+ * @name localToWorld
611
+ * @memberof Camera2d
612
+ * @param {number} x
613
+ * @param {number} y
614
+ * @param {number} [v] - an optional vector object where to set the
615
+ * converted value
616
+ * @returns {Vector2d}
617
+ */
618
+ localToWorld(x, y, v) {
619
+ // TODO memoization for one set of coords (multitouch)
620
+ v = v || pool.pull("Vector2d");
621
+ v.set(x, y).add(this.pos).sub(game.world.pos);
622
+ if (!this.currentTransform.isIdentity()) {
623
+ this.invCurrentTransform.apply(v);
624
+ }
625
+ return v;
626
+ }
627
+
628
+ /**
629
+ * convert the given world coordinates into "local" (screen) coordinates
630
+ * @name worldToLocal
631
+ * @memberof Camera2d
632
+ * @param {number} x
633
+ * @param {number} y
634
+ * @param {number} [v] - an optional vector object where to set the
635
+ * converted value
636
+ * @returns {Vector2d}
637
+ */
638
+ worldToLocal(x, y, v) {
639
+ // TODO memoization for one set of coords (multitouch)
640
+ v = v || pool.pull("Vector2d");
641
+ v.set(x, y);
642
+ if (!this.currentTransform.isIdentity()) {
643
+ this.currentTransform.apply(v);
644
+ }
645
+ return v.sub(this.pos).add(game.world.pos);
646
+ }
647
+
648
+ /**
649
+ * render the camera effects
650
+ * @ignore
651
+ */
652
+ drawFX(renderer) {
653
+ // fading effect
654
+ if (this._fadeIn.tween) {
655
+ // add an overlay
656
+ renderer.save();
657
+ // reset all transform so that the overaly cover the whole camera area
658
+ renderer.resetTransform();
659
+ renderer.setColor(this._fadeIn.color);
660
+ renderer.fillRect(0, 0, this.width, this.height);
661
+ renderer.restore();
662
+ // remove the tween if over
663
+ if (this._fadeIn.color.alpha === 1.0) {
664
+ this._fadeIn.tween = null;
665
+ pool.push(this._fadeIn.color);
666
+ this._fadeIn.color = null;
667
+ }
668
+ }
669
+
670
+ // flashing effect
671
+ if (this._fadeOut.tween) {
672
+ // add an overlay
673
+ renderer.save();
674
+ // reset all transform so that the overaly cover the whole camera area
675
+ renderer.resetTransform();
676
+ renderer.setColor(this._fadeOut.color);
677
+ renderer.fillRect(0, 0, this.width, this.height);
678
+ renderer.restore();
679
+ // remove the tween if over
680
+ if (this._fadeOut.color.alpha === 0.0) {
681
+ this._fadeOut.tween = null;
682
+ pool.push(this._fadeOut.color);
683
+ this._fadeOut.color = null;
684
+ }
685
+ }
686
+ }
687
+
688
+ /**
689
+ * draw all object visibile in this viewport
690
+ * @ignore
691
+ */
692
+ draw(renderer, container) {
693
+ var translateX = this.pos.x + this.offset.x;
694
+ var translateY = this.pos.y + this.offset.y;
695
+
696
+ // translate the world coordinates by default to screen coordinates
697
+ container.currentTransform.translate(-translateX, -translateY);
698
+
699
+ // set the camera projection
700
+ renderer.setProjection(this.projectionMatrix);
701
+
702
+ // clip to camera bounds
703
+ renderer.clipRect(
704
+ 0,
705
+ 0,
706
+ this.width,
707
+ this.height
708
+ );
709
+
710
+ this.preDraw(renderer);
711
+
712
+ container.preDraw(renderer, this);
713
+
714
+ // draw all objects,
715
+ // specifying the viewport as the rectangle area to redraw
716
+ container.draw(renderer, this);
717
+
718
+ // draw the viewport/camera effects
719
+ this.drawFX(renderer);
720
+
721
+ container.postDraw(renderer, this);
722
+
723
+ this.postDraw(renderer);
724
+
725
+ // translate the world coordinates by default to screen coordinates
726
+ container.currentTransform.translate(translateX, translateY);
727
+ }
728
+
729
+ }
730
+
731
+ export { Camera2d as default };