littlejsengine 1.0.14 → 1.1.8
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/build.bat +5 -1
- package/docs/Audio.html +2268 -0
- package/docs/Color.html +2989 -0
- package/docs/Debug.html +2933 -0
- package/docs/Draw.html +4092 -0
- package/docs/EngineObject.html +4458 -0
- package/docs/Input.html +2482 -0
- package/docs/Medal.html +1007 -0
- package/docs/Medals.html +628 -0
- package/docs/Music.html +584 -0
- package/docs/Newgrounds.html +1399 -0
- package/docs/Particle.html +4535 -0
- package/docs/ParticleEmitter.html +7770 -0
- package/docs/Random.html +1774 -0
- package/docs/Settings.html +2679 -0
- package/docs/Sound.html +1249 -0
- package/docs/TileCollision.html +1409 -0
- package/docs/TileLayer.html +6948 -0
- package/docs/TileLayerData.html +1052 -0
- package/docs/Timer.html +1183 -0
- package/docs/Utilities.html +3281 -0
- package/docs/Vector2.html +4207 -0
- package/docs/WebGL.html +2327 -0
- package/docs/engine.js.html +429 -0
- package/docs/engineAudio.js.html +609 -0
- package/docs/engineDebug.js.html +725 -0
- package/docs/engineDraw.js.html +419 -0
- package/docs/engineInput.js.html +401 -0
- package/docs/engineMedals.js.html +461 -0
- package/docs/engineObject.js.html +518 -0
- package/docs/engineParticles.js.html +441 -0
- package/docs/engineSettings.js.html +349 -0
- package/docs/engineTileLayer.js.html +513 -0
- package/docs/engineUtilities.js.html +647 -0
- package/docs/engineWebGL.js.html +522 -0
- package/docs/fonts/MavenPro-Regular.ttf +0 -0
- package/docs/fonts/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Muli-Black.ttf +0 -0
- package/docs/fonts/OFL-hind.txt +93 -0
- package/docs/fonts/OFL-montserrat.txt +93 -0
- package/docs/global.html +1691 -0
- package/docs/index.css +6 -0
- package/docs/index.html +247 -0
- package/docs/scripts/fix-code-block.js +53 -0
- package/docs/scripts/fix-navbar.js +25 -0
- package/docs/scripts/linenumber.js +25 -0
- package/docs/scripts/misc.js +217 -0
- package/docs/scripts/resize.js +85 -0
- package/docs/scripts/search.js +83 -0
- package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
- package/docs/scripts/third-party/fuse.js +9 -0
- package/docs/scripts/third-party/lang-css.js +2 -0
- package/docs/scripts/third-party/prettify.js +28 -0
- package/docs/static/favicon.png +0 -0
- package/docs/static/index.css +4 -0
- package/docs/styles/clean-jsdoc-theme-base.css +393 -0
- package/docs/styles/clean-jsdoc-theme-dark.css +324 -0
- package/docs/styles/clean-jsdoc-theme-light.css +319 -0
- package/docs/styles/reset.css +346 -0
- package/docs/styles/third-party/ionicons.min.css +11 -0
- package/docs/styles/third-party/prettify-jsdoc.css +111 -0
- package/docs/styles/third-party/prettify-tomorrow.css +5 -0
- package/engine/engine.all.js +1997 -744
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.release.js +1743 -569
- package/engine/engine.js +107 -39
- package/engine/engineAudio.js +152 -34
- package/engine/{build.bat → engineBuild.bat} +10 -10
- package/engine/{buildSetup.bat → engineBuildSetup.bat} +0 -0
- package/engine/engineDebug.js +105 -32
- package/engine/engineDraw.js +137 -32
- package/engine/engineInput.js +111 -37
- package/engine/{engineMedal.js → engineMedals.js} +129 -56
- package/engine/engineObject.js +117 -67
- package/engine/engineParticles.js +282 -0
- package/engine/engineRelease.js +3 -9
- package/engine/engineSettings.js +190 -0
- package/engine/engineTileLayer.js +147 -44
- package/engine/engineUtilities.js +488 -0
- package/engine/engineWebGL.js +113 -74
- package/examples/breakout/game.js +1 -1
- package/examples/breakout/gameObjects.js +3 -3
- package/examples/breakout/index.html +3 -3
- package/examples/platformer/game.js +5 -7
- package/examples/platformer/gameEffects.js +7 -7
- package/examples/platformer/gameLevel.js +2 -2
- package/examples/platformer/gameObjects.js +4 -5
- package/examples/platformer/gamePlayer.js +3 -3
- package/examples/platformer/index.html +6 -6
- package/examples/puzzle/game.js +1 -2
- package/examples/puzzle/index.html +2 -2
- package/examples/stress/index.html +2 -8
- package/game.js +5 -11
- package/index.html +13 -13
- package/package.json +4 -4
- package/tiles.png +0 -0
- package/engine/engineConfig.js +0 -64
- package/engine/engineParticle.js +0 -199
- package/engine/engineUtil.js +0 -147
package/engine/engineDebug.js
CHANGED
|
@@ -1,69 +1,137 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Debug Features
|
|
9
|
-
- debug overlay with mouse pick
|
|
10
|
-
- debug primitive rendering
|
|
11
|
-
- save screenshots
|
|
12
|
-
*/
|
|
1
|
+
/**
|
|
2
|
+
* LittleJS Debug System
|
|
3
|
+
* <br> - Debug overlay with mouse pick
|
|
4
|
+
* <br> - Debug primitive rendering
|
|
5
|
+
* <br> - Save screenshots to disk
|
|
6
|
+
* @namespace Debug
|
|
7
|
+
*/
|
|
13
8
|
|
|
14
9
|
'use strict';
|
|
15
10
|
|
|
11
|
+
/** True if debug is enabled
|
|
12
|
+
* @default
|
|
13
|
+
* @memberof Debug */
|
|
16
14
|
const debug = 1;
|
|
15
|
+
|
|
16
|
+
/** True if asserts are enaled
|
|
17
|
+
* @default
|
|
18
|
+
* @memberof Debug */
|
|
17
19
|
const enableAsserts = 1;
|
|
20
|
+
|
|
21
|
+
/** Size to render debug points by default
|
|
22
|
+
* @default
|
|
23
|
+
* @memberof Debug */
|
|
18
24
|
const debugPointSize = .5;
|
|
19
25
|
|
|
26
|
+
/** True if watermark with FPS should be down
|
|
27
|
+
* @default
|
|
28
|
+
* @memberof Debug */
|
|
20
29
|
let showWatermark = 1;
|
|
30
|
+
|
|
31
|
+
/** True if god mode is enabled, handle this however you want
|
|
32
|
+
* @default
|
|
33
|
+
* @memberof Debug */
|
|
21
34
|
let godMode = 0;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let debugPhysics = 0
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
|
|
36
|
+
// Engine internal variables not exposed to documentation
|
|
37
|
+
let debugPrimitives = [], debugOverlay = 0, debugPhysics = 0, debugRaycast = 0,
|
|
38
|
+
debugParticles = 0, debugGamepads = 0, debugMedals = 0, debugTakeScreenshot, downloadLink;
|
|
39
|
+
|
|
40
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
41
|
+
// Debug helper functions
|
|
42
|
+
|
|
43
|
+
/** Asserts if the experssion is false, does not do anything in release builds
|
|
44
|
+
* @param {Boolean} assertion
|
|
45
|
+
* @param {Object} output
|
|
46
|
+
* @memberof Debug */
|
|
34
47
|
const ASSERT = enableAsserts ? (...assert)=> console.assert(...assert) : ()=>{};
|
|
35
|
-
|
|
48
|
+
|
|
49
|
+
/** Draw a debug rectangle in world space
|
|
50
|
+
* @param {Vector2} pos
|
|
51
|
+
* @param {Vector2} [size=new Vector2()]
|
|
52
|
+
* @param {String} [color='#fff']
|
|
53
|
+
* @param {Number} [time=0]
|
|
54
|
+
* @param {Number} [angle=0]
|
|
55
|
+
* @param {Boolean} [fill=0]
|
|
56
|
+
* @memberof Debug */
|
|
57
|
+
const debugRect = (pos, size=vec2(), color='#fff', time=0, angle=0, fill=0)=>
|
|
36
58
|
{
|
|
37
59
|
ASSERT(typeof color == 'string'); // pass in regular html strings as colors
|
|
38
60
|
debugPrimitives.push({pos, size:vec2(size), color, time:new Timer(time), angle, fill});
|
|
39
61
|
}
|
|
62
|
+
|
|
63
|
+
/** Draw a debug circle in world space
|
|
64
|
+
* @param {Vector2} pos
|
|
65
|
+
* @param {Number} [radius=0]
|
|
66
|
+
* @param {String} [color='#fff']
|
|
67
|
+
* @param {Number} [time=0]
|
|
68
|
+
* @param {Boolean} [fill=0]
|
|
69
|
+
* @memberof Debug */
|
|
40
70
|
const debugCircle = (pos, radius=0, color='#fff', time=0, fill=0)=>
|
|
41
71
|
{
|
|
42
72
|
ASSERT(typeof color == 'string'); // pass in regular html strings as colors
|
|
43
73
|
debugPrimitives.push({pos, size:radius, color, time:new Timer(time), angle:0, fill});
|
|
44
74
|
}
|
|
75
|
+
|
|
76
|
+
/** Draw a debug point in world space
|
|
77
|
+
* @param {Vector2} pos
|
|
78
|
+
* @param {String} [color='#fff']
|
|
79
|
+
* @param {Number} [time=0]
|
|
80
|
+
* @param {Number} [angle=0]
|
|
81
|
+
* @memberof Debug */
|
|
45
82
|
const debugPoint = (pos, color, time, angle)=> debugRect(pos, 0, color, time, angle);
|
|
83
|
+
|
|
84
|
+
/** Draw a debug line in world space
|
|
85
|
+
* @param {Vector2} posA
|
|
86
|
+
* @param {Vector2} posB
|
|
87
|
+
* @param {String} [color='#fff']
|
|
88
|
+
* @param {Number} [thickness=.1]
|
|
89
|
+
* @param {Number} [time=0]
|
|
90
|
+
* @memberof Debug */
|
|
46
91
|
const debugLine = (posA, posB, color, thickness=.1, time)=>
|
|
47
92
|
{
|
|
48
93
|
const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
|
|
49
94
|
const size = vec2(thickness, halfDelta.length()*2);
|
|
50
95
|
debugRect(posA.add(halfDelta), size, color, time, halfDelta.angle(), 1);
|
|
51
96
|
}
|
|
52
|
-
|
|
97
|
+
|
|
98
|
+
/** Draw a debug axis aligned bounding box in world space
|
|
99
|
+
* @param {Vector2} posA
|
|
100
|
+
* @param {Vector2} sizeA
|
|
101
|
+
* @param {Vector2} posB
|
|
102
|
+
* @param {Vector2} sizeB
|
|
103
|
+
* @param {String} [color='#fff']
|
|
104
|
+
* @memberof Debug */
|
|
105
|
+
const debugAABB = (pA, sA, pB, sB, color)=>
|
|
53
106
|
{
|
|
54
107
|
const minPos = vec2(min(pA.x - sA.x/2, pB.x - sB.x/2), min(pA.y - sA.y/2, pB.y - sB.y/2));
|
|
55
108
|
const maxPos = vec2(max(pA.x + sA.x/2, pB.x + sB.x/2), max(pA.y + sA.y/2, pB.y + sB.y/2));
|
|
56
109
|
debugRect(minPos.lerp(maxPos,.5), maxPos.subtract(minPos), color);
|
|
57
110
|
}
|
|
58
|
-
|
|
111
|
+
|
|
112
|
+
/** Draw a debug axis aligned bounding box in world space
|
|
113
|
+
* @param {String} text
|
|
114
|
+
* @param {Vector2} pos
|
|
115
|
+
* @param {Number} [size=1]
|
|
116
|
+
* @param {String} [color='#fff']
|
|
117
|
+
* @param {Number} [time=0]
|
|
118
|
+
* @param {Number} [angle=0]
|
|
119
|
+
* @param {String} [font='monospace']
|
|
120
|
+
* @memberof Debug */
|
|
121
|
+
const debugText = (text, pos, size=1, color='#fff', time=0, angle=0, font='monospace')=>
|
|
59
122
|
{
|
|
60
123
|
ASSERT(typeof color == 'string'); // pass in regular html strings as colors
|
|
61
124
|
debugPrimitives.push({text, pos, size, color, time:new Timer(time), angle, font});
|
|
62
125
|
}
|
|
63
126
|
|
|
127
|
+
/** Clear all debug primitives in the list
|
|
128
|
+
* @memberof Debug */
|
|
64
129
|
const debugClear = ()=> debugPrimitives = [];
|
|
65
130
|
|
|
66
|
-
|
|
131
|
+
/** Save a canvas to disk
|
|
132
|
+
* @param {HTMLCanvasElement} canvas
|
|
133
|
+
* @param {String} [filename]
|
|
134
|
+
* @memberof Debug */
|
|
67
135
|
const debugSaveCanvas = (canvas, filename = engineName + '.png') =>
|
|
68
136
|
{
|
|
69
137
|
downloadLink.download = 'screenshot.png';
|
|
@@ -72,7 +140,7 @@ const debugSaveCanvas = (canvas, filename = engineName + '.png') =>
|
|
|
72
140
|
}
|
|
73
141
|
|
|
74
142
|
///////////////////////////////////////////////////////////////////////////////
|
|
75
|
-
//
|
|
143
|
+
// Engine debug function (called automatically)
|
|
76
144
|
|
|
77
145
|
const debugInit = ()=>
|
|
78
146
|
{
|
|
@@ -112,6 +180,11 @@ const debugRender = ()=>
|
|
|
112
180
|
|
|
113
181
|
if (debugTakeScreenshot)
|
|
114
182
|
{
|
|
183
|
+
// composite canvas
|
|
184
|
+
glCopyToContext(mainContext, 1);
|
|
185
|
+
mainContext.drawImage(overlayCanvas, 0, 0);
|
|
186
|
+
overlayCanvas.width |= 0;
|
|
187
|
+
|
|
115
188
|
debugSaveCanvas(mainCanvas);
|
|
116
189
|
debugTakeScreenshot = 0;
|
|
117
190
|
}
|
|
@@ -189,8 +262,8 @@ const debugRender = ()=>
|
|
|
189
262
|
const saveContext = mainContext;
|
|
190
263
|
mainContext = overlayContext
|
|
191
264
|
const raycastHitPos = tileCollisionRaycast(bestObject.pos, mousePos);
|
|
192
|
-
raycastHitPos && drawRect(raycastHitPos.
|
|
193
|
-
drawRect(mousePos.
|
|
265
|
+
raycastHitPos && drawRect(raycastHitPos.floor().add(vec2(.5)), vec2(1), new Color(0,1,1,.3));
|
|
266
|
+
drawRect(mousePos.floor().add(vec2(.5)), vec2(1), new Color(0,0,1,.5));
|
|
194
267
|
drawLine(mousePos, bestObject.pos, .1, !raycastHitPos ? new Color(0,1,0,.5) : new Color(1,0,0,.5));
|
|
195
268
|
|
|
196
269
|
let pos = mousePos.copy(), height = vec2(0,.5);
|
|
@@ -304,7 +377,7 @@ const debugRender = ()=>
|
|
|
304
377
|
}
|
|
305
378
|
|
|
306
379
|
///////////////////////////////////////////////////////////////////////////////
|
|
307
|
-
// particle system editor
|
|
380
|
+
// particle system editor (work in progress)
|
|
308
381
|
let debugParticleEditor = 0, debugParticleSystem, debugParticleSystemDiv, particleSystemCode;
|
|
309
382
|
|
|
310
383
|
const debugToggleParticleEditor = ()=>
|
package/engine/engineDraw.js
CHANGED
|
@@ -1,28 +1,78 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/**
|
|
2
|
+
* LittleJS Drawing System
|
|
3
|
+
* <br> - Hybrid with both Canvas2D and WebGL available
|
|
4
|
+
* <br> - Super fast tile sheet rendering with WebGL
|
|
5
|
+
* <br> - Can apply rotation, mirror, color and additive color
|
|
6
|
+
* <br> - Many useful utility functions
|
|
7
|
+
* @namespace Draw
|
|
8
|
+
*/
|
|
7
9
|
|
|
8
10
|
'use strict';
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
/** Tile sheet for batch rendering system
|
|
13
|
+
* @type {Image}
|
|
14
|
+
* @memberof Draw */
|
|
15
|
+
const tileImage = new Image();
|
|
16
|
+
|
|
17
|
+
/** The primary 2D canvas visible to the user
|
|
18
|
+
* @type {HTMLCanvasElement}
|
|
19
|
+
* @memberof Draw */
|
|
20
|
+
let mainCanvas;
|
|
21
|
+
|
|
22
|
+
/** 2d context for mainCanvas
|
|
23
|
+
* @type {CanvasRenderingContext2D}
|
|
24
|
+
* @memberof Draw */
|
|
25
|
+
let mainContext;
|
|
26
|
+
|
|
27
|
+
/** A canvas that appears on top of everything the same size as mainCanvas
|
|
28
|
+
* @type {HTMLCanvasElement}
|
|
29
|
+
* @memberof Draw */
|
|
30
|
+
let overlayCanvas;
|
|
31
|
+
|
|
32
|
+
/** 2d context for overlayCanvas
|
|
33
|
+
* @type {CanvasRenderingContext2D}
|
|
34
|
+
* @memberof Draw */
|
|
35
|
+
let overlayContext;
|
|
36
|
+
|
|
37
|
+
/** The size of the main canvas (and other secondary canvases)
|
|
38
|
+
* @type {Vector2}
|
|
39
|
+
* @memberof Draw */
|
|
40
|
+
let mainCanvasSize = vec2();
|
|
41
|
+
|
|
42
|
+
/** Convert from screen to world space coordinates
|
|
43
|
+
* @param {Vector2} screenPos
|
|
44
|
+
* @return {Vector2}
|
|
45
|
+
* @memberof Draw */
|
|
11
46
|
const screenToWorld = (screenPos)=>
|
|
12
47
|
screenPos.add(vec2(.5)).subtract(mainCanvasSize.scale(.5)).multiply(vec2(1/cameraScale,-1/cameraScale)).add(cameraPos);
|
|
48
|
+
|
|
49
|
+
/** Convert from world to screen space coordinates
|
|
50
|
+
* @param {Vector2} worldPos
|
|
51
|
+
* @return {Vector2}
|
|
52
|
+
* @memberof Draw */
|
|
13
53
|
const worldToScreen = (worldPos)=>
|
|
14
54
|
worldPos.subtract(cameraPos).multiply(vec2(cameraScale,-cameraScale)).add(mainCanvasSize.scale(.5)).subtract(vec2(.5));
|
|
15
55
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
56
|
+
/** Draw textured tile centered in world space, with color applied if using WebGL
|
|
57
|
+
* @param {Vector2} pos - Center of the tile in world space
|
|
58
|
+
* @param {Vector2} [size=new Vector2(1,1)] - Size of the tile in world space, width and height
|
|
59
|
+
* @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
|
|
60
|
+
* @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
|
|
61
|
+
* @param {Color} [color=new Color(1,1,1)] - Color to modulate with
|
|
62
|
+
* @param {Number} [angle=0] - Angle to rotate by
|
|
63
|
+
* @param {Boolean} [mirror=0] - If true image is flipped along the Y axis
|
|
64
|
+
* @param {Color} [additiveColor=new Color(0,0,0,0)] - Additive color to be applied
|
|
65
|
+
* @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
|
|
66
|
+
* @memberof Draw */
|
|
67
|
+
function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, color=new Color, angle=0, mirror,
|
|
68
|
+
additiveColor=new Color(0,0,0,0), useWebGL=glEnable)
|
|
19
69
|
{
|
|
20
70
|
showWatermark && ++drawCount;
|
|
21
|
-
if (glEnable)
|
|
71
|
+
if (glEnable && useWebGL)
|
|
22
72
|
{
|
|
23
|
-
if (tileIndex < 0)
|
|
73
|
+
if (tileIndex < 0 || !tileImage.width)
|
|
24
74
|
{
|
|
25
|
-
// if negative tile index, force untextured
|
|
75
|
+
// if negative tile index or image not found, force untextured
|
|
26
76
|
glDraw(pos.x, pos.y, size.x, size.y, angle, 0, 0, 0, 0, 0, color.rgbaInt());
|
|
27
77
|
}
|
|
28
78
|
else
|
|
@@ -69,33 +119,68 @@ function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=defaultTileSize, col
|
|
|
69
119
|
}
|
|
70
120
|
}
|
|
71
121
|
|
|
72
|
-
|
|
73
|
-
|
|
122
|
+
/** Draw colored rect centered on pos
|
|
123
|
+
* @param {Vector2} pos
|
|
124
|
+
* @param {Vector2} [size=new Vector2(1,1)]
|
|
125
|
+
* @param {Color} [color=new Color(1,1,1)]
|
|
126
|
+
* @param {Number} [angle=0]
|
|
127
|
+
* @param {Boolean} [useWebGL=glEnable]
|
|
128
|
+
* @memberof Draw */
|
|
129
|
+
function drawRect(pos, size, color, angle, useWebGL)
|
|
74
130
|
{
|
|
75
|
-
drawTile(pos, size, -1,
|
|
131
|
+
drawTile(pos, size, -1, tileSizeDefault, color, angle, 0, 0, useWebGL);
|
|
76
132
|
}
|
|
77
133
|
|
|
78
|
-
|
|
79
|
-
|
|
134
|
+
/** Draw textured tile centered on pos in screen space
|
|
135
|
+
* @param {Vector2} pos - Center of the tile
|
|
136
|
+
* @param {Vector2} [size=new Vector2(1,1)] - Size of the tile
|
|
137
|
+
* @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
|
|
138
|
+
* @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
|
|
139
|
+
* @param {Color} [color=new Color]
|
|
140
|
+
* @param {Number} [angle=0]
|
|
141
|
+
* @param {Boolean} [mirror=0]
|
|
142
|
+
* @param {Color} [additiveColor=new Color(0,0,0,0)]
|
|
143
|
+
* @param {Boolean} [useWebGL=glEnable]
|
|
144
|
+
* @memberof Draw */
|
|
145
|
+
function drawTileScreenSpace(pos, size=vec2(1), tileIndex, tileSize, color, angle, mirror, additiveColor, useWebGL)
|
|
80
146
|
{
|
|
81
|
-
drawTile(screenToWorld(pos), size.scale(1/cameraScale), tileIndex, tileSize, color, angle, mirror, additiveColor);
|
|
147
|
+
drawTile(screenToWorld(pos), size.scale(1/cameraScale), tileIndex, tileSize, color, angle, mirror, additiveColor, useWebGL);
|
|
82
148
|
}
|
|
83
149
|
|
|
84
|
-
|
|
85
|
-
|
|
150
|
+
/** Draw colored rectangle in screen space
|
|
151
|
+
* @param {Vector2} pos
|
|
152
|
+
* @param {Vector2} [size=new Vector2(1,1)]
|
|
153
|
+
* @param {Color} [color=new Color(1,1,1)]
|
|
154
|
+
* @param {Number} [angle=0]
|
|
155
|
+
* @param {Boolean} [useWebGL=glEnable]
|
|
156
|
+
* @memberof Draw */
|
|
157
|
+
function drawRectScreenSpace(pos, size, color, angle, useWebGL)
|
|
86
158
|
{
|
|
87
|
-
|
|
159
|
+
drawTileSrceenSpace(pos, size, -1, tileSizeDefault, color, angle, 0, 0, useWebGL);
|
|
88
160
|
}
|
|
89
161
|
|
|
90
|
-
|
|
91
|
-
|
|
162
|
+
/** Draw colored line between two points
|
|
163
|
+
* @param {Vector2} posA
|
|
164
|
+
* @param {Vector2} posB
|
|
165
|
+
* @param {Number} [thickness=.1]
|
|
166
|
+
* @param {Color} [color=new Color(1,1,1)]
|
|
167
|
+
* @param {Boolean} [useWebGL=glEnable]
|
|
168
|
+
* @memberof Draw */
|
|
169
|
+
function drawLine(posA, posB, thickness=.1, color, useWebGL)
|
|
92
170
|
{
|
|
93
171
|
const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
|
|
94
172
|
const size = vec2(thickness, halfDelta.length()*2);
|
|
95
|
-
drawRect(posA.add(halfDelta), size, color, halfDelta.angle());
|
|
173
|
+
drawRect(posA.add(halfDelta), size, color, halfDelta.angle(), 0, 0, useWebGL);
|
|
96
174
|
}
|
|
97
175
|
|
|
98
|
-
|
|
176
|
+
/** Draw directly to a 2d canvas context in world space
|
|
177
|
+
* @param {Vector2} pos
|
|
178
|
+
* @param {Vector2} size
|
|
179
|
+
* @param {Number} angle
|
|
180
|
+
* @param {Boolean} mirror
|
|
181
|
+
* @param {Function} drawFunction
|
|
182
|
+
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
183
|
+
* @memberof Draw */
|
|
99
184
|
function drawCanvas2D(pos, size, angle, mirror, drawFunction, context = mainContext)
|
|
100
185
|
{
|
|
101
186
|
// create canvas transform from world space to screen space
|
|
@@ -109,8 +194,16 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, context = mainCont
|
|
|
109
194
|
context.restore();
|
|
110
195
|
}
|
|
111
196
|
|
|
112
|
-
|
|
113
|
-
|
|
197
|
+
/** Draw text on overlay canvas in world space
|
|
198
|
+
* @param {String} text
|
|
199
|
+
* @param {Vector2} pos
|
|
200
|
+
* @param {Number} [size=1]
|
|
201
|
+
* @param {Color} [color=new Color(1,1,1)]
|
|
202
|
+
* @param {Number} [lineWidth=0]
|
|
203
|
+
* @param {Color} [lineColor=new Color(0,0,0)]
|
|
204
|
+
* @param {String} [textAlign='center']
|
|
205
|
+
* @memberof Draw */
|
|
206
|
+
function drawText(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault)
|
|
114
207
|
{
|
|
115
208
|
pos = worldToScreen(pos);
|
|
116
209
|
overlayContext.font = size*cameraScale + 'px '+ font;
|
|
@@ -126,16 +219,28 @@ function drawText(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new
|
|
|
126
219
|
overlayContext.fillText(text, pos.x, pos.y);
|
|
127
220
|
}
|
|
128
221
|
|
|
129
|
-
|
|
130
|
-
|
|
222
|
+
/** Enable normal or additive blend mode
|
|
223
|
+
* @param {Boolean} [additive=0]
|
|
224
|
+
* @param {Boolean} [useWebGL=glEnable]
|
|
225
|
+
* @memberof Draw */
|
|
226
|
+
function setBlendMode(additive, useWebGL=glEnable)
|
|
131
227
|
{
|
|
132
|
-
glEnable
|
|
228
|
+
if (glEnable && useWebGL)
|
|
229
|
+
glSetBlendMode(additive);
|
|
230
|
+
else
|
|
231
|
+
mainContext.globalCompositeOperation = additive ? 'lighter' : 'source-over';
|
|
133
232
|
}
|
|
134
233
|
|
|
135
234
|
///////////////////////////////////////////////////////////////////////////////
|
|
136
|
-
//
|
|
235
|
+
// Fullscreen mode
|
|
137
236
|
|
|
237
|
+
/** Returns true if fullscreen mode is active
|
|
238
|
+
* @return {Boolean}
|
|
239
|
+
* @memberof Draw */
|
|
138
240
|
const isFullscreen =()=> document.fullscreenElement;
|
|
241
|
+
|
|
242
|
+
/** Toggle fullsceen mode
|
|
243
|
+
* @memberof Draw */
|
|
139
244
|
function toggleFullscreen()
|
|
140
245
|
{
|
|
141
246
|
if (isFullscreen())
|
package/engine/engineInput.js
CHANGED
|
@@ -1,36 +1,104 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/**
|
|
2
|
+
* LittleJS Input System
|
|
3
|
+
* <br> - Tracks key down, pressed, and released
|
|
4
|
+
* <br> - Also tracks mouse buttons, position, and wheel
|
|
5
|
+
* <br> - Supports multiple gamepads
|
|
6
|
+
* @namespace Input
|
|
7
|
+
*/
|
|
7
8
|
|
|
8
9
|
'use strict';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
/** Returns true if device key is down
|
|
12
|
+
* @param {Number} key
|
|
13
|
+
* @param {Number} [device=0]
|
|
14
|
+
* @return {Boolean}
|
|
15
|
+
* @memberof Input */
|
|
16
|
+
const keyIsDown = (key, device=0)=> inputData[device] && inputData[device][key] & 1 ? 1 : 0;
|
|
17
|
+
|
|
18
|
+
/** Returns true if device key was pressed this frame
|
|
19
|
+
* @param {Number} key
|
|
20
|
+
* @param {Number} [device=0]
|
|
21
|
+
* @return {Boolean}
|
|
22
|
+
* @memberof Input */
|
|
23
|
+
const keyWasPressed = (key, device=0)=> inputData[device] && inputData[device][key] & 2 ? 1 : 0;
|
|
24
|
+
|
|
25
|
+
/** Returns true if device key was released this frame
|
|
26
|
+
* @param {Number} key
|
|
27
|
+
* @param {Number} [device=0]
|
|
28
|
+
* @return {Boolean}
|
|
29
|
+
* @memberof Input */
|
|
14
30
|
const keyWasReleased = (key, device=0)=> inputData[device] && inputData[device][key] & 4 ? 1 : 0;
|
|
15
|
-
const clearInput = ()=> inputData[0] = [];
|
|
16
31
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
32
|
+
/** Clears all input
|
|
33
|
+
* @memberof Input */
|
|
34
|
+
const clearInput = ()=> inputData[0] = [];
|
|
35
|
+
|
|
36
|
+
/** Returns true if mouse button is down
|
|
37
|
+
* @param {Number} button
|
|
38
|
+
* @return {Boolean}
|
|
39
|
+
* @memberof Input */
|
|
40
|
+
const mouseIsDown = keyIsDown;
|
|
41
|
+
|
|
42
|
+
/** Returns true if mouse button was pressed
|
|
43
|
+
* @param {Number} button
|
|
44
|
+
* @return {Boolean}
|
|
45
|
+
* @memberof Input */
|
|
46
|
+
const mouseWasPressed = keyWasPressed;
|
|
47
|
+
|
|
48
|
+
/** Returns true if mouse button was released
|
|
49
|
+
* @param {Number} button
|
|
50
|
+
* @return {Boolean}
|
|
51
|
+
* @memberof Input */
|
|
20
52
|
const mouseWasReleased = keyWasReleased;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
53
|
+
|
|
54
|
+
/** Mouse pos in world space
|
|
55
|
+
* @type {Vector2}
|
|
56
|
+
* @memberof Input */
|
|
57
|
+
let mousePos = vec2();
|
|
58
|
+
|
|
59
|
+
/** Mouse pos in screen space
|
|
60
|
+
* @type {Vector2}
|
|
61
|
+
* @memberof Input */
|
|
62
|
+
let mousePosScreen = vec2();
|
|
63
|
+
|
|
64
|
+
/** Mouse wheel delta this frame
|
|
65
|
+
* @memberof Input */
|
|
66
|
+
let mouseWheel = 0;
|
|
67
|
+
|
|
68
|
+
/** Returns true if user is using gamepad (has more recently pressed a gamepad button)
|
|
69
|
+
* @memberof Input */
|
|
70
|
+
let isUsingGamepad = 0;
|
|
71
|
+
|
|
72
|
+
/** Returns true if gamepad button is down
|
|
73
|
+
* @param {Number} button
|
|
74
|
+
* @param {Number} [gamepad=0]
|
|
75
|
+
* @return {Boolean}
|
|
76
|
+
* @memberof Input */
|
|
77
|
+
const gamepadIsDown = (button, gamepad=0)=> keyIsDown(button, gamepad+1);
|
|
78
|
+
|
|
79
|
+
/** Returns true if gamepad button was pressed
|
|
80
|
+
* @param {Number} button
|
|
81
|
+
* @param {Number} [gamepad=0]
|
|
82
|
+
* @return {Boolean}
|
|
83
|
+
* @memberof Input */
|
|
84
|
+
const gamepadWasPressed = (button, gamepad=0)=> keyWasPressed(button, gamepad+1);
|
|
85
|
+
|
|
86
|
+
/** Returns true if gamepad button was released
|
|
87
|
+
* @param {Number} button
|
|
88
|
+
* @param {Number} [gamepad=0]
|
|
89
|
+
* @return {Boolean}
|
|
90
|
+
* @memberof Input */
|
|
29
91
|
const gamepadWasReleased = (button, gamepad=0)=> keyWasReleased(button, gamepad+1);
|
|
30
|
-
|
|
92
|
+
|
|
93
|
+
/** Returns gamepad stick value
|
|
94
|
+
* @param {Number} stick
|
|
95
|
+
* @param {Number} [gamepad=0]
|
|
96
|
+
* @return {Vector2}
|
|
97
|
+
* @memberof Input */
|
|
98
|
+
const gamepadStick = (stick, gamepad=0)=> stickData[gamepad] ? stickData[gamepad][stick] || vec2() : vec2();
|
|
31
99
|
|
|
32
100
|
///////////////////////////////////////////////////////////////////////////////
|
|
33
|
-
//
|
|
101
|
+
// Input update called by engine
|
|
34
102
|
|
|
35
103
|
const inputData = [[]];
|
|
36
104
|
|
|
@@ -56,23 +124,25 @@ function inputUpdatePost()
|
|
|
56
124
|
}
|
|
57
125
|
|
|
58
126
|
///////////////////////////////////////////////////////////////////////////////
|
|
59
|
-
//
|
|
127
|
+
// Keyboard event handlers
|
|
128
|
+
|
|
60
129
|
onkeydown = e=>
|
|
61
130
|
{
|
|
62
131
|
if (debug && e.target != document.body) return;
|
|
63
|
-
e.repeat || (inputData[
|
|
64
|
-
|
|
132
|
+
e.repeat || (inputData[isUsingGamepad = 0][remapKeyCode(e.keyCode)] = 3);
|
|
133
|
+
debug || e.preventDefault();
|
|
65
134
|
}
|
|
66
135
|
onkeyup = e=>
|
|
67
136
|
{
|
|
68
137
|
if (debug && e.target != document.body) return;
|
|
69
138
|
inputData[0][remapKeyCode(e.keyCode)] = 4;
|
|
70
139
|
}
|
|
71
|
-
const remapKeyCode = c=>
|
|
140
|
+
const remapKeyCode = c=> inputWASDEmulateDirection ? c==87?38 : c==83?40 : c==65?37 : c==68?39 : c : c;
|
|
72
141
|
|
|
73
142
|
///////////////////////////////////////////////////////////////////////////////
|
|
74
|
-
//
|
|
75
|
-
|
|
143
|
+
// Mouse event handlers
|
|
144
|
+
|
|
145
|
+
onmousedown = e=> {inputData[isUsingGamepad = 0][e.button] = 3; onmousemove(e); e.button && e.preventDefault();}
|
|
76
146
|
onmouseup = e=> inputData[0][e.button] = inputData[0][e.button] & 2 | 4;
|
|
77
147
|
onmousemove = e=>
|
|
78
148
|
{
|
|
@@ -86,7 +156,7 @@ onwheel = e=> e.ctrlKey || (mouseWheel = sign(e.deltaY));
|
|
|
86
156
|
oncontextmenu = e=> !1; // prevent right click menu
|
|
87
157
|
|
|
88
158
|
///////////////////////////////////////////////////////////////////////////////
|
|
89
|
-
//
|
|
159
|
+
// Gamepad input
|
|
90
160
|
|
|
91
161
|
const stickData = [];
|
|
92
162
|
function gamepadsUpdate()
|
|
@@ -120,10 +190,10 @@ function gamepadsUpdate()
|
|
|
120
190
|
{
|
|
121
191
|
const button = gamepad.buttons[j];
|
|
122
192
|
data[j] = button.pressed ? 1 + 2*!gamepadIsDown(j,i) : 4*gamepadIsDown(j,i);
|
|
123
|
-
|
|
193
|
+
isUsingGamepad |= !i && button.pressed;
|
|
124
194
|
}
|
|
125
195
|
|
|
126
|
-
if (
|
|
196
|
+
if (gamepadDirectionEmulateStick)
|
|
127
197
|
{
|
|
128
198
|
// copy dpad to left analog stick when pressed
|
|
129
199
|
const dpad = vec2(gamepadIsDown(15,i) - gamepadIsDown(14,i), gamepadIsDown(12,i) - gamepadIsDown(13,i));
|
|
@@ -135,12 +205,16 @@ function gamepadsUpdate()
|
|
|
135
205
|
}
|
|
136
206
|
|
|
137
207
|
///////////////////////////////////////////////////////////////////////////////
|
|
138
|
-
//
|
|
139
|
-
|
|
208
|
+
// Touch input
|
|
209
|
+
|
|
210
|
+
/** True if a touch device has been detected
|
|
211
|
+
* @const {boolean}
|
|
212
|
+
* @memberof Input */
|
|
213
|
+
const isTouchDevice = inputTouchEnable && window.ontouchstart !== undefined;
|
|
140
214
|
if (isTouchDevice)
|
|
141
215
|
{
|
|
142
216
|
// handle all touch events the same way
|
|
143
|
-
let wasTouching;
|
|
217
|
+
let wasTouching, hadTouchInput;
|
|
144
218
|
ontouchstart = ontouchmove = ontouchend = e=>
|
|
145
219
|
{
|
|
146
220
|
e.button = 0; // all touches are left click
|
|
@@ -149,7 +223,7 @@ if (isTouchDevice)
|
|
|
149
223
|
const touching = e.touches.length;
|
|
150
224
|
if (touching)
|
|
151
225
|
{
|
|
152
|
-
|
|
226
|
+
hadTouchInput || zzfx(0, hadTouchInput=1) ; // fix mobile audio, force it to play a sound the first time
|
|
153
227
|
|
|
154
228
|
// set event pos and pass it along
|
|
155
229
|
e.x = e.touches[0].clientX;
|