littlejsengine 1.8.9 → 1.9.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 (48) hide show
  1. package/README.md +17 -17
  2. package/build/littlejs.d.ts +352 -288
  3. package/build/littlejs.esm.js +695 -658
  4. package/build/littlejs.esm.min.js +1 -1
  5. package/build/littlejs.js +694 -658
  6. package/build/littlejs.min.js +1 -1
  7. package/build/littlejs.release.js +629 -594
  8. package/examples/breakout/game.js +4 -4
  9. package/examples/breakout/index.html +3 -3
  10. package/examples/breakoutTutorial/index.html +2 -2
  11. package/examples/electron/game.js +1 -1
  12. package/examples/electron/index.html +2 -2
  13. package/examples/favicon.png +0 -0
  14. package/examples/js13k/build.js +1 -1
  15. package/examples/js13k/index.html +13 -13
  16. package/examples/module/game.js +1 -1
  17. package/examples/module/index.html +1 -1
  18. package/examples/particles/index.html +1 -1
  19. package/examples/platformer/game.js +6 -6
  20. package/examples/platformer/gameCharacter.js +293 -0
  21. package/examples/platformer/gameEffects.js +8 -5
  22. package/examples/platformer/gameObjects.js +13 -13
  23. package/examples/platformer/gamePlayer.js +9 -293
  24. package/examples/platformer/index.html +7 -6
  25. package/examples/puzzle/game.js +3 -2
  26. package/examples/puzzle/index.html +2 -2
  27. package/examples/starter/build.js +1 -1
  28. package/examples/starter/game.js +2 -2
  29. package/examples/starter/index.html +13 -13
  30. package/examples/stress/index.html +35 -27
  31. package/examples/typescript/index.html +1 -1
  32. package/index.d.ts +2094 -0
  33. package/package.json +1 -1
  34. package/src/engine.js +28 -28
  35. package/src/engineAudio.js +57 -57
  36. package/src/engineDebug.js +66 -65
  37. package/src/engineDraw.js +64 -73
  38. package/src/engineExport.js +1 -0
  39. package/src/engineInput.js +57 -40
  40. package/src/engineMedals.js +32 -29
  41. package/src/engineObject.js +42 -27
  42. package/src/engineParticles.js +98 -72
  43. package/src/engineRelease.js +1 -1
  44. package/src/engineSettings.js +22 -22
  45. package/src/engineTileLayer.js +66 -60
  46. package/src/engineUtilities.js +49 -49
  47. package/src/engineWebGL.js +112 -135
  48. package/src/jsconfig.json +10 -0
@@ -10,28 +10,37 @@
10
10
  'use strict';
11
11
 
12
12
  /** Returns true if device key is down
13
- * @param {Number} key
14
- * @param {Number} [device=0]
13
+ * @param {String|Number} key
14
+ * @param {Number} [device]
15
15
  * @return {Boolean}
16
16
  * @memberof Input */
17
17
  function keyIsDown(key, device=0)
18
- { return inputData[device] && inputData[device][key] & 1; }
18
+ {
19
+ ASSERT(device > 0 || typeof key !== 'number' || key < 3, 'use code string for keyboard');
20
+ return inputData[device] && !!(inputData[device][key] & 1);
21
+ }
19
22
 
20
23
  /** Returns true if device key was pressed this frame
21
- * @param {Number} key
22
- * @param {Number} [device=0]
24
+ * @param {String|Number} key
25
+ * @param {Number} [device]
23
26
  * @return {Boolean}
24
27
  * @memberof Input */
25
28
  function keyWasPressed(key, device=0)
26
- { return inputData[device] && inputData[device][key] & 2 ? 1 : 0; }
29
+ {
30
+ ASSERT(device > 0 || typeof key !== 'number' || key < 3, 'use code string for keyboard');
31
+ return inputData[device] && !!(inputData[device][key] & 2);
32
+ }
27
33
 
28
34
  /** Returns true if device key was released this frame
29
- * @param {Number} key
30
- * @param {Number} [device=0]
35
+ * @param {String|Number} key
36
+ * @param {Number} [device]
31
37
  * @return {Boolean}
32
38
  * @memberof Input */
