littlejsengine 1.9.4 → 1.9.6

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.
@@ -5,6 +5,6 @@
5
5
  <link rel=icon type=image/png href=../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../dist/littlejs.js?192></script>
9
- <script src=gameObjects.js?192></script>
10
- <script src=game.js?192></script>
8
+ <script src=../../dist/littlejs.js?196></script>
9
+ <script src=gameObjects.js?196></script>
10
+ <script src=game.js?196></script>
@@ -5,5 +5,5 @@
5
5
  <link rel=icon type=image/png href=../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../dist/littlejs.js?192></script>
9
- <script src=game.js?192></script>
8
+ <script src=../../dist/littlejs.js?196></script>
9
+ <script src=game.js?196></script>
@@ -6,7 +6,7 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- LittleJS Engine -->
9
- <script src=../../dist/littlejs.js?192></script>
9
+ <script src=../../dist/littlejs.js?196></script>
10
10
 
11
11
  <!-- Add your game scripts here -->
12
- <script src=game.js?192></script>
12
+ <script src=game.js?196></script>
@@ -95,6 +95,7 @@ function htmlBuildStep(filename)
95
95
 
96
96
  // create html file
97
97
  let buffer = '';
98
+ buffer += '<body>';
98
99
  buffer += '<script>';
99
100
  buffer += fs.readFileSync(filename);
100
101
  buffer += '</script>';
@@ -1,18 +1,18 @@
1
1
  <head><title>LittleJS JS13K Project</title></head><body>
2
2
 
3
3
  <!-- LittleJS Engine -->
4
- <script src=../../src/engineDebug.js?192></script>
5
- <script src=../../src/engineUtilities.js?192></script>
6
- <script src=../../src/engineSettings.js?192></script>
7
- <script src=../../src/engineObject.js?192></script>
8
- <script src=../../src/engineDraw.js?192></script>
9
- <script src=../../src/engineInput.js?192></script>
10
- <script src=../../src/engineAudio.js?192></script>
11
- <script src=../../src/engineTileLayer.js?192></script>
12
- <script src=../../src/engineParticles.js?192></script>
13
- <script src=../../src/engineMedals.js?192></script>
14
- <script src=../../src/engineWebGL.js?192></script>
15
- <script src=../../src/engine.js?192></script>
4
+ <script src=../../src/engineDebug.js?196></script>
5
+ <script src=../../src/engineUtilities.js?196></script>
6
+ <script src=../../src/engineSettings.js?196></script>
7
+ <script src=../../src/engineObject.js?196></script>
8
+ <script src=../../src/engineDraw.js?196></script>
9
+ <script src=../../src/engineInput.js?196></script>
10
+ <script src=../../src/engineAudio.js?196></script>
11
+ <script src=../../src/engineTileLayer.js?196></script>
12
+ <script src=../../src/engineParticles.js?196></script>
13
+ <script src=../../src/engineMedals.js?196></script>
14
+ <script src=../../src/engineWebGL.js?196></script>
15
+ <script src=../../src/engine.js?196></script>
16
16
 
17
17
  <!-- Add your game scripts here -->
18
- <script src=game.js?192></script>
18
+ <script src=game.js?196></script>
@@ -6,4 +6,4 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- Add your game scripts here -->
9
- <script src=game.js?192 type=module></script>
9
+ <script src=game.js?196 type=module></script>
@@ -9,7 +9,7 @@ button { margin:1px; }
9
9
  </style>
10
10
  </head><body>
11
11
 
12
- <script src=../../dist/littlejs.js?192></script>
12
+ <script src=../../dist/littlejs.js?196></script>
13
13
  <script>
14
14
 
15
15
  'use strict';
@@ -130,14 +130,13 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
130
130
 
131
131
  // destroy tile
132
132
  const tileType = getTileCollisionData(pos);
133
-
134
- if (!tileType || tileType == tileType_solid)
133
+ if (!tileType)
135
134
  return 1;
136
135
 
137
136
  const tileLayer = tileLayers[foregroundLayerIndex];
138
137
  const centerPos = pos.add(vec2(.5));
139
138
  const layerData = tileLayer.getData(pos);
