littlejsengine 1.9.1 → 1.9.3
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 +11 -9
- package/{build → dist}/littlejs.d.ts +48 -43
- package/{build → dist}/littlejs.esm.js +256 -147
- package/dist/littlejs.esm.min.js +1 -0
- package/{build → dist}/littlejs.js +256 -147
- package/dist/littlejs.min.js +1 -0
- package/{build → dist}/littlejs.release.js +249 -144
- package/examples/breakout/game.js +2 -2
- package/examples/breakout/gameObjects.js +3 -3
- package/examples/breakout/index.html +3 -3
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/electron/build.js +1 -1
- package/examples/electron/game.js +49 -38
- package/examples/electron/index.html +2 -2
- package/examples/electron/tiles.png +0 -0
- package/examples/empty/index.html +1 -1
- package/examples/js13k/build.js +1 -1
- package/examples/js13k/game.js +10 -9
- package/examples/js13k/index.html +13 -13
- package/examples/js13k/tiles.png +0 -0
- package/examples/logo.png +0 -0
- package/examples/module/game.js +45 -41
- package/examples/module/index.html +1 -1
- package/examples/module/tiles.png +0 -0
- package/examples/particles/index.html +1 -1
- package/examples/platformer/data/gameLevelData.tmx +143 -0
- package/examples/platformer/data/gameLevelData.tsx +4 -0
- package/examples/platformer/game.js +31 -11
- package/examples/platformer/gameCharacter.js +9 -7
- package/examples/platformer/gameEffects.js +105 -164
- package/examples/platformer/gameLevel.js +164 -181
- package/examples/platformer/gameLevelData.js +181 -0
- package/examples/platformer/gameObjects.js +71 -26
- package/examples/platformer/gamePlayer.js +3 -2
- package/examples/platformer/index.html +8 -7
- package/examples/platformer/tiles.png +0 -0
- package/examples/platformer/tilesLevel.png +0 -0
- package/examples/puzzle/game.js +12 -12
- package/examples/puzzle/index.html +2 -2
- package/examples/screenshot.jpg +0 -0
- package/examples/starter/build.js +1 -1
- package/examples/starter/game.js +6 -6
- package/examples/starter/index.html +13 -13
- package/examples/starter/tiles.png +0 -0
- package/examples/stress/index.html +2 -2
- package/examples/typescript/build.bat +4 -1
- package/examples/typescript/game.js +34 -31
- package/examples/typescript/game.ts +40 -36
- package/examples/typescript/index.html +1 -1
- package/examples/typescript/tiles.png +0 -0
- package/package.json +3 -3
- package/reference.md +409 -0
- package/src/engine.js +46 -41
- package/src/engineAudio.js +22 -19
- package/src/engineBuild.js +9 -2
- package/src/engineDebug.js +7 -3
- package/src/engineDraw.js +8 -7
- package/src/engineInput.js +5 -5
- package/src/engineMedals.js +3 -3
- package/src/engineObject.js +2 -2
- package/src/engineParticles.js +16 -15
- package/src/engineSettings.js +3 -3
- package/src/engineTileLayer.js +3 -3
- package/src/engineUtilities.js +139 -38
- package/src/engineWebGL.js +2 -8
- package/build/littlejs.esm.min.js +0 -1
- package/build/littlejs.min.js +0 -1
- package/index.d.ts +0 -2094
package/src/engineBuild.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
const ENGINE_NAME = 'littlejs';
|
|
14
|
-
const BUILD_FOLDER = '
|
|
14
|
+
const BUILD_FOLDER = 'dist';
|
|
15
15
|
const SOURCE_FOLDER = 'src';
|
|
16
16
|
const engineSourceFiles =
|
|
17
17
|
[
|
|
@@ -158,7 +158,14 @@ function typeScriptBuildStep(filename)
|
|
|
158
158
|
{
|
|
159
159
|
try
|
|
160
160
|
{
|
|
161
|
-
|
|
161
|
+
const tsFilename = `${BUILD_FOLDER}/${ENGINE_NAME}.d.ts`
|
|
162
|
+
child_process.execSync(`npx tsc ${filename} --declaration --allowJs --emitDeclarationOnly --outFile ${tsFilename}`);
|
|
163
|
+
|
|
164
|
+
// Remove declare module part
|
|
165
|
+
//let fileContent = fs.readFileSync(tsFilename, 'utf8');
|
|
166
|
+
//const r = new RegExp(`declare module "${ENGINE_NAME}\.esm" \{([\\s\\S]*?)\}`);
|
|
167
|
+
//fs.writeFileSync(tsFilename, fileContent.replace(r, '$1'));
|
|
168
|
+
|
|
162
169
|
}
|
|
163
170
|
catch (e) { handleError(e, 'Failed to run TypeScript build step!'); }
|
|
164
171
|
};
|
package/src/engineDebug.js
CHANGED
|
@@ -52,11 +52,15 @@ let debugPrimitives = [], debugPhysics = false, debugRaycast = false, debugParti
|
|
|
52
52
|
///////////////////////////////////////////////////////////////////////////////
|
|
53
53
|
// Debug helper functions
|
|
54
54
|
|
|
55
|
-
/** Asserts if the
|
|
55
|
+
/** Asserts if the expression is false, does not do anything in release builds
|
|
56
56
|
* @param {Boolean} assert
|
|
57
|
-
* @param {Object} output
|
|
57
|
+
* @param {Object} [output]
|
|
58
58
|
* @memberof Debug */
|
|
59
|
-
function ASSERT(assert, output)
|
|
59
|
+
function ASSERT(assert, output)
|
|
60
|
+
{
|
|
61
|
+
if (enableAsserts)
|
|
62
|
+
output ? console.assert(assert, output) : console.assert(assert);
|
|
63
|
+
}
|
|
60
64
|
|
|
61
65
|
/** Draw a debug rectangle in world space
|
|
62
66
|
* @param {Vector2} pos
|
package/src/engineDraw.js
CHANGED
|
@@ -85,13 +85,9 @@ function tile(pos=vec2(), size=tileSizeDefault, textureIndex=0)
|
|
|
85
85
|
if (typeof pos === 'number')
|
|
86
86
|
{
|
|
87
87
|
const textureInfo = textureInfos[textureIndex];
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
pos = vec2((pos%cols)*size.x, (pos/cols|0)*size.y);
|
|
92
|
-
}
|
|
93
|
-
else
|
|
94
|
-
pos = vec2();
|
|
88
|
+
ASSERT(textureInfo, 'Texture not loaded');
|
|
89
|
+
const cols = textureInfo.size.x / size.x |0;
|
|
90
|
+
pos = vec2((pos%cols)*size.x, (pos/cols|0)*size.y);
|
|
95
91
|
}
|
|
96
92
|
|
|
97
93
|
// return a tile info object
|
|
@@ -180,6 +176,11 @@ function worldToScreen(worldPos)
|
|
|
180
176
|
);
|
|
181
177
|
}
|
|
182
178
|
|
|
179
|
+
/** Get the camera's visible area in world space
|
|
180
|
+
* @return {Vector2}
|
|
181
|
+
* @memberof Draw */
|
|
182
|
+
function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
|
|
183
|
+
|
|
183
184
|
/** Draw textured tile centered in world space, with color applied if using WebGL
|
|
184
185
|
* @param {Vector2} pos - Center of the tile in world space
|
|
185
186
|
* @param {Vector2} [size=(1,1)] - Size of the tile in world space
|
package/src/engineInput.js
CHANGED
|
@@ -314,9 +314,9 @@ if (isTouchDevice)
|
|
|
314
314
|
// handle all touch events the same way
|
|
315
315
|
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
316
316
|
{
|
|
317
|
-
// fix stalled audio
|
|
318
|
-
if (soundEnable)
|
|
319
|
-
|
|
317
|
+
// fix stalled audio requiring user interaction
|
|
318
|
+
if (soundEnable && audioContext && audioContext.state != 'running')
|
|
319
|
+
zzfx(0);
|
|
320
320
|
|
|
321
321
|
// check if touching and pass to mouse events
|
|
322
322
|
const touching = e.touches.length;
|
|
@@ -357,7 +357,7 @@ function createTouchGamepad()
|
|
|
357
357
|
touchGamepadStick = vec2();
|
|
358
358
|
|
|
359
359
|
const touchHandler = ontouchstart;
|
|
360
|
-
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
360
|
+
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
361
361
|
{
|
|
362
362
|
// clear touch gamepad input
|
|
363
363
|
touchGamepadStick = vec2();
|
|
@@ -462,7 +462,7 @@ function touchGamepadRender()
|
|
|
462
462
|
const rightCenter = vec2(mainCanvasSize.x-touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
463
463
|
for (let i=4; i--;)
|
|
464
464
|
{
|
|
465
|
-
const pos = rightCenter.add(vec2().
|
|
465
|
+
const pos = rightCenter.add(vec2().setDirection(i, touchGamepadSize/2));
|
|
466
466
|
overlayContext.fillStyle = touchGamepadButtons[i] ? '#fff' : '#000';
|
|
467
467
|
overlayContext.beginPath();
|
|
468
468
|
overlayContext.arc(pos.x, pos.y, touchGamepadSize/4, 0,9);
|
package/src/engineMedals.js
CHANGED
|
@@ -90,8 +90,8 @@ class Medal
|
|
|
90
90
|
// draw containing rect and clip to that region
|
|
91
91
|
context.save();
|
|
92
92
|
context.beginPath();
|
|
93
|
-
context.fillStyle =
|
|
94
|
-
context.strokeStyle =
|
|
93
|
+
context.fillStyle = new Color(.9,.9,.9).toString();
|
|
94
|
+
context.strokeStyle = new Color(0,0,0).toString();
|
|
95
95
|
context.lineWidth = 3;
|
|
96
96
|
context.rect(x, y, width, medalDisplaySize.y);
|
|
97
97
|
context.fill();
|
|
@@ -270,7 +270,7 @@ class Newgrounds
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
// build the input object
|
|
273
|
-
const input =
|
|
273
|
+
const input =
|
|
274
274
|
{
|
|
275
275
|
'app_id': this.app_id,
|
|
276
276
|
'session_id': this.session_id,
|
package/src/engineObject.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - Automatically adds self to object list
|
|
11
11
|
* - Will be updated and rendered each frame
|
|
12
12
|
* - Renders as a sprite from a tilesheet by default
|
|
13
|
-
* - Can have color and
|
|
13
|
+
* - Can have color and additive color applied
|
|
14
14
|
* - 2D Physics and collision system
|
|
15
15
|
* - Sorted by renderOrder
|
|
16
16
|
* - Objects can have children attached
|
|
@@ -289,7 +289,7 @@ class EngineObject
|
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
/** Destroy this object, destroy it's children, detach it's parent, and mark it for removal */
|
|
292
|
-
destroy()
|
|
292
|
+
destroy()
|
|
293
293
|
{
|
|
294
294
|
if (this.destroyed)
|
|
295
295
|
return;
|
package/src/engineParticles.js
CHANGED
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
* @example
|
|
11
11
|
* // create a particle emitter
|
|
12
12
|
* let pos = vec2(2,3);
|
|
13
|
-
* let
|
|
13
|
+
* let particleEmitter = new ParticleEmitter
|
|
14
14
|
* (
|
|
15
|
-
* pos, 0, 1, 0, 500, PI,
|
|
16
|
-
* tile(0, 16),
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
|
|
16
|
+
* tile(0, 16), // tileInfo
|
|
17
|
+
* rgb(1,1,1), rgb(0,0,0), // colorStartA, colorStartB
|
|
18
|
+
* rgb(1,1,1,0), rgb(0,0,0,0), // colorEndA, colorEndB
|
|
19
19
|
* 2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
|
|
20
20
|
* .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleCone, fadeRate,
|
|
21
21
|
* .5, 1 // randomness, collide, additive, randomColorLinear, renderOrder
|
|
@@ -202,16 +202,17 @@ class ParticleEmitter extends EngineObject
|
|
|
202
202
|
|
|
203
203
|
// build particle
|
|
204
204
|
const particle = new Particle(pos, this.tileInfo, angle, colorStart, colorEnd, particleTime, sizeStart, sizeEnd, this.fadeRate, this.additive, this.trailScale, this.localSpace && this, this.particleDestroyCallback);
|
|
205
|
-
particle.velocity
|
|
206
|
-
particle.
|
|
207
|
-
particle.
|
|
208
|
-
particle.
|
|
209
|
-
particle.
|
|
210
|
-
particle.
|
|
211
|
-
particle.
|
|
212
|
-
particle.
|
|
213
|
-
particle.
|
|
214
|
-
particle.
|
|
205
|
+
particle.velocity = vec2().setAngle(velocityAngle, speed);
|
|
206
|
+
particle.angleVelocity = angleSpeed;
|
|
207
|
+
particle.fadeRate = this.fadeRate;
|
|
208
|
+
particle.damping = this.damping;
|
|
209
|
+
particle.angleDamping = this.angleDamping;
|
|
210
|
+
particle.elasticity = this.elasticity;
|
|
211
|
+
particle.friction = this.friction;
|
|
212
|
+
particle.gravityScale = this.gravityScale;
|
|
213
|
+
particle.collideTiles = this.collideTiles;
|
|
214
|
+
particle.renderOrder = this.renderOrder;
|
|
215
|
+
particle.mirror = !!randInt(2);
|
|
215
216
|
|
|
216
217
|
// call particle create callaback
|
|
217
218
|
this.particleCreateCallback && this.particleCreateCallback(particle);
|
package/src/engineSettings.js
CHANGED
|
@@ -83,7 +83,7 @@ let tileSizeDefault = vec2(16);
|
|
|
83
83
|
* @type {Number}
|
|
84
84
|
* @default
|
|
85
85
|
* @memberof Settings */
|
|
86
|
-
let tileFixBleedScale = .
|
|
86
|
+
let tileFixBleedScale = .1;
|
|
87
87
|
|
|
88
88
|
///////////////////////////////////////////////////////////////////////////////
|
|
89
89
|
// Object settings
|
|
@@ -94,7 +94,7 @@ let tileFixBleedScale = .3;
|
|
|
94
94
|
* @memberof Settings */
|
|
95
95
|
let enablePhysicsSolver = true;
|
|
96
96
|
|
|
97
|
-
/** Default object mass for
|
|
97
|
+
/** Default object mass for collision calcuations (how heavy objects are)
|
|
98
98
|
* @type {Number}
|
|
99
99
|
* @default
|
|
100
100
|
* @memberof Settings */
|
|
@@ -177,7 +177,7 @@ let touchGamepadEnable = false;
|
|
|
177
177
|
* @memberof Settings */
|
|
178
178
|
let touchGamepadAnalog = true;
|
|
179
179
|
|
|
180
|
-
/** Size of
|
|
180
|
+
/** Size of virtual gamepad for touch devices in pixels
|
|
181
181
|
* @type {Number}
|
|
182
182
|
* @default
|
|
183
183
|
* @memberof Settings */
|
package/src/engineTileLayer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LittleJS Tile Layer System
|
|
3
3
|
* - Caches arrays of tiles to off screen canvas for fast rendering
|
|
4
|
-
* -
|
|
4
|
+
* - Unlimited numbers of layers, allocates canvases as needed
|
|
5
5
|
* - Interfaces with EngineObject for collision
|
|
6
6
|
* - Collision layer is separate from visible layers
|
|
7
7
|
* - It is recommended to have a visible layer that matches the collision
|
|
@@ -53,7 +53,7 @@ function getTileCollisionData(pos)
|
|
|
53
53
|
|
|
54
54
|
/** Check if collision with another object should occur
|
|
55
55
|
* @param {Vector2} pos
|
|
56
|
-
* @param {Vector2} [size=(
|
|
56
|
+
* @param {Vector2} [size=(0,0)]
|
|
57
57
|
* @param {EngineObject} [object]
|
|
58
58
|
* @return {Boolean}
|
|
59
59
|
* @memberof TileCollision */
|
|
@@ -138,7 +138,7 @@ class TileLayerData
|
|
|
138
138
|
* @param {Number} [direction] - Integer direction of tile, in 90 degree increments
|
|
139
139
|
* @param {Boolean} [mirror] - If the tile should be mirrored along the x axis
|
|
140
140
|
* @param {Color} [color] - Color of the tile */
|
|
141
|
-
constructor(tile, direction=0, mirror=false, color=new Color
|
|
141
|
+
constructor(tile, direction=0, mirror=false, color=new Color)
|
|
142
142
|
{
|
|
143
143
|
/** @property {Number} - The tile to use, untextured if undefined */
|
|
144
144
|
this.tile = tile;
|
package/src/engineUtilities.js
CHANGED
|
@@ -36,7 +36,7 @@ function min(valueA, valueB) { return Math.min(valueA, valueB); }
|
|
|
36
36
|
* @memberof Utilities */
|
|
37
37
|
function max(valueA, valueB) { return Math.max(valueA, valueB); }
|
|
38
38
|
|
|
39
|
-
/** Returns the sign of value passed in
|
|
39
|
+
/** Returns the sign of value passed in
|
|
40
40
|
* @param {Number} value
|
|
41
41
|
* @return {Number}
|
|
42
42
|
* @memberof Utilities */
|
|
@@ -83,7 +83,7 @@ function lerp(percent, valueA, valueB) { return valueA + clamp(percent) * (value
|
|
|
83
83
|
function distanceWrap(valueA, valueB, wrapSize=1)
|
|
84
84
|
{ const d = (valueA - valueB) % wrapSize; return d*2 % wrapSize - d; }
|
|
85
85
|
|
|
86
|
-
/** Linearly interpolates between values passed in with
|
|
86
|
+
/** Linearly interpolates between values passed in with wrapping
|
|
87
87
|
* @param {Number} percent
|
|
88
88
|
* @param {Number} valueA
|
|
89
89
|
* @param {Number} valueB
|
|
@@ -100,7 +100,7 @@ function lerpWrap(percent, valueA, valueB, wrapSize=1)
|
|
|
100
100
|
* @memberof Utilities */
|
|
101
101
|
function distanceAngle(angleA, angleB) { return distanceWrap(angleA, angleB, 2*PI); }
|
|
102
102
|
|
|
103
|
-
/** Linearly interpolates between the angles passed in with
|
|
103
|
+
/** Linearly interpolates between the angles passed in with wrapping
|
|
104
104
|
* @param {Number} percent
|
|
105
105
|
* @param {Number} angleA
|
|
106
106
|
* @param {Number} angleB
|
|
@@ -121,13 +121,13 @@ function smoothStep(percent) { return percent * percent * (3 - 2 * percent); }
|
|
|
121
121
|
function nearestPowerOfTwo(value) { return 2**Math.ceil(Math.log2(value)); }
|
|
122
122
|
|
|
123
123
|
/** Returns true if two axis aligned bounding boxes are overlapping
|
|
124
|
-
* @param {Vector2} pointA
|
|
125
|
-
* @param {Vector2} sizeA
|
|
126
|
-
* @param {Vector2} pointB
|
|
127
|
-
* @param {Vector2} sizeB - Size of box B
|
|
128
|
-
* @return {Boolean}
|
|
124
|
+
* @param {Vector2} pointA - Center of box A
|
|
125
|
+
* @param {Vector2} sizeA - Size of box A
|
|
126
|
+
* @param {Vector2} pointB - Center of box B
|
|
127
|
+
* @param {Vector2} [sizeB=(0,0)] - Size of box B, a point if undefined
|
|
128
|
+
* @return {Boolean} - True if overlapping
|
|
129
129
|
* @memberof Utilities */
|
|
130
|
-
function isOverlapping(pointA, sizeA, pointB, sizeB)
|
|
130
|
+
function isOverlapping(pointA, sizeA, pointB, sizeB=vec2())
|
|
131
131
|
{
|
|
132
132
|
return abs(pointA.x - pointB.x)*2 < sizeA.x + sizeB.x
|
|
133
133
|
&& abs(pointA.y - pointB.y)*2 < sizeA.y + sizeB.y;
|
|
@@ -187,8 +187,8 @@ function randInCircle(radius=1, minRadius=0)
|
|
|
187
187
|
{ return radius > 0 ? randVector(radius * rand(minRadius / radius, 1)**.5) : new Vector2; }
|
|
188
188
|
|
|
189
189
|
/** Returns a random color between the two passed in colors, combine components if linear
|
|
190
|
-
* @param {Color} [colorA=
|
|
191
|
-
* @param {Color} [colorB=
|
|
190
|
+
* @param {Color} [colorA=(1,1,1,1)]
|
|
191
|
+
* @param {Color} [colorB=(0,0,0,1)]
|
|
192
192
|
* @param {Boolean} [linear]
|
|
193
193
|
* @return {Color}
|
|
194
194
|
* @memberof Random */
|
|
@@ -259,7 +259,11 @@ class RandomGenerator
|
|
|
259
259
|
* @memberof Utilities
|
|
260
260
|
*/
|
|
261
261
|
function vec2(x=0, y)
|
|
262
|
-
{
|
|
262
|
+
{
|
|
263
|
+
return typeof x === 'number' ?
|
|
264
|
+
new Vector2(x, y == undefined? x : y) :
|
|
265
|
+
new Vector2(x.x, x.y);
|
|
266
|
+
}
|
|
263
267
|
|
|
264
268
|
/**
|
|
265
269
|
* Check if object is a valid Vector2
|
|
@@ -267,7 +271,7 @@ function vec2(x=0, y)
|
|
|
267
271
|
* @return {Boolean}
|
|
268
272
|
* @memberof Utilities
|
|
269
273
|
*/
|
|
270
|
-
function isVector2(v) { return
|
|
274
|
+
function isVector2(v) { return v instanceof Vector2; }
|
|
271
275
|
|
|
272
276
|
/**
|
|
273
277
|
* 2D Vector object with vector math library
|
|
@@ -298,27 +302,47 @@ class Vector2
|
|
|
298
302
|
/** Returns a copy of this vector plus the vector passed in
|
|
299
303
|
* @param {Vector2} v - other vector
|
|
300
304
|
* @return {Vector2} */
|
|
301
|
-
add(v)
|
|
305
|
+
add(v)
|
|
306
|
+
{
|
|
307
|
+
ASSERT(isVector2(v));
|
|
308
|
+
return new Vector2(this.x + v.x, this.y + v.y);
|
|
309
|
+
}
|
|
302
310
|
|
|
303
311
|
/** Returns a copy of this vector minus the vector passed in
|
|
304
312
|
* @param {Vector2} v - other vector
|
|
305
313
|
* @return {Vector2} */
|
|
306
|
-
subtract(v)
|
|
314
|
+
subtract(v)
|
|
315
|
+
{
|
|
316
|
+
ASSERT(isVector2(v));
|
|
317
|
+
return new Vector2(this.x - v.x, this.y - v.y);
|
|
318
|
+
}
|
|
307
319
|
|
|
308
320
|
/** Returns a copy of this vector times the vector passed in
|
|
309
321
|
* @param {Vector2} v - other vector
|
|
310
322
|
* @return {Vector2} */
|
|
311
|
-
multiply(v)
|
|
323
|
+
multiply(v)
|
|
324
|
+
{
|
|
325
|
+
ASSERT(isVector2(v));
|
|
326
|
+
return new Vector2(this.x * v.x, this.y * v.y);
|
|
327
|
+
}
|
|
312
328
|
|
|
313
329
|
/** Returns a copy of this vector divided by the vector passed in
|
|
314
330
|
* @param {Vector2} v - other vector
|
|
315
331
|
* @return {Vector2} */
|
|
316
|
-
divide(v)
|
|
332
|
+
divide(v)
|
|
333
|
+
{
|
|
334
|
+
ASSERT(isVector2(v));
|
|
335
|
+
return new Vector2(this.x / v.x, this.y / v.y);
|
|
336
|
+
}
|
|
317
337
|
|
|
318
338
|
/** Returns a copy of this vector scaled by the vector passed in
|
|
319
339
|
* @param {Number} s - scale
|
|
320
340
|
* @return {Vector2} */
|
|
321
|
-
scale(s)
|
|
341
|
+
scale(s)
|
|
342
|
+
{
|
|
343
|
+
ASSERT(!isVector2(s));
|
|
344
|
+
return new Vector2(this.x * s, this.y * s);
|
|
345
|
+
}
|
|
322
346
|
|
|
323
347
|
/** Returns the length of this vector
|
|
324
348
|
* @return {Number} */
|
|
@@ -331,32 +355,56 @@ class Vector2
|
|
|
331
355
|
/** Returns the distance from this vector to vector passed in
|
|
332
356
|
* @param {Vector2} v - other vector
|
|
333
357
|
* @return {Number} */
|
|
334
|
-
distance(v)
|
|
358
|
+
distance(v)
|
|
359
|
+
{
|
|
360
|
+
ASSERT(isVector2(v));
|
|
361
|
+
return this.distanceSquared(v)**.5;
|
|
362
|
+
}
|
|
335
363
|
|
|
336
364
|
/** Returns the distance squared from this vector to vector passed in
|
|
337
365
|
* @param {Vector2} v - other vector
|
|
338
366
|
* @return {Number} */
|
|
339
|
-
distanceSquared(v)
|
|
367
|
+
distanceSquared(v)
|
|
368
|
+
{
|
|
369
|
+
ASSERT(isVector2(v));
|
|
370
|
+
return (this.x - v.x)**2 + (this.y - v.y)**2;
|
|
371
|
+
}
|
|
340
372
|
|
|
341
373
|
/** Returns a new vector in same direction as this one with the length passed in
|
|
342
374
|
* @param {Number} [length]
|
|
343
375
|
* @return {Vector2} */
|
|
344
|
-
normalize(length=1)
|
|
376
|
+
normalize(length=1)
|
|
377
|
+
{
|
|
378
|
+
const l = this.length();
|
|
379
|
+
return l ? this.scale(length/l) : new Vector2(0, length);
|
|
380
|
+
}
|
|
345
381
|
|
|
346
382
|
/** Returns a new vector clamped to length passed in
|
|
347
383
|
* @param {Number} [length]
|
|
348
384
|
* @return {Vector2} */
|
|
349
|
-
clampLength(length=1)
|
|
385
|
+
clampLength(length=1)
|
|
386
|
+
{
|
|
387
|
+
const l = this.length();
|
|
388
|
+
return l > length ? this.scale(length/l) : this;
|
|
389
|
+
}
|
|
350
390
|
|
|
351
391
|
/** Returns the dot product of this and the vector passed in
|
|
352
392
|
* @param {Vector2} v - other vector
|
|
353
393
|
* @return {Number} */
|
|
354
|
-
dot(v)
|
|
394
|
+
dot(v)
|
|
395
|
+
{
|
|
396
|
+
ASSERT(isVector2(v));
|
|
397
|
+
return this.x*v.x + this.y*v.y;
|
|
398
|
+
}
|
|
355
399
|
|
|
356
400
|
/** Returns the cross product of this and the vector passed in
|
|
357
401
|
* @param {Vector2} v - other vector
|
|
358
402
|
* @return {Number} */
|
|
359
|
-
cross(v)
|
|
403
|
+
cross(v)
|
|
404
|
+
{
|
|
405
|
+
ASSERT(isVector2(v));
|
|
406
|
+
return this.x*v.y - this.y*v.x;
|
|
407
|
+
}
|
|
360
408
|
|
|
361
409
|
/** Returns the angle of this vector, up is angle 0
|
|
362
410
|
* @return {Number} */
|
|
@@ -367,7 +415,11 @@ class Vector2
|
|
|
367
415
|
* @param {Number} [length]
|
|
368
416
|
* @return {Vector2} */
|
|
369
417
|
setAngle(angle=0, length=1)
|
|
370
|
-
{
|
|
418
|
+
{
|
|
419
|
+
this.x = length*Math.sin(angle);
|
|
420
|
+
this.y = length*Math.cos(angle);
|
|
421
|
+
return this;
|
|
422
|
+
}
|
|
371
423
|
|
|
372
424
|
/** Returns copy of this vector rotated by the angle passed in
|
|
373
425
|
* @param {Number} angle
|
|
@@ -378,9 +430,20 @@ class Vector2
|
|
|
378
430
|
return new Vector2(this.x*c - this.y*s, this.x*s + this.y*c);
|
|
379
431
|
}
|
|
380
432
|
|
|
433
|
+
/** Set the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)
|
|
434
|
+
* @param {Number} [direction]
|
|
435
|
+
* @param {Number} [length] */
|
|
436
|
+
setDirection(direction, length=1)
|
|
437
|
+
{
|
|
438
|
+
ASSERT(direction==0 || direction==1 || direction==2 || direction==3);
|
|
439
|
+
return vec2(direction%2 ? direction-1 ? -length : length : 0,
|
|
440
|
+
direction%2 ? 0 : direction ? -length : length);
|
|
441
|
+
}
|
|
442
|
+
|
|
381
443
|
/** Returns the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)
|
|
382
444
|
* @return {Number} */
|
|
383
|
-
direction()
|
|
445
|
+
direction()
|
|
446
|
+
{ return abs(this.x) > abs(this.y) ? this.x < 0 ? 3 : 1 : this.y < 0 ? 2 : 0; }
|
|
384
447
|
|
|
385
448
|
/** Returns a copy of this vector that has been inverted
|
|
386
449
|
* @return {Vector2} */
|
|
@@ -399,24 +462,34 @@ class Vector2
|
|
|
399
462
|
* @param {Number} percent
|
|
400
463
|
* @return {Vector2} */
|
|
401
464
|
lerp(v, percent)
|
|
402
|
-
{
|
|
465
|
+
{
|
|
466
|
+
ASSERT(isVector2(v));
|
|
467
|
+
return this.add(v.subtract(this).scale(clamp(percent)));
|
|
468
|
+
}
|
|
403
469
|
|
|
404
470
|
/** Returns true if this vector is within the bounds of an array size passed in
|
|
405
471
|
* @param {Vector2} arraySize
|
|
406
472
|
* @return {Boolean} */
|
|
407
|
-
arrayCheck(arraySize)
|
|
473
|
+
arrayCheck(arraySize)
|
|
474
|
+
{
|
|
475
|
+
ASSERT(isVector2(arraySize));
|
|
476
|
+
return this.x >= 0 && this.y >= 0 && this.x < arraySize.x && this.y < arraySize.y;
|
|
477
|
+
}
|
|
408
478
|
|
|
409
479
|
/** Returns this vector expressed as a string
|
|
410
480
|
* @param {Number} digits - precision to display
|
|
411
481
|
* @return {String} */
|
|
412
482
|
toString(digits=3)
|
|
413
|
-
{
|
|
483
|
+
{
|
|
484
|
+
if (debug)
|
|
485
|
+
return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`;
|
|
486
|
+
}
|
|
414
487
|
}
|
|
415
488
|
|
|
416
489
|
///////////////////////////////////////////////////////////////////////////////
|
|
417
490
|
|
|
418
491
|
/**
|
|
419
|
-
* Create a color object with RGBA values
|
|
492
|
+
* Create a color object with RGBA values, white by default
|
|
420
493
|
* @param {Number} [r=1] - red
|
|
421
494
|
* @param {Number} [g=1] - green
|
|
422
495
|
* @param {Number} [b=1] - blue
|
|
@@ -427,7 +500,7 @@ class Vector2
|
|
|
427
500
|
function rgb(r, g, b, a) { return new Color(r, g, b, a); }
|
|
428
501
|
|
|
429
502
|
/**
|
|
430
|
-
* Create a color object with HSLA values
|
|
503
|
+
* Create a color object with HSLA values, white by default
|
|
431
504
|
* @param {Number} [h=0] - hue
|
|
432
505
|
* @param {Number} [s=0] - saturation
|
|
433
506
|
* @param {Number} [l=1] - lightness
|
|
@@ -437,14 +510,22 @@ function rgb(r, g, b, a) { return new Color(r, g, b, a); }
|
|
|
437
510
|
*/
|
|
438
511
|
function hsl(h, s, l, a) { return new Color().setHSLA(h, s, l, a); }
|
|
439
512
|
|
|
513
|
+
/**
|
|
514
|
+
* Check if object is a valid Color
|
|
515
|
+
* @param {any} c
|
|
516
|
+
* @return {Boolean}
|
|
517
|
+
* @memberof Utilities
|
|
518
|
+
*/
|
|
519
|
+
function isColor(c) { return c instanceof Color; }
|
|
520
|
+
|
|
440
521
|
/**
|
|
441
522
|
* Color object (red, green, blue, alpha) with some helpful functions
|
|
442
523
|
* @example
|
|
443
524
|
* let a = new Color; // white
|
|
444
525
|
* let b = new Color(1, 0, 0); // red
|
|
445
526
|
* let c = new Color(0, 0, 0, 0); // transparent black
|
|
446
|
-
* let d =
|
|
447
|
-
* let e =
|
|
527
|
+
* let d = rgb(0, 0, 1); // blue using rgb color
|
|
528
|
+
* let e = hsl(.3, 1, .5); // green using hsl color
|
|
448
529
|
*/
|
|
449
530
|
class Color
|
|
450
531
|
{
|
|
@@ -472,22 +553,38 @@ class Color
|
|
|
472
553
|
/** Returns a copy of this color plus the color passed in
|
|
473
554
|
* @param {Color} c - other color
|
|
474
555
|
* @return {Color} */
|
|
475
|
-
add(c)
|
|
556
|
+
add(c)
|
|
557
|
+
{
|
|
558
|
+
ASSERT(isColor(c));
|
|
559
|
+
return new Color(this.r+c.r, this.g+c.g, this.b+c.b, this.a+c.a);
|
|
560
|
+
}
|
|
476
561
|
|
|
477
562
|
/** Returns a copy of this color minus the color passed in
|
|
478
563
|
* @param {Color} c - other color
|
|
479
564
|
* @return {Color} */
|
|
480
|
-
subtract(c)
|
|
565
|
+
subtract(c)
|
|
566
|
+
{
|
|
567
|
+
ASSERT(isColor(c));
|
|
568
|
+
return new Color(this.r-c.r, this.g-c.g, this.b-c.b, this.a-c.a);
|
|
569
|
+
}
|
|
481
570
|
|
|
482
571
|
/** Returns a copy of this color times the color passed in
|
|
483
572
|
* @param {Color} c - other color
|
|
484
573
|
* @return {Color} */
|
|
485
|
-
multiply(c)
|
|
574
|
+
multiply(c)
|
|
575
|
+
{
|
|
576
|
+
ASSERT(isColor(c));
|
|
577
|
+
return new Color(this.r*c.r, this.g*c.g, this.b*c.b, this.a*c.a);
|
|
578
|
+
}
|
|
486
579
|
|
|
487
580
|
/** Returns a copy of this color divided by the color passed in
|
|
488
581
|
* @param {Color} c - other color
|
|
489
582
|
* @return {Color} */
|
|
490
|
-
divide(c)
|
|
583
|
+
divide(c)
|
|
584
|
+
{
|
|
585
|
+
ASSERT(isColor(c));
|
|
586
|
+
return new Color(this.r/c.r, this.g/c.g, this.b/c.b, this.a/c.a);
|
|
587
|
+
}
|
|
491
588
|
|
|
492
589
|
/** Returns a copy of this color scaled by the value passed in, alpha can be scaled separately
|
|
493
590
|
* @param {Number} scale
|
|
@@ -504,7 +601,11 @@ class Color
|
|
|
504
601
|
* @param {Color} c - other color
|
|
505
602
|
* @param {Number} percent
|
|
506
603
|
* @return {Color} */
|
|
507
|
-
lerp(c, percent)
|
|
604
|
+
lerp(c, percent)
|
|
605
|
+
{
|
|
606
|
+
ASSERT(isColor(c));
|
|
607
|
+
return this.add(c.subtract(this).scale(clamp(percent)));
|
|
608
|
+
}
|
|
508
609
|
|
|
509
610
|
/** Sets this color given a hue, saturation, lightness, and alpha
|
|
510
611
|
* @param {Number} [h] - hue
|
package/src/engineWebGL.js
CHANGED
|
@@ -193,8 +193,6 @@ function glCreateTexture(image)
|
|
|
193
193
|
const filter = canvasPixelated ? gl_NEAREST : gl_LINEAR;
|
|
194
194
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, filter);
|
|
195
195
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, filter);
|
|
196
|
-
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE);
|
|
197
|
-
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE);
|
|
198
196
|
|
|
199
197
|
return texture;
|
|
200
198
|
}
|
|
@@ -251,7 +249,7 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
|
|
|
251
249
|
ASSERT(typeof rgba == 'number' && typeof rgbaAdditive == 'number', 'invalid color');
|
|
252
250
|
|
|
253
251
|
// flush if there is not enough room or if different blend mode
|
|
254
|
-
if (glInstanceCount >= gl_MAX_INSTANCES
|
|
252
|
+
if (glInstanceCount >= gl_MAX_INSTANCES || glBatchAdditive != glAdditive)
|
|
255
253
|
glFlush();
|
|
256
254
|
|
|
257
255
|
let offset = glInstanceCount * gl_INDICIES_PER_INSTANCE;
|
|
@@ -272,7 +270,7 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
|
|
|
272
270
|
///////////////////////////////////////////////////////////////////////////////
|
|
273
271
|
// post processing - can be enabled to pass other canvases through a final shader
|
|
274
272
|
|
|
275
|
-
let glPostShader,
|
|
273
|
+
let glPostShader, glPostTexture, glPostIncludeOverlay;
|
|
276
274
|
|
|
277
275
|
/** Set up a post processing shader
|
|
278
276
|
* @param {String} shaderCode
|
|
@@ -308,7 +306,6 @@ function glInitPostProcess(shaderCode, includeOverlay=false)
|
|
|
308
306
|
);
|
|
309
307
|
|
|
310
308
|
// create buffer and texture
|
|
311
|
-
glPostArrayBuffer = glContext.createBuffer();
|
|
312
309
|
glPostTexture = glCreateTexture(undefined);
|
|
313
310
|
glPostIncludeOverlay = includeOverlay;
|
|
314
311
|
|
|
@@ -380,10 +377,7 @@ gl_NEAREST = 9728,
|
|
|
380
377
|
gl_LINEAR = 9729,
|
|
381
378
|
gl_TEXTURE_MAG_FILTER = 10240,
|
|
382
379
|
gl_TEXTURE_MIN_FILTER = 10241,
|
|
383
|
-
gl_TEXTURE_WRAP_S = 10242,
|
|
384
|
-
gl_TEXTURE_WRAP_T = 10243,
|
|
385
380
|
gl_COLOR_BUFFER_BIT = 16384,
|
|
386
|
-
gl_CLAMP_TO_EDGE = 33071,
|
|
387
381
|
gl_TEXTURE0 = 33984,
|
|
388
382
|
gl_ARRAY_BUFFER = 34962,
|
|
389
383
|
gl_STATIC_DRAW = 35044,
|