33
39
  function keyWasReleased(key, device=0)
34
- { return inputData[device] && inputData[device][key] & 4 ? 1 : 0; }
40
+ {
41
+ ASSERT(device > 0 || typeof key !== 'number' || key < 3, 'use code string for keyboard');
42
+ return inputData[device] && !!(inputData[device][key] & 4);
43
+ }
35
44
 
36
45
  /** Clears all input
37
46
  * @memberof Input */
@@ -76,16 +85,16 @@ let mouseWheel = 0;
76
85
  /** Returns true if user is using gamepad (has more recently pressed a gamepad button)
77
86
  * @type {Boolean}
78
87
  * @memberof Input */
79
- let isUsingGamepad = 0;
88
+ let isUsingGamepad = false;
80
89
 
81
90
  /** Prevents input continuing to the default browser handling (false by default)
82
91
  * @type {Boolean}
83
92
  * @memberof Input */
84
- let preventDefaultInput = 0;
93
+ let preventDefaultInput = false;
85
94
 
86
95
  /** Returns true if gamepad button is down
87
96
  * @param {Number} button
88
- * @param {Number} [gamepad=0]
97
+ * @param {Number} [gamepad]
89
98
  * @return {Boolean}
90
99
  * @memberof Input */
91
100
  function gamepadIsDown(button, gamepad=0)
@@ -93,7 +102,7 @@ function gamepadIsDown(button, gamepad=0)
93
102
 
94
103
  /** Returns true if gamepad button was pressed
95
104
  * @param {Number} button
96
- * @param {Number} [gamepad=0]
105
+ * @param {Number} [gamepad]
97
106
  * @return {Boolean}
98
107
  * @memberof Input */
99
108
  function gamepadWasPressed(button, gamepad=0)
@@ -101,7 +110,7 @@ function gamepadWasPressed(button, gamepad=0)
101
110
 
102
111
  /** Returns true if gamepad button was released
103
112
  * @param {Number} button
104
- * @param {Number} [gamepad=0]
113
+ * @param {Number} [gamepad]
105
114
  * @return {Boolean}
106
115
  * @memberof Input */
107
116
  function gamepadWasReleased(button, gamepad=0)
@@ -109,7 +118,7 @@ function gamepadWasReleased(button, gamepad=0)
109
118
 
110
119
  /** Returns gamepad stick value
111
120
  * @param {Number} stick
112
- * @param {Number} [gamepad=0]
121
+ * @param {Number} [gamepad]
113
122
  * @return {Vector2}
114
123
  * @memberof Input */
115
124
  function gamepadStick(stick, gamepad=0)
@@ -152,9 +161,10 @@ function inputUpdatePost()
152
161
  if (debug && e.target != document.body) return;
153
162
  if (!e.repeat)
154
163
  {
155
- inputData[isUsingGamepad = 0][e.which] = 3;
164
+ isUsingGamepad = false;
165
+ inputData[0][e.code] = 3;
156
166
  if (inputWASDEmulateDirection)
157
- inputData[0][remapKey(e.which)] = 3;
167
+ inputData[0][remapKey(e.code)] = 3;
158
168
  }
159
169
  preventDefaultInput && e.preventDefault();
160
170
  }
@@ -162,26 +172,29 @@ function inputUpdatePost()
162
172
  onkeyup = (e)=>
163
173
  {
164
174
  if (debug && e.target != document.body) return;
165
- inputData[0][e.which] = 4;
175
+ inputData[0][e.code] = 4;
166
176
  if (inputWASDEmulateDirection)
167
- inputData[0][remapKey(e.which)] = 4;
177
+ inputData[0][remapKey(e.code)] = 4;
168
178
  }
169
179
 
170
180
  // handle remapping wasd keys to directions
171
181
  function remapKey(c)
172
- {
182
+ {
173
183
  return inputWASDEmulateDirection ?
174
- c==87?38 : c==83?40 : c==65?37 : c==68?39 : c : c;
184
+ c == 'KeyW' ? 'ArrowUp' :
185
+ c == 'KeyS' ? 'ArrowDown' :
186
+ c == 'KeyA' ? 'ArrowLeft' :
187
+ c == 'KeyD' ? 'ArrowRight' : c : c;
175
188
  }
176
189
  }