140
- if (!layerData)
139
+ if (!layerData || tileType == tileType_solid)
141
140
  return;
142
141
 
143
142
  // create effects
@@ -6,11 +6,11 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../dist/littlejs.js?192></script>
10
- <script src=gameObjects.js?192></script>
11
- <script src=gameCharacter.js?192></script>
12
- <script src=gamePlayer.js?192></script>
13
- <script src=gameEffects.js?192></script>
14
- <script src=gameLevel.js?192></script>
15
- <script src=gameLevelData.js?192></script>
16
- <script src=game.js?192></script>
9
+ <script src=../../dist/littlejs.js?196></script>
10
+ <script src=gameObjects.js?196></script>
11
+ <script src=gameCharacter.js?196></script>
12
+ <script src=gamePlayer.js?196></script>
13
+ <script src=gameEffects.js?196></script>
14
+ <script src=gameLevel.js?196></script>
15
+ <script src=gameLevelData.js?196></script>
16
+ <script src=game.js?196></script>
@@ -5,5 +5,5 @@
5
5
  <link rel=icon type=image/png href=../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../dist/littlejs.js?192></script>
9
- <script src=game.js?192></script>
8
+ <script src=../../dist/littlejs.js?196></script>
9
+ <script src=game.js?196></script>
@@ -6,18 +6,18 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- LittleJS Engine -->
9
- <script src=../../src/engineDebug.js?192></script>
10
- <script src=../../src/engineUtilities.js?192></script>
11
- <script src=../../src/engineSettings.js?192></script>
12
- <script src=../../src/engineObject.js?192></script>
13
- <script src=../../src/engineDraw.js?192></script>
14
- <script src=../../src/engineInput.js?192></script>
15
- <script src=../../src/engineAudio.js?192></script>
16
- <script src=../../src/engineTileLayer.js?192></script>
17
- <script src=../../src/engineParticles.js?192></script>
18
- <script src=../../src/engineMedals.js?192></script>
19
- <script src=../../src/engineWebGL.js?192></script>
20
- <script src=../../src/engine.js?192></script>
9
+ <script src=../../src/engineDebug.js?196></script>
10
+ <script src=../../src/engineUtilities.js?196></script>
11
+ <script src=../../src/engineSettings.js?196></script>
12
+ <script src=../../src/engineObject.js?196></script>
13
+ <script src=../../src/engineDraw.js?196></script>
14
+ <script src=../../src/engineInput.js?196></script>
15
+ <script src=../../src/engineAudio.js?196></script>
16
+ <script src=../../src/engineTileLayer.js?196></script>
17
+ <script src=../../src/engineParticles.js?196></script>
18
+ <script src=../../src/engineMedals.js?196></script>
19
+ <script src=../../src/engineWebGL.js?196></script>
20
+ <script src=../../src/engine.js?196></script>
21
21
 
22
22
  <!-- Add your game scripts here -->
23
- <script src=game.js?192></script>
23
+ <script src=game.js?196></script>
@@ -6,7 +6,7 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- LittleJS Engine -->
9
- <script src=../../dist/littlejs.min.js?192></script>
9
+ <script src=../../dist/littlejs.min.js?196></script>
10
10
  <script>
11
11
 
