littlejsengine 1.2.0 → 1.3.0
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.
- package/README.md +5 -9
- package/build.bat +5 -5
- package/buildSetup.bat +7 -0
- package/engine/engine.all.js +193 -125
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.release.js +183 -110
- package/engine/engine.js +10 -33
- package/engine/engineBuild.bat +3 -3
- package/engine/engineDebug.js +10 -15
- package/engine/engineDraw.js +38 -17
- package/engine/engineFont.png +0 -0
- package/engine/engineInput.js +22 -6
- package/engine/engineMedals.js +7 -4
- package/engine/engineObject.js +17 -1
- package/engine/engineParticles.js +5 -3
- package/engine/engineSettings.js +5 -0
- package/engine/engineTileLayer.js +11 -10
- package/engine/engineUtilities.js +38 -6
- package/engine/engineWebGL.js +30 -30
- package/engine/index.d.ts +55 -21
- package/examples/breakout/gameObjects.js +2 -2
- package/examples/breakout/index.html +3 -3
- package/examples/particles/index.html +366 -0
- package/examples/particles/tiles.png +0 -0
- package/examples/platformer/game.js +4 -4
- package/examples/platformer/gameEffects.js +9 -9
- package/examples/platformer/gameObjects.js +2 -2
- package/examples/platformer/index.html +6 -6
- package/examples/puzzle/game.js +2 -2
- package/examples/puzzle/index.html +2 -2
- package/examples/screenshot.jpg +0 -0
- package/examples/stress/index.html +2 -2
- package/game.js +4 -4
- package/index.html +13 -13
- package/package.json +1 -1
- package/engine/engineBuildSetup.bat +0 -7
package/engine/engineBuild.bat
CHANGED
|
@@ -79,7 +79,7 @@ copy engine.all.release.js %OUTPUT_FILENAME%
|
|
|
79
79
|
|
|
80
80
|
rem check code with closure
|
|
81
81
|
move %OUTPUT_FILENAME% %OUTPUT_FILENAME%.temp
|
|
82
|
-
call google-closure-compiler --js
|
|
82
|
+
call npx google-closure-compiler --js=%OUTPUT_FILENAME%.temp --js_output_file=%OUTPUT_FILENAME% --language_out=ECMASCRIPT_2019 --warning_level=VERBOSE --jscomp_off=*
|
|
83
83
|
del %OUTPUT_FILENAME%.temp
|
|
84
84
|
if %ERRORLEVEL% NEQ 0 (
|
|
85
85
|
pause
|
|
@@ -87,7 +87,7 @@ if %ERRORLEVEL% NEQ 0 (
|
|
|
87
87
|
)
|
|
88
88
|
|
|
89
89
|
rem lightly minify with uglify
|
|
90
|
-
call uglifyjs -o %OUTPUT_FILENAME% -- %OUTPUT_FILENAME%
|
|
90
|
+
call npx uglifyjs -o %OUTPUT_FILENAME% -- %OUTPUT_FILENAME%
|
|
91
91
|
if %ERRORLEVEL% NEQ 0 (
|
|
92
92
|
pause
|
|
93
93
|
exit /b %ERRORLEVEL%
|
|
@@ -95,7 +95,7 @@ if %ERRORLEVEL% NEQ 0 (
|
|
|
95
95
|
|
|
96
96
|
rem --- BUILD TYPESCRIPT DEFINITIONS ---
|
|
97
97
|
|
|
98
|
-
call tsc engine.all.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts
|
|
98
|
+
call npx tsc engine.all.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts
|
|
99
99
|
if %ERRORLEVEL% NEQ 0 (
|
|
100
100
|
pause
|
|
101
101
|
exit /b %ERRORLEVEL%
|
package/engine/engineDebug.js
CHANGED
|
@@ -160,7 +160,7 @@ const debugUpdate = ()=>
|
|
|
160
160
|
{
|
|
161
161
|
if (!debug)
|
|
162
162
|
return;
|
|
163
|
-
|
|
163
|
+
|
|
164
164
|
if (keyWasPressed(192)) // ~
|
|
165
165
|
debugOverlay = !debugOverlay;
|
|
166
166
|
if (debugOverlay)
|
|
@@ -273,17 +273,11 @@ const debugRender = ()=>
|
|
|
273
273
|
drawRect(mousePos.floor().add(vec2(.5)), vec2(1), new Color(0,0,1,.5));
|
|
274
274
|
drawLine(mousePos, bestObject.pos, .1, !raycastHitPos ? new Color(0,1,0,.5) : new Color(1,0,0,.5));
|
|
275
275
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
+ (bestObject.angle>0?' ':' ') + (bestObject.angle*180/PI).toFixed(1) + '°',
|
|
282
|
-
pos = pos.add(height), ...args);
|
|
283
|
-
drawText('vel = ' + printVec2(bestObject.velocity), pos = pos.add(height), ...args);
|
|
284
|
-
drawText('size = ' + printVec2(bestObject.size), pos = pos.add(height), ...args);
|
|
285
|
-
drawText('type = ' + ( bestObject.constructor.name), pos = mousePos.subtract(height), ...args);
|
|
286
|
-
drawText('collision = ' + getTileCollisionData(mousePos), pos = mousePos.subtract(height.scale(2)), ...args);
|
|
276
|
+
const debugText = 'mouse pos = ' + mousePos +
|
|
277
|
+
'\nmouse collision = ' + getTileCollisionData(mousePos) +
|
|
278
|
+
'\n\n--- object info ---\n' +
|
|
279
|
+
bestObject.toString();
|
|
280
|
+
drawTextScreen(debugText, mousePosScreen, 24, new Color, .05, undefined, undefined, 'monospace');
|
|
287
281
|
mainContext = saveContext;
|
|
288
282
|
}
|
|
289
283
|
|
|
@@ -292,11 +286,12 @@ const debugRender = ()=>
|
|
|
292
286
|
|
|
293
287
|
{
|
|
294
288
|
// draw debug primitives
|
|
295
|
-
overlayContext.save();
|
|
296
289
|
overlayContext.lineWidth = 2;
|
|
297
290
|
const pointSize = debugPointSize * cameraScale;
|
|
298
291
|
debugPrimitives.forEach(p=>
|
|
299
292
|
{
|
|
293
|
+
overlayContext.save();
|
|
294
|
+
|
|
300
295
|
// create canvas transform from world space to screen space
|
|
301
296
|
const pos = worldToScreen(p.pos);
|
|
302
297
|
|
|
@@ -332,12 +327,12 @@ const debugRender = ()=>
|
|
|
332
327
|
p.fill && overlayContext.fill();
|
|
333
328
|
overlayContext.stroke();
|
|
334
329
|
}
|
|
330
|
+
|
|
331
|
+
overlayContext.restore();
|
|
335
332
|
});
|
|
336
333
|
|
|
337
334
|
// remove expired pritives
|
|
338
335
|
debugPrimitives = debugPrimitives.filter(r=>r.time.get()<0);
|
|
339
|
-
|
|
340
|
-
overlayContext.restore();
|
|
341
336
|
}
|
|
342
337
|
|
|
343
338
|
{
|
package/engine/engineDraw.js
CHANGED
|
@@ -110,7 +110,7 @@ function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, col
|
|
|
110
110
|
if (tileIndex < 0)
|
|
111
111
|
{
|
|
112
112
|
// if negative tile index, force untextured
|
|
113
|
-
context.fillStyle = color
|
|
113
|
+
context.fillStyle = color;
|
|
114
114
|
context.fillRect(-.5, -.5, 1, 1);
|
|
115
115
|
}
|
|
116
116
|
else
|
|
@@ -215,7 +215,8 @@ function setBlendMode(additive, useWebGL=glEnable)
|
|
|
215
215
|
mainContext.globalCompositeOperation = additive ? 'lighter' : 'source-over';
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
/** Draw text on overlay canvas in
|
|
218
|
+
/** Draw text on overlay canvas in screen space
|
|
219
|
+
* Automatically splits new lines into rows
|
|
219
220
|
* @param {String} text
|
|
220
221
|
* @param {Vector2} pos
|
|
221
222
|
* @param {Number} [size=1]
|
|
@@ -224,20 +225,37 @@ function setBlendMode(additive, useWebGL=glEnable)
|
|
|
224
225
|
* @param {Color} [lineColor=new Color(0,0,0)]
|
|
225
226
|
* @param {String} [textAlign='center']
|
|
226
227
|
* @memberof Draw */
|
|
227
|
-
function
|
|
228
|
+
function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault)
|
|
228
229
|
{
|
|
229
|
-
|
|
230
|
-
overlayContext.
|
|
230
|
+
overlayContext.fillStyle = color;
|
|
231
|
+
overlayContext.lineWidth = lineWidth *= cameraScale;
|
|
232
|
+
overlayContext.strokeStyle = lineColor;
|
|
231
233
|
overlayContext.textAlign = textAlign;
|
|
234
|
+
overlayContext.font = size + 'px '+ font;
|
|
232
235
|
overlayContext.textBaseline = 'middle';
|
|
233
|
-
|
|
236
|
+
|
|
237
|
+
pos = pos.copy();
|
|
238
|
+
text.split('\n').forEach(line=>
|
|
234
239
|
{
|
|
235
|
-
overlayContext.
|
|
236
|
-
overlayContext.
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
lineWidth && overlayContext.strokeText(line, pos.x, pos.y);
|
|
241
|
+
overlayContext.fillText(line, pos.x, pos.y);
|
|
242
|
+
pos.y += size;
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** Draw text on overlay canvas in world space
|
|
247
|
+
* Automatically splits new lines into rows
|
|
248
|
+
* @param {String} text
|
|
249
|
+
* @param {Vector2} pos
|
|
250
|
+
* @param {Number} [size=1]
|
|
251
|
+
* @param {Color} [color=new Color(1,1,1)]
|
|
252
|
+
* @param {Number} [lineWidth=0]
|
|
253
|
+
* @param {Color} [lineColor=new Color(0,0,0)]
|
|
254
|
+
* @param {String} [textAlign='center']
|
|
255
|
+
* @memberof Draw */
|
|
256
|
+
function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, font)
|
|
257
|
+
{
|
|
258
|
+
drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth, lineColor, textAlign, font);
|
|
241
259
|
}
|
|
242
260
|
|
|
243
261
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -254,6 +272,9 @@ function drawText(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new
|
|
|
254
272
|
* // draw text
|
|
255
273
|
* font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));
|
|
256
274
|
*/
|
|
275
|
+
|
|
276
|
+
let engineFontImage;
|
|
277
|
+
|
|
257
278
|
class FontImage
|
|
258
279
|
{
|
|
259
280
|
/** Create an image font
|
|
@@ -265,14 +286,14 @@ class FontImage
|
|
|
265
286
|
*/
|
|
266
287
|
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), startTileIndex=0, context=overlayContext)
|
|
267
288
|
{
|
|
268
|
-
if (!image)
|
|
289
|
+
if (!image && !engineFontImage)
|
|
269
290
|
{
|
|
270
|
-
//
|
|
271
|
-
|
|
272
|
-
|
|
291
|
+
// load default font image
|
|
292
|
+
engineFontImage = new Image();
|
|
293
|
+
engineFontImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAAYAQAAAAA9+x6JAAAAAnRSTlMAAHaTzTgAAAGiSURBVHjaZZABhxxBEIUf6ECLBdFY+Q0PMNgf0yCgsSAGZcT9sgIPtBWwIA5wgAPEoHUyJeeSlW+gjK+fegWwtROWpVQEyWh2npdpBmTUFVhb29RINgLIukoXr5LIAvYQ5ve+1FqWEMqNKTX3FAJHyQDRZvmKWubAACcv5z5Gtg2oyCWE+Yk/8JZQX1jTTCpKAFGIgza+dJCNBF2UskRlsgwitHbSV0QLgt9sTPtsRlvJjEr8C/FARWA2bJ/TtJ7lko34dNDn6usJUMzuErP89UUBJbWeozrwLLncXczd508deAjLWipLO4Q5XGPcJvPu92cNDaN0P5G1FL0nSOzddZOrJ6rNhbXGmeDvO3TF7DeJWl4bvaYQTNHCTeuqKZmbjHaSOFes+IX/+IhHrnAkXOAsfn24EM68XieIECoccD4KZLk/odiwzeo2rovYdhvb2HYFgyznJyDpYJdYOmfXgVdJTaUi4xA2uWYNYec9BLeqdl9EsoTw582mSFDX2DxVLbNt9U3YYoeatBad1c2Tj8t2akrjaIGJNywKB/7h75/gN3vCMSaadIUTAAAAAElFTkSuQmCC';
|
|
273
294
|
}
|
|
274
295
|
|
|
275
|
-
this.image = image;
|
|
296
|
+
this.image = image || engineFontImage;
|
|
276
297
|
this.tileSize = tileSize;
|
|
277
298
|
this.paddingSize = paddingSize;
|
|
278
299
|
this.startTileIndex = startTileIndex;
|
|
Binary file
|
package/engine/engineInput.js
CHANGED
|
@@ -281,7 +281,7 @@ if (isTouchDevice)
|
|
|
281
281
|
// touch gamepad, virtual on screen gamepad emulator for touch devices
|
|
282
282
|
|
|
283
283
|
// touch input internal variables
|
|
284
|
-
let touchGamepadTimer = new Timer, touchGamepadButtons = [], touchGamepadStick = vec2()
|
|
284
|
+
let touchGamepadTimer = new Timer, touchGamepadButtons = [], touchGamepadStick = vec2();
|
|
285
285
|
|
|
286
286
|
// create the touch gamepad, called automatically by the engine
|
|
287
287
|
function touchGamepadCreate()
|
|
@@ -328,7 +328,7 @@ function touchGamepadCreate()
|
|
|
328
328
|
{
|
|
329
329
|
// virtual analog stick
|
|
330
330
|
if (touchGamepadAnalog)
|
|
331
|
-
touchGamepadStick = touchPos.subtract(stickCenter).
|
|
331
|
+
touchGamepadStick = touchPos.subtract(stickCenter).scale(2/touchGamepadSize).clampLength();
|
|
332
332
|
else
|
|
333
333
|
{
|
|
334
334
|
// 8 way dpad
|
|
@@ -369,12 +369,28 @@ function touchGamepadRender()
|
|
|
369
369
|
overlayContext.lineWidth = 3;
|
|
370
370
|
|
|
371
371
|
// draw left analog stick
|
|
372
|
-
overlayContext.fillStyle =
|
|
372
|
+
overlayContext.fillStyle = touchGamepadStick.lengthSquared() > 0 ? '#fff' : '#000';
|
|
373
373
|
overlayContext.beginPath();
|
|
374
|
-
overlayContext.arc(touchGamepadSize, mainCanvasSize.y-touchGamepadSize, touchGamepadSize/2, 0,9);
|
|
375
|
-
overlayContext.fill();
|
|
376
|
-
overlayContext.stroke();
|
|
377
374
|
|
|
375
|
+
const leftCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
376
|
+
if (touchGamepadAnalog)
|
|
377
|
+
{
|
|
378
|
+
overlayContext.arc(leftCenter.x, leftCenter.y, touchGamepadSize/2, 0, 9);
|
|
379
|
+
overlayContext.fill();
|
|
380
|
+
overlayContext.stroke();
|
|
381
|
+
}
|
|
382
|
+
else // draw cross shaped gamepad
|
|
383
|
+
{
|
|
384
|
+
for(let i=10; i--;)
|
|
385
|
+
{
|
|
386
|
+
const angle = i*PI/4;
|
|
387
|
+
overlayContext.arc(leftCenter.x, leftCenter.y,touchGamepadSize*.6, angle + PI/8, angle + PI/8);
|
|
388
|
+
i%2 && overlayContext.arc(leftCenter.x, leftCenter.y, touchGamepadSize*.33, angle, angle);
|
|
389
|
+
i==1 && overlayContext.fill();
|
|
390
|
+
}
|
|
391
|
+
overlayContext.stroke();
|
|
392
|
+
}
|
|
393
|
+
|
|
378
394
|
// draw right face buttons
|
|
379
395
|
const rightCenter = vec2(mainCanvasSize.x-touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
380
396
|
for (let i=4; i--;)
|
package/engine/engineMedals.js
CHANGED
|
@@ -35,7 +35,7 @@ function medalsInit(saveName)
|
|
|
35
35
|
{
|
|
36
36
|
// check if medals are unlocked
|
|
37
37
|
medalsSaveName = saveName;
|
|
38
|
-
debugMedals || medals.forEach(medal=>
|
|
38
|
+
debugMedals || medals.forEach(medal=> localStorage[medal.storageKey()]);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -224,6 +224,9 @@ class Newgrounds
|
|
|
224
224
|
const scoreboardResult = this.call('ScoreBoard.getBoards');
|
|
225
225
|
this.scoreboards = scoreboardResult ? scoreboardResult.result.data.scoreboards : [];
|
|
226
226
|
debugMedals && console.log(this.scoreboards);
|
|
227
|
+
|
|
228
|
+
const keepAliveMS = 5 * 60 * 1e3;
|
|
229
|
+
setInterval(()=>this.call('Gateway.ping', 0, 1), keepAliveMS);
|
|
227
230
|
}
|
|
228
231
|
|
|
229
232
|
/** Send message to unlock a medal by id
|
|
@@ -235,9 +238,6 @@ class Newgrounds
|
|
|
235
238
|
* @param {Number} value - The score value */
|
|
236
239
|
postScore(id, value) { return this.call('ScoreBoard.postScore', {'id':id, 'value':value}, 1); }
|
|
237
240
|
|
|
238
|
-
/** Send message to log a view */
|
|
239
|
-
logView() { return this.call('App.logView', {'host':this.host}, 1); }
|
|
240
|
-
|
|
241
241
|
/** Get scores from a scoreboard
|
|
242
242
|
* @param {Number} id - The scoreboard id
|
|
243
243
|
* @param {String} [user=0] - A user's id or name
|
|
@@ -249,6 +249,9 @@ class Newgrounds
|
|
|
249
249
|
getScores(id, user=0, social=0, skip=0, limit=10)
|
|
250
250
|
{ return this.call('ScoreBoard.getScores', {'id':id, 'user':user, 'social':social, 'skip':skip, 'limit':limit}); }
|
|
251
251
|
|
|
252
|
+
/** Send message to log a view */
|
|
253
|
+
logView() { return this.call('App.logView', {'host':this.host}, 1); }
|
|
254
|
+
|
|
252
255
|
/** Send a message to call a component of the Newgrounds API
|
|
253
256
|
* @param {String} component - Name of the component
|
|
254
257
|
* @param {Object} [parameters=0] - Parameters to use for call
|
package/engine/engineObject.js
CHANGED
|
@@ -36,7 +36,7 @@ class EngineObject
|
|
|
36
36
|
* @param {Vector2} [size=objectDefaultSize] - World space size of the object
|
|
37
37
|
* @param {Number} [tileIndex=-1] - Tile to use to render object, untextured if -1
|
|
38
38
|
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
|
|
39
|
-
* @param {Number} [angle=0] - Angle
|
|
39
|
+
* @param {Number} [angle=0] - Angle the object is rotated by
|
|
40
40
|
* @param {Color} [color] - Color to apply to tile when rendered
|
|
41
41
|
* @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
|
|
42
42
|
*/
|
|
@@ -352,4 +352,20 @@ class EngineObject
|
|
|
352
352
|
this.isSolid = isSolid;
|
|
353
353
|
this.collideTiles = collideTiles;
|
|
354
354
|
}
|
|
355
|
+
|
|
356
|
+
toString()
|
|
357
|
+
{
|
|
358
|
+
let text = 'type = ' + this.constructor.name;
|
|
359
|
+
if (this.pos.x || this.pos.y)
|
|
360
|
+
text += '\npos = ' + this.pos;
|
|
361
|
+
if (this.velocity.x || this.velocity.y)
|
|
362
|
+
text += '\nvelocity = ' + this.velocity;
|
|
363
|
+
if (this.size.x || this.size.y)
|
|
364
|
+
text += '\nsize = ' + this.size;
|
|
365
|
+
if (this.angle)
|
|
366
|
+
text += '\nangle = ' + this.angle.toFixed(3);
|
|
367
|
+
if (this.color)
|
|
368
|
+
text += '\ncolor = ' + this.color;
|
|
369
|
+
return text;
|
|
370
|
+
}
|
|
355
371
|
}
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* let pos = vec2(2,3);
|
|
16
16
|
* let particleEmiter = new ParticleEmitter
|
|
17
17
|
* (
|
|
18
|
-
* pos, 1, 0, 500, PI, // pos, emitSize, emitTime, emitRate, emiteCone
|
|
18
|
+
* pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
|
|
19
19
|
* 0, vec2(16), // tileIndex, tileSize
|
|
20
|
-
* new Color,
|
|
20
|
+
* new Color(1,1,1), new Color(0,0,0), // colorStartA, colorStartB
|
|
21
21
|
* new Color(1,1,1,0), new Color(0,0,0,0), // colorEndA, colorEndB
|
|
22
22
|
* 2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
|
|
23
23
|
* .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleCone, fadeRate,
|
|
@@ -28,6 +28,7 @@ class ParticleEmitter extends EngineObject
|
|
|
28
28
|
{
|
|
29
29
|
/** Create a particle system with the given settings
|
|
30
30
|
* @param {Vector2} position - World space position of the emitter
|
|
31
|
+
* @param {Number} [angle=0] - Angle to emit the particles
|
|
31
32
|
* @param {Number} [emitSize=0] - World space size of the emitter (float for circle diameter, vec2 for rect)
|
|
32
33
|
* @param {Number} [emitTime=0] - How long to stay alive (0 is forever)
|
|
33
34
|
* @param {Number} [emitRate=100] - How many particles per second to spawn, does not emit if 0
|
|
@@ -57,6 +58,7 @@ class ParticleEmitter extends EngineObject
|
|
|
57
58
|
constructor
|
|
58
59
|
(
|
|
59
60
|
pos,
|
|
61
|
+
angle,
|
|
60
62
|
emitSize = 0,
|
|
61
63
|
emitTime = 0,
|
|
62
64
|
emitRate = 100,
|
|
@@ -84,7 +86,7 @@ class ParticleEmitter extends EngineObject
|
|
|
84
86
|
renderOrder = additive ? 1e9 : 0
|
|
85
87
|
)
|
|
86
88
|
{
|
|
87
|
-
super(pos, new Vector2, tileIndex, tileSize,
|
|
89
|
+
super(pos, new Vector2, tileIndex, tileSize, angle, undefined, renderOrder);
|
|
88
90
|
|
|
89
91
|
// emitter settings
|
|
90
92
|
/** @property {Number} - World space size of the emitter (float for circle diameter, vec2 for rect) */
|
package/engine/engineSettings.js
CHANGED
|
@@ -145,6 +145,11 @@ let inputWASDEmulateDirection = 1;
|
|
|
145
145
|
* @memberof Settings */
|
|
146
146
|
let touchGamepadEnable = 0;
|
|
147
147
|
|
|
148
|
+
/** True if touch gamepad should be analog stick or false to use if 8 way dpad
|
|
149
|
+
* @default
|
|
150
|
+
* @memberof Settings */
|
|
151
|
+
let touchGamepadAnalog = 1;
|
|
152
|
+
|
|
148
153
|
/** Size of virutal gamepad for touch devices in pixels
|
|
149
154
|
* @default
|
|
150
155
|
* @memberof Settings */
|
|
@@ -153,14 +153,14 @@ class TileLayerData
|
|
|
153
153
|
*/
|
|
154
154
|
class TileLayer extends EngineObject
|
|
155
155
|
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
156
|
+
/** Create a tile layer object
|
|
157
|
+
* @param {Vector2} [position=new Vector2()] - World space position
|
|
158
|
+
* @param {Vector2} [size=tileCollisionSize] - World space size
|
|
159
|
+
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tiles in source pixels
|
|
160
|
+
* @param {Vector2} [scale=new Vector2(1,1)] - How much to scale this layer when rendered
|
|
161
|
+
* @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
|
|
162
|
+
*/
|
|
163
|
+
constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1), renderOrder=0)
|
|
164
164
|
{
|
|
165
165
|
super(pos, size, -1, tileSize, 0, undefined, renderOrder);
|
|
166
166
|
|
|
@@ -320,7 +320,7 @@ class TileLayer extends EngineObject
|
|
|
320
320
|
if (tileIndex < 0)
|
|
321
321
|
{
|
|
322
322
|
// untextured
|
|
323
|
-
context.fillStyle = color
|
|
323
|
+
context.fillStyle = color;
|
|
324
324
|
context.fillRect(-.5, -.5, 1, 1);
|
|
325
325
|
}
|
|
326
326
|
else
|
|
@@ -339,5 +339,6 @@ class TileLayer extends EngineObject
|
|
|
339
339
|
* @param {Vector2} [size=new Vector2(1,1)]
|
|
340
340
|
* @param {Color} [color=new Color(1,1,1)]
|
|
341
341
|
* @param {Number} [angle=0] */
|
|
342
|
-
drawRect(pos, size, color, angle)
|
|
342
|
+
drawRect(pos, size, color, angle)
|
|
343
|
+
{ this.drawTile(pos, size, -1, 0, color, angle); }
|
|
343
344
|
}
|
|
@@ -311,7 +311,13 @@ class Vector2
|
|
|
311
311
|
/** Returns true if this vector is within the bounds of an array size passed in
|
|
312
312
|
* @param {Vector2} arraySize
|
|
313
313
|
* @return {Boolean} */
|
|
314
|
-
arrayCheck(arraySize) { return this.x >= 0 && this.y >= 0 && this.x < arraySize.x && this.y < arraySize.y; }
|
|
314
|
+
arrayCheck(arraySize) { return this.x >= 0 && this.y >= 0 && this.x < arraySize.x && this.y < arraySize.y; }
|
|
315
|
+
|
|
316
|
+
/** Returns this vector expressed as a string
|
|
317
|
+
* @param {float} digits - precision to display
|
|
318
|
+
* @return {String} */
|
|
319
|
+
toString(digits=3)
|
|
320
|
+
{ return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`; }
|
|
315
321
|
}
|
|
316
322
|
|
|
317
323
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -382,7 +388,7 @@ class Color
|
|
|
382
388
|
* @return {Color} */
|
|
383
389
|
lerp(c, p) { return this.add(c.subtract(this).scale(clamp(p))); }
|
|
384
390
|
|
|
385
|
-
/** Sets this color given a hue, saturation, lightness
|
|
391
|
+
/** Sets this color given a hue, saturation, lightness, and alpha
|
|
386
392
|
* @param {Number} [hue=0]
|
|
387
393
|
* @param {Number} [saturation=0]
|
|
388
394
|
* @param {Number} [lightness=1]
|
|
@@ -418,21 +424,43 @@ class Color
|
|
|
418
424
|
).clamp();
|
|
419
425
|
}
|
|
420
426
|
|
|
421
|
-
/** Returns this color expressed as an
|
|
427
|
+
/** Returns this color expressed as an CSS color value
|
|
422
428
|
* @return {String} */
|
|
423
|
-
|
|
429
|
+
toString()
|
|
424
430
|
{
|
|
425
431
|
ASSERT(this.r>=0 && this.r<=1 && this.g>=0 && this.g<=1 && this.b>=0 && this.b<=1 && this.a>=0 && this.a<=1);
|
|
426
432
|
return `rgb(${this.r*255|0},${this.g*255|0},${this.b*255|0},${this.a})`;
|
|
427
433
|
}
|
|
428
434
|
|
|
429
|
-
/** Returns this color expressed as 32 bit integer value
|
|
435
|
+
/** Returns this color expressed as 32 bit integer RGBA value
|
|
430
436
|
* @return {Number} */
|
|
431
437
|
rgbaInt()
|
|
432
438
|
{
|
|
433
439
|
ASSERT(this.r>=0 && this.r<=1 && this.g>=0 && this.g<=1 && this.b>=0 && this.b<=1 && this.a>=0 && this.a<=1);
|
|
434
440
|
return (this.r*255|0) + (this.g*255<<8) + (this.b*255<<16) + (this.a*255<<24);
|
|
435
441
|
}
|
|
442
|
+
|
|
443
|
+
/** Returns this color expressed as a hex code
|
|
444
|
+
* @return {String} */
|
|
445
|
+
hex()
|
|
446
|
+
{
|
|
447
|
+
const toHex = (c)=> ((c=c*255|0)<16 ? '0' : '') + c.toString(16);
|
|
448
|
+
return '#' + toHex(this.r) + toHex(this.g) + toHex(this.b);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/** Set this color from a hex code
|
|
452
|
+
* @param {String} hex - html hex code
|
|
453
|
+
* @return {Color} */
|
|
454
|
+
setHex(hex)
|
|
455
|
+
{
|
|
456
|
+
const fromHex = (a)=> parseInt(hex.slice(a,a+2), 16)/255;
|
|
457
|
+
this.r = fromHex(1);
|
|
458
|
+
this.g = fromHex(3),
|
|
459
|
+
this.b = fromHex(5);
|
|
460
|
+
this.a = 1;
|
|
461
|
+
ASSERT(this.r>=0 && this.r<=1 && this.g>=0 && this.g<=1 && this.b>=0 && this.b<=1);
|
|
462
|
+
return this;
|
|
463
|
+
}
|
|
436
464
|
}
|
|
437
465
|
|
|
438
466
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -469,7 +497,7 @@ class Timer
|
|
|
469
497
|
|
|
470
498
|
/** Returns true if set and elapsed
|
|
471
499
|
* @return {Boolean} */
|
|
472
|
-
elapsed() { return time >
|
|
500
|
+
elapsed() { return time > this.time; }
|
|
473
501
|
|
|
474
502
|
/** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
|
|
475
503
|
* @return {Number} */
|
|
@@ -478,4 +506,8 @@ class Timer
|
|
|
478
506
|
/** Get percentage elapsed based on time it was set to, returns 0 if not set
|
|
479
507
|
* @return {Number} */
|
|
480
508
|
getPercent() { return this.isSet()? percent(this.time - time, this.setTime, 0) : 0; }
|
|
509
|
+
|
|
510
|
+
/** Returns this timer expressed as a string
|
|
511
|
+
* @return {String} */
|
|
512
|
+
toString() { return this.unset() ? 'unset' : Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ); }
|
|
481
513
|
}
|
package/engine/engineWebGL.js
CHANGED
|
@@ -47,24 +47,24 @@ function glInit()
|
|
|
47
47
|
|
|
48
48
|
// setup vertex and fragment shaders
|
|
49
49
|
glShader = glCreateProgram(
|
|
50
|
-
'precision highp float;'+
|
|
51
|
-
'uniform mat4 m;'+
|
|
52
|
-
'attribute vec2 p,t;'+
|
|
53
|
-
'attribute vec4 c,a;'+
|
|
54
|
-
'varying vec2 v;'+
|
|
55
|
-
'varying vec4 d,e;'+
|
|
56
|
-
'void main(){'+
|
|
57
|
-
'gl_Position=m*vec4(p,1,1);'
|
|
58
|
-
'v=t;d=c;e=a;'+
|
|
59
|
-
'}'
|
|
50
|
+
'precision highp float;'+ // use highp for better accuracy
|
|
51
|
+
'uniform mat4 m;'+ // transform matrix
|
|
52
|
+
'attribute vec2 p,t;'+ // position, uv
|
|
53
|
+
'attribute vec4 c,a;'+ // color, additiveColor
|
|
54
|
+
'varying vec2 v;'+ // return uv
|
|
55
|
+
'varying vec4 d,e;'+ // return color, additiveColor
|
|
56
|
+
'void main(){'+ // shader entry point
|
|
57
|
+
'gl_Position=m*vec4(p,1,1);'+ // transform position
|
|
58
|
+
'v=t;d=c;e=a;'+ // pass stuff to fragment shader
|
|
59
|
+
'}' // end of shader
|
|
60
60
|
,
|
|
61
|
-
'precision highp float;'+
|
|
62
|
-
'varying vec2 v;'+
|
|
63
|
-
'varying vec4 d,e;'+
|
|
64
|
-
'uniform sampler2D
|
|
65
|
-
'void main(){'+
|
|
66
|
-
'gl_FragColor=texture2D(
|
|
67
|
-
'}'
|
|
61
|
+
'precision highp float;'+ // use highp for better accuracy
|
|
62
|
+
'varying vec2 v;'+ // uv
|
|
63
|
+
'varying vec4 d,e;'+ // color, additiveColor
|
|
64
|
+
'uniform sampler2D s;'+ // texture
|
|
65
|
+
'void main(){'+ // shader entry point
|
|
66
|
+
'gl_FragColor=texture2D(s,v)*d+e;'+ // modulate texture by color plus additive
|
|
67
|
+
'}' // end of shader
|
|
68
68
|
);
|
|
69
69
|
|
|
70
70
|
// init buffers
|
|
@@ -276,44 +276,44 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba=0xffffff
|
|
|
276
276
|
|
|
277
277
|
// prepare to create the verts from size and angle
|
|
278
278
|
const c = Math.cos(angle)/2, s = Math.sin(angle)/2;
|
|
279
|
-
const
|
|
279
|
+
const cx = c*sizeX, cy = c*sizeY, sx = s*sizeX, sy = s*sizeY;
|
|
280
280
|
|
|
281
281
|
// setup 2 triangles to form a quad
|
|
282
282
|
let offset = glBatchCount++ * gl_VERTICES_PER_QUAD * gl_INDICIES_PER_VERT;
|
|
283
283
|
|
|
284
284
|
// vertex 0
|
|
285
|
-
glPositionData[offset++] = x -
|
|
286
|
-
glPositionData[offset++] = y -
|
|
285
|
+
glPositionData[offset++] = x - cx - sy;
|
|
286
|
+
glPositionData[offset++] = y - cy + sx;
|
|
287
287
|
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv1Y;
|
|
288
288
|
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
289
289
|
|
|
290
290
|
// vertex 1
|
|
291
|
-
glPositionData[offset++] = x +
|
|
292
|
-
glPositionData[offset++] = y +
|
|
291
|
+
glPositionData[offset++] = x + cx + sy;
|
|
292
|
+
glPositionData[offset++] = y + cy - sx;
|
|
293
293
|
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
|
|
294
294
|
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
295
295
|
|
|
296
296
|
// vertex 2
|
|
297
|
-
glPositionData[offset++] = x -
|
|
298
|
-
glPositionData[offset++] = y +
|
|
297
|
+
glPositionData[offset++] = x - cx + sy;
|
|
298
|
+
glPositionData[offset++] = y + cy + sx;
|
|
299
299
|
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv0Y;
|
|
300
300
|
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
301
301
|
|
|
302
302
|
// vertex 0
|
|
303
|
-
glPositionData[offset++] = x -
|
|
304
|
-
glPositionData[offset++] = y -
|
|
303
|
+
glPositionData[offset++] = x - cx - sy;
|
|
304
|
+
glPositionData[offset++] = y - cy + sx;
|
|
305
305
|
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv1Y;
|
|
306
306
|
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
307
307
|
|
|
308
308
|
// vertex 3
|
|
309
|
-
glPositionData[offset++] = x +
|
|
310
|
-
glPositionData[offset++] = y -
|
|
309
|
+
glPositionData[offset++] = x + cx - sy;
|
|
310
|
+
glPositionData[offset++] = y - cy - sx;
|
|
311
311
|
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv1Y;
|
|
312
312
|
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
313
313
|
|
|
314
314
|
// vertex 1
|
|
315
|
-
glPositionData[offset++] = x +
|
|
316
|
-
glPositionData[offset++] = y +
|
|
315
|
+
glPositionData[offset++] = x + cx + sy;
|
|
316
|
+
glPositionData[offset++] = y + cy - sx;
|
|
317
317
|
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
|
|
318
318
|
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
319
319
|
}
|