177
190
 
178
191
  ///////////////////////////////////////////////////////////////////////////////
179
192
  // Mouse event handlers
180
193
 
181
- onmousedown = (e)=> {inputData[isUsingGamepad = 0][e.button] = 3; onmousemove(e); e.button && e.preventDefault();}
194
+ onmousedown = (e)=> {isUsingGamepad = false; inputData[0][e.button] = 3; mousePosScreen = mouseToScreen(e); e.button && e.preventDefault();}
182
195
  onmouseup = (e)=> inputData[0][e.button] = inputData[0][e.button] & 2 | 4;
183
196
  onmousemove = (e)=> mousePosScreen = mouseToScreen(e);
184
- onwheel = (e)=> e.ctrlKey || (mouseWheel = sign(e.deltaY));
197
+ onwheel = (e)=> mouseWheel = e.ctrlKey ? 0 : sign(e.deltaY);
185
198
  oncontextmenu = (e)=> false; // prevent right click menu
186
199
 
187
200
  // convert a mouse or touch event position to screen space
@@ -219,7 +232,7 @@ function gamepadsUpdate()
219
232
  for (let i=10; i--;)
220
233
  {
221
234
  const j = i == 3 ? 2 : i == 2 ? 3 : i; // fix button locations
222
- data[j] = touchGamepadButtons[i] ? 1 + 2*!gamepadIsDown(j,0) : 4*gamepadIsDown(j,0);
235
+ data[j] = touchGamepadButtons[i] ? gamepadIsDown(j,0) ? 1 : 3 : gamepadIsDown(j,0) ? 4 : 0;
223
236
  }
224
237
  }
225
238
  }
@@ -251,18 +264,23 @@ function gamepadsUpdate()
251
264
  for (let j = gamepad.buttons.length; j--;)
252
265
  {
253
266
  const button = gamepad.buttons[j];
254
- data[j] = button.pressed ? 1 + 2*!gamepadIsDown(j,i) : 4*gamepadIsDown(j,i);
255
- isUsingGamepad |= !i && button.pressed;
256
- touchGamepadEnable && touchGamepadTimer.unset(); // disable touch gamepad if using real gamepad
267
+ const wasDown = gamepadIsDown(j,i);
268
+ data[j] = button.pressed ? wasDown ? 1 : 3 : wasDown ? 4 : 0;
269
+ isUsingGamepad ||= !i && button.pressed;
257
270
  }
258
271
 
259
272
  if (gamepadDirectionEmulateStick)
260
273
  {
261
274
  // copy dpad to left analog stick when pressed
262
- const dpad = vec2(gamepadIsDown(15,i) - gamepadIsDown(14,i), gamepadIsDown(12,i) - gamepadIsDown(13,i));
275
+ const dpad = vec2(
276
+ (gamepadIsDown(15,i)&&1) - (gamepadIsDown(14,i)&&1),
277
+ (gamepadIsDown(12,i)&&1) - (gamepadIsDown(13,i)&&1));
263
278
  if (dpad.lengthSquared())
264
279
  sticks[0] = dpad.clampLength();
265
280
  }
281
+
282
+ // disable touch gamepad if using real gamepad
283
+ touchGamepadEnable && isUsingGamepad && touchGamepadTimer.unset();
266
284
  }
267
285
  }
268
286
  }
@@ -270,9 +288,9 @@ function gamepadsUpdate()
270
288
  ///////////////////////////////////////////////////////////////////////////////
271
289
 
272
290
  /** Pulse the vibration hardware if it exists
273
- * @param {Number} [pattern=100] - a single value in miliseconds or vibration interval array
291
+ * @param {Number|Array} [pattern] - single value in ms or vibration interval array
274
292
  * @memberof Input */
275
- function vibrate(pattern)
293
+ function vibrate(pattern=100)
276
294
  { vibrateEnable && navigator && navigator.vibrate && navigator.vibrate(pattern); }
277
295
 