12
12
  /*
@@ -6,4 +6,4 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- Add your game scripts here -->
9
- <script src=game.js?192 type=module></script>
9
+ <script src=game.js?196 type=module></script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.9.4",
3
+ "version": "1.9.6",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "dist/littlejs.esm.js",
6
6
  "types": "dist/littlejs.d.ts",
package/reference.md CHANGED
@@ -13,13 +13,7 @@ To start LittleJS, you need to create a few functions and pass them to engineIni
13
13
 
14
14
  ```javascript
15
15
  // Start up LittleJS engine with your callback functions
16
- engineInit(init, update, updatePost, render, renderPost, imageSources=['tiles.png'])
17
-
18
- // Destroy and remove all objects
19
- engineObjectsDestroy()
20
-
21
- // Trigger a callback for each object within a given area
22
- engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
16
+ engineInit(init, update, updatePost, render, renderPost, imageSources=['tiles.png']);
23
17
  ```
24
18
 
25
19
  ## LittleJS Utilities Classes and Functions
@@ -53,6 +47,7 @@ lerpAngle(percent, angleA, angleB) // Linearly interpolates with wrap
53
47
  smoothStep(percent) // Applies smoothstep function
54
48
  nearestPowerOfTwo(value) // Returns the nearest power of two
55
49
  isOverlapping(pointA, sizeA, pointB, sizeB) // Checks if bounding boxes overlap
50
+ isIntersecting(start, end, pos, size) // Checks if ray intersects box
56
51
  wave(frequency=1, amplitude=1, t=time) // Returns oscillating wave
57
52
  formatTime(t) // Formats seconds for display
58
53
 
@@ -103,7 +98,7 @@ Color.scale(scale, alphaScale=scale) // Scale by a float
103
98
  Color.clamp() // Clamp this color
104
99
  Color.lerp(c, percent) // Interpolate between colors
105
100
  Color.setHSLA(h=0, s=0, l=1, a=1) // Set the color from HSLA values
106
- Color.getHSLA() // Get the color in HSLA format
101
+ Color.HSLA() // Get the color in HSLA format
107
102
  Color.mutate(amount=.05, alphaAmount=0) // Randomly diverge from this color
108
103
  Color.setHex(hex) // Set this color from a hex code
109
104
  Color.rgbaInt() // Get this color as 32 bit RGBA value
@@ -138,7 +133,6 @@ Timer.valueOf() // Get how long since elapsed, 0 if not set
138
133
  // Drawing functions
139
134
  drawTile(pos, size=(1,1), tileInfo, color, angle=0, mirror, additiveColor)
140
135
  drawRect(pos, size=(1,1), color=(1,1,1,1), angle=0)
141
- drawPoly(points, color=(1,1,1,1))
142
136
  drawLine(posA, posB, thickness=.1, color=(1,1,1,1))
143
137
  drawCanvas2D(pos, size, angle, mirror, drawFunction)
144
138
  drawText(text, pos, size=1, color=(1,1,1,1), lineWidth, lineColor)
@@ -153,6 +147,7 @@ TileInfo.pos // Top left corner of tile in pixels
153
147
  TileInfo.size // Size of tile in pixels
154
148
  TileInfo.textureIndex // Texture index to use
155
149
  TileInfo.offset(offset) // Offset this tile by a certain amount in pixels
150
+ TileInfo.frame(frame) // Offset this tile by a number of animation frames
156
151
  TileInfo.getTextureInfo() // Returns texture info for this tile
157
152
 
158
153
  // Texture Info Object
@@ -285,7 +280,6 @@ EngineObject.update() // Update object, called auto
285
280
  EngineObject.render() // Render object, called automatically
286
281
  EngineObject.destroy() // Destroy this object and children
287
282
  EngineObject.collideWithTile(tileData, pos) // Tile collision resolve check
288
- EngineObject.collideWithTileRaycast(tileData, pos) // Check if raycast hit
289
283
  EngineObject.collideWithObject(object) // Object collision resolve check
290
284
  EngineObject.getAliveTime(object) // How long since object was created
291
285
  EngineObject.applyAcceleration(acceleration) // Apply acceleration
@@ -314,7 +308,7 @@ EngineObject.renderOrder // Objects are sorted by render order
314
308
  EngineObject.velocity // Velocity of the object
315
309
  EngineObject.angleVelocity // Angular velocity of the object
316
310
 
317
- // Object settings
311
+ // Engine Object settings
318
312
  enablePhysicsSolver = true // Enable collisions between objects?
319
313
  objectDefaultMass = 1 // Default object mass for collisions
320
314
  objectDefaultDamping = 1 // How much to slow velocity by each frame (0-1)
@@ -323,6 +317,12 @@ objectDefaultElasticity = 0 // How much to bounce when a collision occurs (0-1
323
317
  objectDefaultFriction = .8 // How much to slow when touching (0-1)
324
318
  objectMaxSpeed = 1 // Clamp max speed to avoid fast objects missing collisions
325
319
  gravity = 0 // How much gravity to apply to objects
320
+
321
+ // Engine Object functions
322
+ engineObjectsCollect(pos, size, objects=engineObjects)k
323
+ engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
324
+ engineObjectsRaycast(start, end, objects=engineObjects)
325
+ engineObjectsDestroy()
326
326
  ```
327
327
 
328
328
  ## LittleJS Tile Layer System
package/src/engine.js CHANGED
@@ -30,7 +30,7 @@ const engineName = 'LittleJS';
30
30
  * @type {String}
31
31
  * @default
32
32
  * @memberof Engine */