278
296
  /** Cancel any ongoing vibration
@@ -290,29 +308,28 @@ const isTouchDevice = window.ontouchstart !== undefined;
290
308
  if (isTouchDevice)
291
309
  {
292
310
  // override mouse events
293
- let wasTouching, mouseDown = onmousedown, mouseUp = onmouseup;
311
+ let wasTouching;
294
312
  onmousedown = onmouseup = ()=> 0;
295
313
 
296
314
  // handle all touch events the same way
297
315
  ontouchstart = ontouchmove = ontouchend = (e)=>
298
316
  {
299
- e.button = 0; // all touches are left click
300
-
301
317
  // fix stalled audio on mobile
302
318
  if (soundEnable)
303
319
  audioContext ? audioContext.resume() : zzfx(0);
304
320
 
305
321
  // check if touching and pass to mouse events
306
322
  const touching = e.touches.length;
323
+ const button = 0; // all touches are left mouse button
307
324
  if (touching)
308
325
  {
309
326
  // set event pos and pass it along
310
- e.x = e.touches[0].clientX;
311
- e.y = e.touches[0].clientY;
312
- wasTouching ? onmousemove(e) : mouseDown(e);
327
+ const p = vec2(e.touches[0].clientX, e.touches[0].clientY);
328
+ mousePosScreen = mouseToScreen(p);
329
+ wasTouching ? isUsingGamepad = false : inputData[0][button] = 3;
313
330
  }
314
331
  else if (wasTouching)
315
- mouseUp(e);
332
+ inputData[0][button] = inputData[0][button] & 2 | 4;
316
333
 
317
334
  // set was touching
318
335
  wasTouching = touching;
@@ -393,8 +410,8 @@ function createTouchGamepad()
393
410
  }
394
411
 
395
412
  // call default touch handler and set to using gamepad
396
- touchHandler(e);
397
- isUsingGamepad = 1;
413
+ touchHandler.bind(window)(e);
414
+ isUsingGamepad = true;
398
415
 
399
416
  // must return true so the document will get focus
400
417
  return true;
@@ -408,7 +425,7 @@ function touchGamepadRender()
408
425
  return;
409
426
 
410
427
  // fade off when not touching or paused
411
- const alpha = percent(touchGamepadTimer, 4, 3);
428
+ const alpha = percent(touchGamepadTimer.get(), 4, 3);
412
429
  if (!alpha || paused)
413
430
  return;
414
431
 
@@ -48,7 +48,7 @@ class Medal
48
48
  * @param {Number} id - The unique identifier of the medal
49
49
  * @param {String} name - Name of the medal
50
50
  * @param {String} [description] - Description of the medal
51
- * @param {String} [icon='🏆'] - Icon for the medal
51
+ * @param {String} [icon] - Icon for the medal
52
52
  * @param {String} [src] - Image location for the medal
53
53
  */
54
54
  constructor(id, name, description='', icon='🏆', src)
@@ -71,14 +71,14 @@ class Medal
71
71
  return;
72
72
 
73
73
  // save the medal
74
- ASSERT(medalsSaveName); // save name must be set
74
+ ASSERT(medalsSaveName, 'save name must be set');
75
75
  localStorage[this.storageKey()] = this.unlocked = 1;
76
76
  medalsDisplayQueue.push(this);
77
77
  newgrounds && newgrounds.unlockMedal(this.id);
78
78
  }
79
79
 
80
80
  /** Render a medal
81
- * @param {Number} [hidePercent=0] - How much to slide the medal off screen
81
+ * @param {Number} [hidePercent] - How much to slide the medal off screen
82
82
  */
83
83
  render(hidePercent=0)