33
- const engineVersion = '1.9.4';
33
+ const engineVersion = '1.9.6';
34
34
 
35
35
  /** Frames per second to update
36
36
  * @type {Number}
@@ -97,6 +97,19 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
97
97
  {
98
98
  ASSERT(Array.isArray(imageSources), 'pass in images as array');
99
99
 
100
+ // Called automatically by engine to setup render system
101
+ function enginePreRender()
102
+ {
103
+ // save canvas size
104
+ mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
105
+
106
+ // disable smoothing for pixel art
107
+ mainContext.imageSmoothingEnabled = !canvasPixelated;
108
+
109
+ // setup gl rendering if enabled
110
+ glPreRender();
111
+ }
112
+
100
113
  // internal update loop for engine
101
114
  function engineUpdate(frameTimeMS=0)
102
115
  {
@@ -113,11 +126,14 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
113
126
  frameTimeBufferMS += paused ? 0 : frameTimeDeltaMS;
114
127
  if (!debugSpeedUp)
115
128
  frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp in case of slow framerate
129
+
116
130
  updateCanvas();
117
131
 
118
132
  if (paused)
119
133
  {
120
- // do post update even when paused
134
+ // update object transforms even when paused
135
+ for (const o of engineObjects)
136
+ o.parent || o.updateTransforms();
121
137
  inputUpdate();
122
138
  debugUpdate();
123
139
  gameUpdatePost();
@@ -129,7 +145,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
129
145
  let deltaSmooth = 0;
130
146
  if (frameTimeBufferMS < 0 && frameTimeBufferMS > -9)
131
147
  {
132
- // force an update each frame if time is close enough (not just a fast refresh rate)
148
+ // force at least one update each frame since it is waiting for refresh
133
149
  deltaSmooth = frameTimeBufferMS;
134
150
  frameTimeBufferMS = 0;
135
151
  }
@@ -154,34 +170,37 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
154
170
  // add the time smoothing back in
155
171
  frameTimeBufferMS += deltaSmooth;
156
172
  }
157
-
158
- // render sort then render while removing destroyed objects
159
- enginePreRender();
160
- gameRender();
161
- engineObjects.sort((a,b)=> a.renderOrder - b.renderOrder);
162
- for (const o of engineObjects)
163
- o.destroyed || o.render();
164
- gameRenderPost();
165
- glRenderPostProcess();
166
- medalsRender();
167
- touchGamepadRender();
168
- debugRender();
169
- glEnable && glCopyToContext(mainContext);
170
-
171
- if (showWatermark)
173
+
174
+ if (!headlessMode)
172
175
  {
173
- // update fps
174
- overlayContext.textAlign = 'right';
175
- overlayContext.textBaseline = 'top';
176
- overlayContext.font = '1em monospace';
177
- overlayContext.fillStyle = '#000';
178
- const text = engineName + ' ' + 'v' + engineVersion + ' / '
179
- + drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
180
- + (glEnable ? ' GL' : ' 2D') ;
181
- overlayContext.fillText(text, mainCanvas.width-3, 3);
182
- overlayContext.fillStyle = '#fff';
183
- overlayContext.fillText(text, mainCanvas.width-2, 2);
184
- drawCount = 0;
176
+ // render sort then render while removing destroyed objects
177
+ enginePreRender();
178
+ gameRender();
179
+ engineObjects.sort((a,b)=> a.renderOrder - b.renderOrder);
180
+ for (const o of engineObjects)
181
+ o.destroyed || o.render();
182
+ gameRenderPost();
183
+ glRenderPostProcess();
184
+ medalsRender();
185
+ touchGamepadRender();
186
+ debugRender();
187
+ glCopyToContext(mainContext);
188
+
189
+ if (showWatermark)
190
+ {
191
+ // update fps
192
+ overlayContext.textAlign = 'right';
193
+ overlayContext.textBaseline = 'top';
194
+ overlayContext.font = '1em monospace';
195
+ overlayContext.fillStyle = '#000';
196
+ const text = engineName + ' ' + 'v' + engineVersion + ' / '
197
+ + drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
198
+ + (glEnable ? ' GL' : ' 2D') ;
199
+ overlayContext.fillText(text, mainCanvas.width-3, 3);
200
+ overlayContext.fillStyle = '#fff';
201
+ overlayContext.fillText(text, mainCanvas.width-2, 2);
202
+ drawCount = 0;
203
+ }
185
204
  }
186
205
 
187
206
  requestAnimationFrame(engineUpdate);
@@ -189,6 +208,8 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
189
208
 
190
209
  function updateCanvas()
191
210
  {
211
+ if (headlessMode) return;
212
+
192
213
  if (canvasFixedSize.x)
193
214
  {
194
215
  // clear canvas and set fixed size
@@ -216,8 +237,20 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
216
237
  mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
217
238
  }
218
239
 
240
+ function startEngine()
241
+ {
242
+ gameInit();
243
+ engineUpdate();
244
+ }
245
+
246
+ if (headlessMode)
247
+ {
248
+ startEngine();
249
+ return;
250
+ }
251
+
219
252
  // setup html
220
- const styleBody =
253
+ const styleBody =
221
254
  'margin:0;overflow:hidden;' + // fill the window
222
255
  'background:#000;' + // set background color
223
256
  'touch-action:none;' + // prevent mobile pinch to resize
@@ -229,8 +262,9 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
229
262
  mainContext = mainCanvas.getContext('2d');
230
263
 
231
264
  // init stuff and start engine
265
+ inputInit();
232
266
  debugInit();
233
- glEnable && glInit();
267
+ glInit();
234
268
 
235
269
  // create overlay canvas for hud to appear above gl canvas
236
270
  document.body.appendChild(overlayCanvas = document.createElement('canvas'));
@@ -254,7 +288,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
254
288
  }
255
289
  image.src = src;
256
290
  })
257
- )
291
+ );
258
292
 
259
293
  // draw splash screen
260
294
  showSplashScreen && promises.push(new Promise(resolve =>
@@ -271,25 +305,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
271
305
  }));
272
306
 
273
307
  // load all of the images
274
- Promise.all(promises).then(()=>
275
- {
276
- // start the engine
277
- gameInit();
278
- engineUpdate();
279
- });
280
- }
281
-
282
- // Called automatically by engine to setup render system
283
- function enginePreRender()
284
- {
285
- // save canvas size
286
- mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
287
-
288
- // disable smoothing for pixel art
289
- mainContext.imageSmoothingEnabled = !canvasPixelated;
290
-
291
- // setup gl rendering if enabled
292
- glEnable && glPreRender();
308
+ Promise.all(promises).then(startEngine);
293
309
  }
294
310
 
295
311
  /** Update each engine object, remove destroyed objects, and update time
@@ -310,7 +326,14 @@ function engineObjectsUpdate()
310
326
  }
311
327
  }
312
328
  for (const o of engineObjects)
313
- o.parent || updateObject(o);
329
+ {
330
+ // update top level objects
331
+ if (!o.parent)
332
+ {
333
+ updateObject(o);
334
+ o.updateTransforms();
335
+ }
336
+ }
314
337
 
315
338
  // remove destroyed objects
316
339
  engineObjects = engineObjects.filter(o=>!o.destroyed);
@@ -325,30 +348,63 @@ function engineObjectsDestroy()
325
348
  engineObjects = engineObjects.filter(o=>!o.destroyed);
326
349
  }
327
350
 
328
- /** Triggers a callback for each object within a given area
329
- * @param {Vector2} [pos] - Center of test area
351
+ /** Collects all object within a given area
352
+ * @param {Vector2} [pos] - Center of test area, or undefined for all objects
330
353
  * @param {Number|Vector2} [size] - Radius of circle if float, rectangle size if Vector2
331
- * @param {Function} [callbackFunction] - Calls this function on every object that passes the test
332
354
  * @param {Array} [objects=engineObjects] - List of objects to check
355
+ * @return {Array} - List of collected objects
333
356
  * @memberof Engine */
334
- function engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
357
+ function engineObjectsCollect(pos, size, objects=engineObjects)
335
358
  {
359
+ const collectedObjects = [];
336
360
  if (!pos) // all objects
337
361
  {
338
362
  for (const o of objects)
339
- callbackFunction(o);
363
+ collectedObjects.push(o);
340
364
  }
341
- else if (typeof size === 'object') // bounding box test
365
+ else if (size instanceof Vector2) // bounding box test
342
366
  {
343
367
  for (const o of objects)
344
- isOverlapping(pos, size, o.pos, o.size) && callbackFunction(o);
368
+ isOverlapping(pos, size, o.pos, o.size) && collectedObjects.push(o);
345
369
  }
346
370
  else // circle test
347
371
  {
348
372
  const sizeSquared = size*size;
349
373
  for (const o of objects)
350
- pos.distanceSquared(o.pos) < sizeSquared && callbackFunction(o);
374
+ pos.distanceSquared(o.pos) < sizeSquared && collectedObjects.push(o);
375
+ }
376
+ return collectedObjects;
377
+ }
378
+
379
+ /** Triggers a callback for each object within a given area
380
+ * @param {Vector2} [pos] - Center of test area, or undefined for all objects
381
+ * @param {Number|Vector2} [size] - Radius of circle if float, rectangle size if Vector2
382
+ * @param {Function} [callbackFunction] - Calls this function on every object that passes the test
383
+ * @param {Array} [objects=engineObjects] - List of objects to check
384
+ * @memberof Engine */
385
+ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
386
+ { engineObjectsCollect(pos, size, objects).forEach(o => callbackFunction(o)); }
387
+
388
+ /** Return a list of objects intersecting a ray
389
+ * @param {Vector2} start
390
+ * @param {Vector2} end
391
+ * @param {Array} [objects=engineObjects] - List of objects to check
392
+ * @return {Array} - List of objects hit
393
+ * @memberof Engine */
394
+ function engineObjectsRaycast(start, end, objects=engineObjects)
395
+ {
396
+ const hitObjects = [];
397
+ for (const o of objects)
398
+ {
399
+ if (o.collideRaycast && isIntersecting(start, end, o.pos, o.size))
400
+ {
401
+ debugRaycast && debugRect(o.pos, o.size, '#f00');
402
+ hitObjects.push(o);
403
+ }
351
404
  }
405
+
406
+ debugRaycast && debugLine(start, end, hitObjects.length ? '#f00' : '#00f', .02);
407
+ return hitObjects;
352
408
  }