84
84
  {
@@ -90,25 +90,25 @@ class Medal
90
90
  // draw containing rect and clip to that region
91
91
  context.save();
92
92
  context.beginPath();
93
- context.fillStyle = new Color(.9,.9,.9);
94
- context.strokeStyle = new Color(0,0,0);
93
+ context.fillStyle = rgb(.9,.9,.9).toString();
94
+ context.strokeStyle = rgb(0,0,0).toString();
95
95
  context.lineWidth = 3;
96
- context.fill(context.rect(x, y, width, medalDisplaySize.y));
96
+ context.rect(x, y, width, medalDisplaySize.y);
97
+ context.fill();
97
98
  context.stroke();
98
99
  context.clip();
99
100
 
100
101
  // draw the icon and text
101
102
  this.renderIcon(vec2(x+15+medalDisplayIconSize/2, y+medalDisplaySize.y/2));
102
103
  const pos = vec2(x+medalDisplayIconSize+30, y+28);
103
- drawTextScreen(this.name, pos, 38, new Color(0,0,0), 0, 0, 'left');
104
+ drawTextScreen(this.name, pos, 38, new Color(0,0,0), 0, undefined, 'left');
104
105
  pos.y += 32;
105
- drawTextScreen(this.description, pos, 24, new Color(0,0,0), 0, 0, 'left');
106
+ drawTextScreen(this.description, pos, 24, new Color(0,0,0), 0, undefined, 'left');
106
107
  context.restore();
107
108
  }
108
109
 
109
110
  /** Render the icon for a medal
110
- * @param {Number} x - Screen space X position
111
- * @param {Number} y - Screen space Y position
111
+ * @param {Vector2} pos - Screen space position
112
112
  * @param {Number} [size=medalDisplayIconSize] - Screen space size
113
113
  */
114
114
  renderIcon(pos, size=medalDisplayIconSize)
@@ -136,7 +136,10 @@ function medalsRender()
136
136
  if (!medalsDisplayTimeLast)
137
137
  medalsDisplayTimeLast = timeReal;
138
138
  else if (time > medalDisplayTime)
139
- medalsDisplayQueue.shift(medalsDisplayTimeLast = 0);
139
+ {
140
+ medalsDisplayTimeLast = 0;
141
+ medalsDisplayQueue.shift();
142
+ }
140
143
  else
141
144
  {
142
145
  // slide on/off medals
@@ -176,8 +179,8 @@ class Newgrounds
176
179
  * @param {Object} [cryptoJS] - An instance of CryptoJS, if there is a cipher */
177
180
  constructor(app_id, cipher, cryptoJS)
178
181
  {
179
- ASSERT(!newgrounds && app_id); // can only be one newgrounds object
180
- ASSERT(!cipher || cryptoJS); // must provide cryptojs if there is a cipher
182
+ ASSERT(!newgrounds && app_id>0, 'there can only be one newgrounds object');
183
+ ASSERT(!cipher || cryptoJS, 'must provide cryptojs if there is a cipher');
181
184
 
182
185
  this.app_id = app_id;
183
186
  this.cipher = cipher;
@@ -220,39 +223,39 @@ class Newgrounds
220
223
  debugMedals && console.log(this.scoreboards);
221
224
 
222
225
  const keepAliveMS = 5 * 60 * 1e3;
223
- setInterval(()=>this.call('Gateway.ping', 0, 1), keepAliveMS);
226
+ setInterval(()=>this.call('Gateway.ping', 0, true), keepAliveMS);
224
227
  }
225
228
 
226
229
  /** Send message to unlock a medal by id
227
230
  * @param {Number} id - The medal id */
228
- unlockMedal(id) { return this.call('Medal.unlock', {'id':id}, 1); }
231
+ unlockMedal(id) { return this.call('Medal.unlock', {'id':id}, true); }
229
232
 
230
233
  /** Send message to post score
231
234
  * @param {Number} id - The scoreboard id
232
235
  * @param {Number} value - The score value */
233
- postScore(id, value) { return this.call('ScoreBoard.postScore', {'id':id, 'value':value}, 1); }
236
+ postScore(id, value) { return this.call('ScoreBoard.postScore', {'id':id, 'value':value}, true); }
234
237
 
235
238
  /** Get scores from a scoreboard
236
- * @param {Number} id - The scoreboard id
237
- * @param {String} [user=0] - A user's id or name
238
- * @param {Number} [social=0] - If true, only social scores will be loaded
239
- * @param {Number} [skip=0] - Number of scores to skip before start
240
- * @param {Number} [limit=10] - Number of scores to include in the list
241
- * @return {Object} - The response JSON object
239
+ * @param {Number} id - The scoreboard id
240
+ * @param {String} [user] - A user's id or name
241
+ * @param {Number} [social] - If true, only social scores will be loaded
242
+ * @param {Number} [skip] - Number of scores to skip before start
243
+ * @param {Number} [limit] - Number of scores to include in the list
244
+ * @return {Object} - The response JSON object
242
245
  */
243
- getScores(id, user=0, social=0, skip=0, limit=10)
246
+ getScores(id, user, social=0, skip=0, limit=10)
244
247
  { return this.call('ScoreBoard.getScores', {'id':id, 'user':user, 'social':social, 'skip':skip, 'limit':limit}); }
245
248
 
246
249
  /** Send message to log a view */
247
- logView() { return this.call('App.logView', {'host':this.host}, 1); }
250
+ logView() { return this.call('App.logView', {'host':this.host}, true); }
248
251
 
249
252
  /** Send a message to call a component of the Newgrounds API
250
- * @param {String} component - Name of the component
251
- * @param {Object} [parameters=0] - Parameters to use for call
252
- * @param {Boolean} [async=0] - If true, don't wait for response before continuing (avoid stall)
253
- * @return {Object} - The response JSON object
253
+ * @param {String} component - Name of the component
254
+ * @param {Object} [parameters] - Parameters to use for call
255
+ * @param {Boolean} [async] - If true, don't wait for response before continuing
256
+ * @return {Object} - The response JSON object
254
257
  */
255
- call(component, parameters=0, async=0)
258
+ call(component, parameters, async=false)
256
259
  {
257
260
  const call = {'component':component, 'parameters':parameters};
258
261
  if (this.cipher)
@@ -32,27 +32,25 @@
32
32
  class EngineObject
33
33
  {
34
34
  /** Create an engine object and adds it to the list of objects
35
- * @param {Vector2} [pos=Vector2()] - World space position of the object
36
- * @param {Vector2} [size=Vector2(1,1)] - World space size of the object
37
- * @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
38
- * @param {Number} [angle=0] - Angle the object is rotated by
39
- * @param {Color} [color=Color()] - Color to apply to tile when rendered
40
- * @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
35
+ * @param {Vector2} [pos=(0,0)] - World space position of the object
36
+ * @param {Vector2} [size=(1,1)] - World space size of the object
37
+ * @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
38
+ * @param {Number} [angle] - Angle the object is rotated by
39
+ * @param {Color} [color=(1,1,1,1)] - Color to apply to tile when rendered
40
+ * @param {Number} [renderOrder] - Objects sorted by renderOrder before being rendered
41
41
  */
42
42
  constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color, renderOrder=0)
43
43
  {
44
44
  // set passed in params
45
- ASSERT(isVector2(pos) && isVector2(size)); // ensure pos and size are vec2s
46
- ASSERT(typeof tileInfo !== 'number' || !tileInfo); // prevent old style calls
47
- ASSERT(!(renderOrder instanceof Color)); // prevent old style calls
48
- // to fix old calls, replace with tile(tileIndex, tileSize)
45
+ ASSERT(isVector2(pos) && isVector2(size), 'ensure pos and size are vec2s');
46
+ ASSERT(typeof tileInfo !== 'number' || !tileInfo, 'old style tile setup');
49
47
 
50
48
  /** @property {Vector2} - World space position of the object */
51
49
  this.pos = pos.copy();
52
50
  /** @property {Vector2} - World space width and height of the object */
53
51
  this.size = size;
54
52
  /** @property {Vector2} - Size of object used for drawing, uses size if not set */
55
- this.drawSize;
53
+ this.drawSize = undefined;
56
54
  /** @property {TileInfo} - Tile info to render object (undefined is untextured) */
57
55
  this.tileInfo = tileInfo;
58
56
  /** @property {Number} - Angle to rotate the object */
@@ -60,9 +58,11 @@ class EngineObject
60
58
  /** @property {Color} - Color to apply when rendered */
61
59
  this.color = color;
62
60
  /** @property {Color} - Additive color to apply when rendered */
63
- this.additiveColor;
61
+ this.additiveColor = undefined;
62
+ /** @property {Boolean} - Should it flip along y axis when rendered */
63
+ this.mirror = false;
64
64
 
65
- // set object defaults
65
+ // physical properties
66
66
  /** @property {Number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
67
67
  this.mass = objectDefaultMass;
68
68
  /** @property {Number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
@@ -73,19 +73,34 @@ class EngineObject
73
73
  this.elasticity = objectDefaultElasticity;
74
74
  /** @property {Number} [friction=objectDefaultFriction] - How much friction to apply when sliding (0-1) */
75
75
  this.friction = objectDefaultFriction;
76
- /** @property {Number} [gravityScale=1] - How much to scale gravity by for this object */
76
+ /** @property {Number} - How much to scale gravity by for this object */
77
77
  this.gravityScale = 1;
78
- /** @property {Number} [renderOrder=0] - Objects are sorted by render order */
78
+ /** @property {Number} - Objects are sorted by render order */
79
79
  this.renderOrder = renderOrder;
80
- /** @property {Vector2} [velocity=Vector2()] - Velocity of the object */
80
+ /** @property {Vector2} - Velocity of the object */
81
81
  this.velocity = vec2();
82
- /** @property {Number} [angleVelocity=0] - Angular velocity of the object */
82
+ /** @property {Number} - Angular velocity of the object */
83
83
  this.angleVelocity = 0;
84
-
85
- // init other internal object stuff
84
+ /** @property {Number} - Track when object was created */
86
85
  this.spawnTime = time;
86
+ /** @property {Array} - List of children of this object */
87
87
  this.children = [];
88
+
89
+ // parent child system
90
+ /** @property {EngineObject} - Parent of object if in local space */
91
+ this.parent = undefined;
92
+ /** @property {Vector2} - Local position if child */
93
+ this.localPos = vec2();
94
+ /** @property {Number} - Local angle if child */
95
+ this.localAngle = 0;
96
+
97
+ // collision flags
98
+ /** @property {Boolean} - Object collides with the tile collision */
88
99
  this.collideTiles = false;
100
+ /** @property {Boolean} - Object collides with solid objects */
101
+ this.collideSolidObjects = false;
102
+ /** @property {Boolean} - Object collides with and blocks other objects */
103
+ this.isSolid = false;
89
104
 
90
105
  // add to list of objects
91
106
  engineObjects.push(this);
@@ -302,7 +317,7 @@ class EngineObject
302
317
  * @param {EngineObject} object - the object to test against
303
318
  * @return {Boolean} - true if the collision should be resolved
304
319
  */
305
- collideWithObject(object) { return 1; }
320
+ collideWithObject(object) { return true; }
306
321
 
307
322
  /** How long since the object was created
308
323
  * @return {Number} */
@@ -322,8 +337,8 @@ class EngineObject
322
337
 
323
338
  /** Attaches a child to this with a given local transform
324
339
  * @param {EngineObject} child
325
- * @param {Vector2} [localPos=Vector2()]
326
- * @param {Number} [localAngle=0] */
340
+ * @param {Vector2} [localPos=(0,0)]
341
+ * @param {Number} [localAngle] */
327
342
  addChild(child, localPos=vec2(), localAngle=0)
328
343
  {
329
344
  ASSERT(!child.parent && !this.children.includes(child));
@@ -343,12 +358,12 @@ class EngineObject
343
358
  }
344
359
 
345
360
  /** Set how this object collides
346
- * @param {Boolean} [collideSolidObjects=1] - Does it collide with solid objects
347
- * @param {Boolean} [isSolid=1] - Does it collide with and block other objects (expensive in large numbers)
348
- * @param {Boolean} [collideTiles=1] - Does it collide with the tile collision */
349
- setCollision(collideSolidObjects=1, isSolid=1, collideTiles=1)
361
+ * @param {Boolean} [collideSolidObjects] - Does it collide with solid objects
362
+ * @param {Boolean} [isSolid] - Does it collide with and block other objects (expensive in large numbers)
363
+ * @param {Boolean} [collideTiles] - Does it collide with the tile collision */
364
+ setCollision(collideSolidObjects=true, isSolid=true, collideTiles=true)
350
365
  {
351
- ASSERT(collideSolidObjects || !isSolid); // solid objects must be set to collide
366
+ ASSERT(collideSolidObjects || !isSolid, 'solid objects must be set to collide');
352
367
 
353
368
  this.collideSolidObjects = collideSolidObjects;
354
369
  this.isSolid = isSolid;