353
409
 
354
410
  ///////////////////////////////////////////////////////////////////////////////
@@ -436,16 +492,16 @@ function drawEngineSplashScreen(t)
436
492
  rect(37,14,9,6);
437
493
 
438
494
  // big stack
439
- rect(50,20,10,-10,color(0,1));
440
- rect(50,20,6.5,-10,color(0,2));
441
- rect(50,20,3.5,-10,color(0,3));
442
- rect(50,20,10,-10);
443
- circle(55,2,11.4,.5,PI-.5,color(3,3));
444
- circle(55,2,11.4,.5,PI/2,color(3,2),1);
445
- circle(55,2,11.4,.5,PI-.5);
446
- rect(45,7,20,-7,color(0,2));
447
- rect(45,0,20,3,color(0,3));
448
- rect(45,0,20,7);
495
+ rect(50,20,10,-8,color(0,1))
496
+ rect(50,20,6.5,-8,color(0,2))
497
+ rect(50,20,3.5,-8,color(0,3))
498
+ rect(50,20,10,-8)
499
+ circle(55,2,11.4,.5,PI-.5,color(3,3))
500
+ circle(55,2,11.4,.5,PI/2,color(3,2),1)
501
+ circle(55,2,11.4,.5,PI-.5)
502
+ rect(45,7,20,-7,color(0,2))
503
+ rect(45,-1,20,4,color(0,3))
504
+ rect(45,-1,20,8)
449
505
 
450
506
  // engine
451
507
  for (let i=5; i--;)