littlejsengine 1.8.6 → 1.8.9
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 +9 -3
- package/build/littlejs.d.ts +18 -9
- package/build/littlejs.esm.js +298 -92
- package/build/littlejs.esm.min.js +1 -1
- package/build/littlejs.js +296 -92
- package/build/littlejs.min.js +1 -1
- package/build/littlejs.release.js +296 -92
- package/examples/breakout/game.js +3 -0
- package/examples/breakout/index.html +3 -3
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/electron/game.js +3 -0
- package/examples/electron/index.html +2 -2
- package/examples/js13k/index.html +13 -13
- package/examples/logo.png +0 -0
- package/examples/module/game.js +3 -0
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +1 -1
- package/examples/platformer/game.js +3 -0
- package/examples/platformer/gameEffects.js +1 -1
- package/examples/platformer/index.html +6 -6
- package/examples/puzzle/game.js +3 -0
- package/examples/puzzle/index.html +2 -2
- package/examples/starter/game.js +4 -1
- package/examples/starter/index.html +13 -13
- package/examples/starter/tiles.png +0 -0
- package/examples/stress/index.html +3 -1
- package/examples/typescript/game.js +2 -0
- package/examples/typescript/game.ts +3 -0
- package/examples/typescript/index.html +1 -1
- package/package.json +1 -1
- package/src/engine.js +189 -9
- package/src/engineAudio.js +72 -58
- package/src/engineDraw.js +1 -1
- package/src/engineExport.js +2 -0
- package/src/engineParticles.js +7 -7
- package/src/engineSettings.js +11 -0
- package/src/engineUtilities.js +4 -5
- package/src/engineWebGL.js +12 -12
|
@@ -631,11 +631,10 @@ class Color
|
|
|
631
631
|
* @return {Number} */
|
|
632
632
|
rgbaInt()
|
|
633
633
|
{
|
|
634
|
-
const
|
|
635
|
-
const
|
|
636
|
-
const
|
|
637
|
-
const
|
|
638
|
-
const a = toByte(this.a)<<24;
|
|
634
|
+
const r = clamp(this.r)*255|0;
|
|
635
|
+
const g = clamp(this.g)*255<<8;
|
|
636
|
+
const b = clamp(this.b)*255<<16;
|
|
637
|
+
const a = clamp(this.a)*255<<24;
|
|
639
638
|
return r + g + b + a;
|
|
640
639
|
}
|
|
641
640
|
}
|
|
@@ -743,6 +742,12 @@ let canvasPixelated = 1;
|
|
|
743
742
|
* @memberof Settings */
|
|
744
743
|
let fontDefault = 'arial';
|
|
745
744
|
|
|
745
|
+
/** Enable to show the LittleJS splash screen be shown on startup
|
|
746
|
+
* @type {Boolean}
|
|
747
|
+
* @default
|
|
748
|
+
* @memberof Settings */
|
|
749
|
+
let showSplashScreen = 0;
|
|
750
|
+
|
|
746
751
|
///////////////////////////////////////////////////////////////////////////////
|
|
747
752
|
// WebGL settings
|
|
748
753
|
|
|
@@ -976,6 +981,11 @@ function setCanvasPixelated(pixelated) { canvasPixelated = pixelated; }
|
|
|
976
981
|
* @memberof Settings */
|
|
977
982
|
function setFontDefault(font) { fontDefault = font; }
|
|
978
983
|
|
|
984
|
+
/** Set if the LittleJS splash screen be shown on startup
|
|
985
|
+
* @param {Boolean} show
|
|
986
|
+
* @memberof Settings */
|
|
987
|
+
function setShowSplashScreen(show) { showSplashScreen = show; }
|
|
988
|
+
|
|
979
989
|
/** Set if webgl rendering is enabled
|
|
980
990
|
* @param {Boolean} enable
|
|
981
991
|
* @memberof Settings */
|
|
@@ -1567,7 +1577,7 @@ let mainCanvasSize = vec2();
|
|
|
1567
1577
|
* @memberof Draw */
|
|
1568
1578
|
let textureInfos = [];
|
|
1569
1579
|
|
|
1570
|
-
//
|
|
1580
|
+
// Keep track of how many draw calls there were each frame for debugging
|
|
1571
1581
|
let drawCount;
|
|
1572
1582
|
|
|
1573
1583
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -2809,7 +2819,7 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0, sampleRate
|
|
|
2809
2819
|
}
|
|
2810
2820
|
|
|
2811
2821
|
///////////////////////////////////////////////////////////////////////////////
|
|
2812
|
-
// ZzFXMicro - Zuper Zmall Zound Zynth - v1.
|
|
2822
|
+
// ZzFXMicro - Zuper Zmall Zound Zynth - v1.3.0 by Frank Force
|
|
2813
2823
|
|
|
2814
2824
|
/** Generate and play a ZzFX sound
|
|
2815
2825
|
*
|
|
@@ -2845,6 +2855,7 @@ const zzfxR = 44100;
|
|
|
2845
2855
|
* @param {Number} [sustainVolume=1] - Volume level for sustain (percent)
|
|
2846
2856
|
* @param {Number} [decay=0] - Decay time, how long to reach sustain after attack (seconds)
|
|
2847
2857
|
* @param {Number} [tremolo=0] - Trembling effect, rate controlled by repeat time (precent)
|
|
2858
|
+
* @param {Number} [filter=0] - Filter cutoff frequency, positive for HPF, negative for LPF (Hz)
|
|
2848
2859
|
* @return {Array} - Array of audio samples
|
|
2849
2860
|
* @memberof Audio
|
|
2850
2861
|
*/
|
|
@@ -2854,78 +2865,91 @@ function zzfxG
|
|
|
2854
2865
|
volume = 1, randomness = .05, frequency = 220, attack = 0, sustain = 0,
|
|
2855
2866
|
release = .1, shape = 0, shapeCurve = 1, slide = 0, deltaSlide = 0,
|
|
2856
2867
|
pitchJump = 0, pitchJumpTime = 0, repeatTime = 0, noise = 0, modulation = 0,
|
|
2857
|
-
bitCrush = 0, delay = 0, sustainVolume = 1, decay = 0, tremolo = 0
|
|
2868
|
+
bitCrush = 0, delay = 0, sustainVolume = 1, decay = 0, tremolo = 0, filter = 0
|
|
2858
2869
|
)
|
|
2859
2870
|
{
|
|
2860
|
-
//
|
|
2861
|
-
let PI2 = PI*2,
|
|
2862
|
-
|
|
2863
|
-
|
|
2871
|
+
// init parameters
|
|
2872
|
+
let PI2 = PI*2, sampleRate = zzfxR,
|
|
2873
|
+
startSlide = slide *= 500 * PI2 / sampleRate / sampleRate,
|
|
2874
|
+
startFrequency = frequency *=
|
|
2875
|
+
rand(1 + randomness, 1-randomness) * PI2 / sampleRate,
|
|
2876
|
+
b = [], t = 0, tm = 0, i = 0, j = 1, r = 0, c = 0, s = 0, f, length,
|
|
2877
|
+
|
|
2878
|
+
// biquad LP/HP filter
|
|
2879
|
+
quality = 2, w = PI2 * abs(filter) * 2 / sampleRate,
|
|
2880
|
+
cos = Math.cos(w), alpha = Math.sin(w) / 2 / quality,
|
|
2881
|
+
a0 = 1 + alpha, a1 = -2*cos / a0, a2 = (1 - alpha) / a0,
|
|
2882
|
+
b0 = (1 + sign(filter) * cos) / 2 / a0,
|
|
2883
|
+
b1 = -(sign(filter) + cos) / a0, b2 = b0,
|
|
2884
|
+
x2 = 0, x1 = 0, y2 = 0, y1 = 0;
|
|
2864
2885
|
|
|
2865
2886
|
// scale by sample rate
|
|
2866
|
-
attack = attack *
|
|
2867
|
-
decay *=
|
|
2868
|
-
sustain *=
|
|
2869
|
-
release *=
|
|
2870
|
-
delay *=
|
|
2871
|
-
deltaSlide *= 500 * PI2 /
|
|
2872
|
-
modulation *= PI2 /
|
|
2873
|
-
pitchJump *= PI2 /
|
|
2874
|
-
pitchJumpTime *=
|
|
2875
|
-
repeatTime = repeatTime *
|
|
2887
|
+
attack = attack * sampleRate + 9; // minimum attack to prevent pop
|
|
2888
|
+
decay *= sampleRate;
|
|
2889
|
+
sustain *= sampleRate;
|
|
2890
|
+
release *= sampleRate;
|
|
2891
|
+
delay *= sampleRate;
|
|
2892
|
+
deltaSlide *= 500 * PI2 / sampleRate**3;
|
|
2893
|
+
modulation *= PI2 / sampleRate;
|
|
2894
|
+
pitchJump *= PI2 / sampleRate;
|
|
2895
|
+
pitchJumpTime *= sampleRate;
|
|
2896
|
+
repeatTime = repeatTime * sampleRate | 0;
|
|
2897
|
+
volume *= soundVolume;
|
|
2876
2898
|
|
|
2877
2899
|
// generate waveform
|
|
2878
|
-
for
|
|
2879
|
-
i < length; b[i++] = s)
|
|
2900
|
+
for(length = attack + decay + sustain + release + delay | 0;
|
|
2901
|
+
i < length; b[i++] = s * volume) // sample
|
|
2880
2902
|
{
|
|
2881
|
-
if (!(++c%(bitCrush*100|0)))
|
|
2903
|
+
if (!(++c%(bitCrush*100|0))) // bit crush
|
|
2882
2904
|
{
|
|
2883
|
-
s = shape? shape>1? shape>2? shape>3?
|
|
2884
|
-
Math.sin(
|
|
2885
|
-
|
|
2886
|
-
1-(2*t/PI2%2+2)%2:
|
|
2887
|
-
1-4*abs(Math.round(t/PI2)-t/PI2):
|
|
2888
|
-
Math.sin(t);
|
|
2889
|
-
|
|
2905
|
+
s = shape? shape>1? shape>2? shape>3? // wave shape
|
|
2906
|
+
Math.sin(t*t) : // 4 noise
|
|
2907
|
+
clamp(Math.tan(t),1,-1): // 3 tan
|
|
2908
|
+
1-(2*t/PI2%2+2)%2: // 2 saw
|
|
2909
|
+
1-4*abs(Math.round(t/PI2)-t/PI2): // 1 triangle
|
|
2910
|
+
Math.sin(t); // 0 sin
|
|
2911
|
+
|
|
2890
2912
|
s = (repeatTime ?
|
|
2891
2913
|
1 - tremolo + tremolo*Math.sin(PI2*i/repeatTime) // tremolo
|
|
2892
2914
|
: 1) *
|
|
2893
|
-
sign(s)*(abs(s)**shapeCurve) *
|
|
2894
|
-
|
|
2895
|
-
i < attack
|
|
2896
|
-
i
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
f = (frequency += slide += deltaSlide) * // frequency
|
|
2911
|
-
Math.cos(modulation*tm++); // modulation
|
|
2912
|
-
t += f - f*noise*(1 - (Math.sin(i)+1)*1e9%2); // noise
|
|
2913
|
-
|
|
2914
|
-
if (j && ++j > pitchJumpTime) // pitch jump
|
|
2915
|
-
{
|
|
2916
|
-
frequency += pitchJump; // apply pitch jump
|
|
2917
|
-
startFrequency += pitchJump; // also apply to start
|
|
2918
|
-
j = 0; // reset pitch jump time
|
|
2915
|
+
sign(s)*(abs(s)**shapeCurve) * // curve
|
|
2916
|
+
(i < attack ? i/attack : // attack
|
|
2917
|
+
i < attack + decay ? // decay
|
|
2918
|
+
1-((i-attack)/decay)*(1-sustainVolume) : // decay falloff
|
|
2919
|
+
i < attack + decay + sustain ? // sustain
|
|
2920
|
+
sustainVolume : // sustain volume
|
|
2921
|
+
i < length - delay ? // release
|
|
2922
|
+
(length - i - delay)/release * // release falloff
|
|
2923
|
+
sustainVolume : // release volume
|
|
2924
|
+
0); // post release
|
|
2925
|
+
|
|
2926
|
+
s = delay ? s/2 + (delay > i ? 0 : // delay
|
|
2927
|
+
(i<length-delay? 1 : (length-i)/delay) * // release delay
|
|
2928
|
+
b[i-delay|0]/2/volume) : s; // sample delay
|
|
2929
|
+
|
|
2930
|
+
if (filter) // apply filter
|
|
2931
|
+
s = y1 = b2*x2 + b1*(x2=x1) + b0*(x1=s) - a2*y2 - a1*(y2=y1);
|
|
2919
2932
|
}
|
|
2920
2933
|
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2934
|
+
f = (frequency += slide += deltaSlide) *// frequency
|
|
2935
|
+
Math.cos(modulation*tm++); // modulation
|
|
2936
|
+
t += f + f*noise*Math.sin(i**5); // noise
|
|
2937
|
+
|
|
2938
|
+
if (j && ++j > pitchJumpTime) // pitch jump
|
|
2939
|
+
{
|
|
2940
|
+
frequency += pitchJump; // apply pitch jump
|
|
2941
|
+
startFrequency += pitchJump; // also apply to start
|
|
2942
|
+
j = 0; // stop pitch jump time
|
|
2943
|
+
}
|
|
2944
|
+
|
|
2945
|
+
if (repeatTime && !(++r % repeatTime)) // repeat
|
|
2946
|
+
{
|
|
2947
|
+
frequency = startFrequency; // reset frequency
|
|
2948
|
+
slide = startSlide; // reset slide
|
|
2949
|
+
j = j || 1; // reset pitch jump time
|
|
2926
2950
|
}
|
|
2927
2951
|
}
|
|
2928
|
-
|
|
2952
|
+
|
|
2929
2953
|
return b;
|
|
2930
2954
|
}
|
|
2931
2955
|
|
|
@@ -3421,13 +3445,13 @@ constructor(pos, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderO
|
|
|
3421
3445
|
class ParticleEmitter extends EngineObject
|
|
3422
3446
|
{
|
|
3423
3447
|
/** Create a particle system with the given settings
|
|
3424
|
-
* @param {Vector2} position
|
|
3425
|
-
* @param {Number} [angle=0]
|
|
3426
|
-
* @param {Number} [emitSize=0]
|
|
3427
|
-
* @param {Number} [emitTime=0]
|
|
3428
|
-
* @param {Number} [emitRate=100]
|
|
3448
|
+
* @param {Vector2} position - World space position of the emitter
|
|
3449
|
+
* @param {Number} [angle=0] - Angle to emit the particles
|
|
3450
|
+
* @param {Number|Vector2} [emitSize=0] - World space size of the emitter (float for circle diameter, vec2 for rect)
|
|
3451
|
+
* @param {Number} [emitTime=0] - How long to stay alive (0 is forever)
|
|
3452
|
+
* @param {Number} [emitRate=100] - How many particles per second to spawn, does not emit if 0
|
|
3429
3453
|
* @param {Number} [emitConeAngle=PI] - Local angle to apply velocity to particles from emitter
|
|
3430
|
-
* @param {TileInfo} [tileInfo]
|
|
3454
|
+
* @param {TileInfo} [tileInfo] - Tile info to render particles (undefined is untextured)
|
|
3431
3455
|
* @param {Color} [colorStartA=Color()] - Color at start of life 1, randomized between start colors
|
|
3432
3456
|
* @param {Color} [colorStartB=Color()] - Color at start of life 2, randomized between start colors
|
|
3433
3457
|
* @param {Color} [colorEndA=Color(1,1,1,0)] - Color at end of life 1, randomized between end colors
|
|
@@ -3483,7 +3507,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3483
3507
|
super(pos, vec2(), tileInfo, angle, undefined, renderOrder);
|
|
3484
3508
|
|
|
3485
3509
|
// emitter settings
|
|
3486
|
-
/** @property {Number} - World space size of the emitter (float for circle diameter, vec2 for rect) */
|
|
3510
|
+
/** @property {Number|Vector2} - World space size of the emitter (float for circle diameter, vec2 for rect) */
|
|
3487
3511
|
this.emitSize = emitSize
|
|
3488
3512
|
/** @property {Number} - How long to stay alive (0 is forever) */
|
|
3489
3513
|
this.emitTime = emitTime;
|
|
@@ -4015,7 +4039,7 @@ let glCanvas;
|
|
|
4015
4039
|
let glContext;
|
|
4016
4040
|
|
|
4017
4041
|
// WebGL internal variables not exposed to documentation
|
|
4018
|
-
let glActiveTexture, glShader, glArrayBuffer, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
|
|
4042
|
+
let glActiveTexture, glShader, glArrayBuffer, glVertexData, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
|
|
4019
4043
|
|
|
4020
4044
|
///////////////////////////////////////////////////////////////////////////////
|
|
4021
4045
|
|
|
@@ -4052,10 +4076,10 @@ function glInit()
|
|
|
4052
4076
|
);
|
|
4053
4077
|
|
|
4054
4078
|
// init buffers
|
|
4055
|
-
|
|
4079
|
+
glVertexData = new ArrayBuffer(gl_VERTEX_BUFFER_SIZE);
|
|
4080
|
+
glPositionData = new Float32Array(glVertexData);
|
|
4081
|
+
glColorData = new Uint32Array(glVertexData);
|
|
4056
4082
|
glArrayBuffer = glContext.createBuffer();
|
|
4057
|
-
glPositionData = new Float32Array(vertexData);
|
|
4058
|
-
glColorData = new Uint32Array(vertexData);
|
|
4059
4083
|
glBatchCount = 0;
|
|
4060
4084
|
}
|
|
4061
4085
|
|
|
@@ -4083,7 +4107,7 @@ function glPreRender()
|
|
|
4083
4107
|
glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
|
|
4084
4108
|
offset += size*typeSize;
|
|
4085
4109
|
}
|
|
4086
|
-
initVertexAttribArray('p', gl_FLOAT, 4, 4); // position & texture
|
|
4110
|
+
initVertexAttribArray('p', gl_FLOAT, 4, 4); // position & texture
|
|
4087
4111
|
initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
|
|
4088
4112
|
initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
|
|
4089
4113
|
|
|
@@ -4171,6 +4195,7 @@ function glCreateTexture(image)
|
|
|
4171
4195
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, filter);
|
|
4172
4196
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE);
|
|
4173
4197
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE);
|
|
4198
|
+
|
|
4174
4199
|
return texture;
|
|
4175
4200
|
}
|
|
4176
4201
|
|
|
@@ -4185,8 +4210,7 @@ function glFlush()
|
|
|
4185
4210
|
glContext.enable(gl_BLEND);
|
|
4186
4211
|
|
|
4187
4212
|
// draw all the sprites in the batch and reset the buffer
|
|
4188
|
-
glContext.bufferSubData(gl_ARRAY_BUFFER, 0,
|
|
4189
|
-
glPositionData.subarray(0, glBatchCount * gl_INDICIES_PER_VERT));
|
|
4213
|
+
glContext.bufferSubData(gl_ARRAY_BUFFER, 0, glVertexData);
|
|
4190
4214
|
glContext.drawArrays(gl_TRIANGLE_STRIP, 0, glBatchCount);
|
|
4191
4215
|
glBatchCount = 0;
|
|
4192
4216
|
glBatchAdditive = glAdditive;
|
|
@@ -4241,11 +4265,11 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
|
|
|
4241
4265
|
// setup 2 triangle strip quad
|
|
4242
4266
|
for(let i = vertCount, offset = glBatchCount * gl_INDICIES_PER_VERT; i--;)
|
|
4243
4267
|
{
|
|
4244
|
-
|
|
4245
|
-
glPositionData[offset++] = positionData[j
|
|
4246
|
-
glPositionData[offset++] = positionData[j
|
|
4247
|
-
glPositionData[offset++] = positionData[j
|
|
4248
|
-
glPositionData[offset++] = positionData[j
|
|
4268
|
+
const j = clamp(i-1, 0, 3)*4; // degenerate tri at ends
|
|
4269
|
+
glPositionData[offset++] = positionData[j+0];
|
|
4270
|
+
glPositionData[offset++] = positionData[j+1];
|
|
4271
|
+
glPositionData[offset++] = positionData[j+2];
|
|
4272
|
+
glPositionData[offset++] = positionData[j+3];
|
|
4249
4273
|
glColorData[offset++] = rgba;
|
|
4250
4274
|
glColorData[offset++] = rgbaAdditive;
|
|
4251
4275
|
}
|
|
@@ -4446,7 +4470,7 @@ const engineName = 'LittleJS';
|
|
|
4446
4470
|
* @type {String}
|
|
4447
4471
|
* @default
|
|
4448
4472
|
* @memberof Engine */
|
|
4449
|
-
const engineVersion = '1.8.
|
|
4473
|
+
const engineVersion = '1.8.9';
|
|
4450
4474
|
|
|
4451
4475
|
/** Frames per second to update objects
|
|
4452
4476
|
* @type {Number}
|
|
@@ -4629,7 +4653,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4629
4653
|
}
|
|
4630
4654
|
|
|
4631
4655
|
// setup html
|
|
4632
|
-
|
|
4656
|
+
const styleBody =
|
|
4633
4657
|
'margin:0;overflow:hidden;' + // fill the window
|
|
4634
4658
|
'background:#000;' + // set background color
|
|
4635
4659
|
'touch-action:none;' + // prevent mobile pinch to resize
|
|
@@ -4650,14 +4674,13 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4650
4674
|
|
|
4651
4675
|
// set canvas style
|
|
4652
4676
|
const styleCanvas =
|
|
4653
|
-
'position:absolute;' +
|
|
4654
|
-
'top:50%;left:50%;transform:translate(-50%,-50%);
|
|
4655
|
-
(canvasPixelated?'image-rendering:pixelated':''); // pixelated rendering
|
|
4677
|
+
'position:absolute;' + // position
|
|
4678
|
+
'top:50%;left:50%;transform:translate(-50%,-50%)'; // center
|
|
4656
4679
|
(glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
|
|
4657
4680
|
|
|
4658
|
-
//
|
|
4659
|
-
|
|
4660
|
-
new Promise(
|
|
4681
|
+
// create promises for loading images
|
|
4682
|
+
const promises = imageSources.map((src, textureIndex)=>
|
|
4683
|
+
new Promise(resolve =>
|
|
4661
4684
|
{
|
|
4662
4685
|
const image = new Image;
|
|
4663
4686
|
image.onerror = image.onload = ()=>
|
|
@@ -4667,7 +4690,24 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4667
4690
|
}
|
|
4668
4691
|
image.src = src;
|
|
4669
4692
|
})
|
|
4670
|
-
)
|
|
4693
|
+
)
|
|
4694
|
+
|
|
4695
|
+
// draw splash screen
|
|
4696
|
+
showSplashScreen && promises.push(new Promise(resolve =>
|
|
4697
|
+
{
|
|
4698
|
+
let t = 0;
|
|
4699
|
+
console.log(`LittleJS Engine v${engineVersion}`);
|
|
4700
|
+
updateSplash();
|
|
4701
|
+
function updateSplash()
|
|
4702
|
+
{
|
|
4703
|
+
clearInput();
|
|
4704
|
+
drawEngineSplashScreen(t+=.01);
|
|
4705
|
+
t>1 ? resolve() : setTimeout(updateSplash,16);
|
|
4706
|
+
}
|
|
4707
|
+
}));
|
|
4708
|
+
|
|
4709
|
+
// load all of the images
|
|
4710
|
+
Promise.all(promises).then(()=>
|
|
4671
4711
|
{
|
|
4672
4712
|
// start the engine
|
|
4673
4713
|
gameInit();
|
|
@@ -4745,4 +4785,168 @@ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObject
|
|
|
4745
4785
|
for (const o of objects)
|
|
4746
4786
|
pos.distanceSquared(o.pos) < sizeSquared && callbackFunction(o);
|
|
4747
4787
|
}
|
|
4788
|
+
}
|
|
4789
|
+
|
|
4790
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
4791
|
+
// LittleJS splash screen and logo
|
|
4792
|
+
|
|
4793
|
+
function drawEngineSplashScreen(t)
|
|
4794
|
+
{
|
|
4795
|
+
const x = mainContext;
|
|
4796
|
+
const w = mainCanvas.width = innerWidth;
|
|
4797
|
+
const h = mainCanvas.height = innerHeight;
|
|
4798
|
+
{
|
|
4799
|
+
// background
|
|
4800
|
+
const p3 = percent(t, 1, .8);
|
|
4801
|
+
const p4 = percent(t, 0, .5);
|
|
4802
|
+
const g = x.createRadialGradient(w/2,h/2,0,w/2,h/2,Math.hypot(w,h)*.7);
|
|
4803
|
+
g.addColorStop(0,hsl(0,0,lerp(p4,0,p3/2),p3));
|
|
4804
|
+
g.addColorStop(1,hsl(0,0,0,p3));
|
|
4805
|
+
x.save();
|
|
4806
|
+
x.fillStyle = g;
|
|
4807
|
+
x.fillRect(0,0,w,h);
|
|
4808
|
+
}
|
|
4809
|
+
|
|
4810
|
+
// draw LittleJS logo...
|
|
4811
|
+
|
|
4812
|
+
const rect = (X, Y, W, H, C)=>
|
|
4813
|
+
{
|
|
4814
|
+
x.beginPath();
|
|
4815
|
+
x.rect(X,Y,W,C?H*p:H);
|
|
4816
|
+
x.fillStyle = C;
|
|
4817
|
+
C ? x.fill() : x.stroke();
|
|
4818
|
+
};
|
|
4819
|
+
const line = (X, Y, Z, W)=>
|
|
4820
|
+
{
|
|
4821
|
+
x.beginPath();
|
|
4822
|
+
x.lineTo(X,Y);
|
|
4823
|
+
x.lineTo(Z,W);
|
|
4824
|
+
x.stroke();
|
|
4825
|
+
};
|
|
4826
|
+
const circle = (X, Y, R, A=0, B=2*PI, C, F)=>
|
|
4827
|
+
{
|
|
4828
|
+
const D = (A+B)/2, E = p*(B-A)/2;
|
|
4829
|
+
x.beginPath();
|
|
4830
|
+
F && x.lineTo(X,Y);
|
|
4831
|
+
x.arc(X,Y,R,D-E,D+E);
|
|
4832
|
+
x.fillStyle = C;
|
|
4833
|
+
C ? x.fill() : x.stroke();
|
|
4834
|
+
};
|
|
4835
|
+
const color = (c=0, l=0) =>
|
|
4836
|
+
hsl([.98,.3,.57,.14][c%4]-10,.8,[0,.3,.5,.8,.9][l]);
|
|
4837
|
+
const alpha = wave(1,1,t);
|
|
4838
|
+
const p = percent(alpha, .1, .5);
|
|
4839
|
+
|
|
4840
|
+
// setup
|
|
4841
|
+
x.translate(w/2,h/2);
|
|
4842
|
+
const size = min(6, min(w,h)/99); // fit to screen
|
|
4843
|
+
x.scale(size,size);
|
|
4844
|
+
x.translate(-40,-35);
|
|
4845
|
+
x.lineJoin = x.lineCap = 'round';
|
|
4846
|
+
x.lineWidth = 1+p;
|
|
4847
|
+
|
|
4848
|
+
// drawing effect
|
|
4849
|
+
const p2 = percent(alpha,.1,1);
|
|
4850
|
+
x.setLineDash([99*p2,99]);
|
|
4851
|
+
|
|
4852
|
+
// cab top
|
|
4853
|
+
rect(7,17,18,-8,color(2,2));
|
|
4854
|
+
rect(7,9,18,4,color(2,3));
|
|
4855
|
+
rect(25,9,8,8,color(2,1));
|
|
4856
|
+
rect(25,9,-18,8);
|
|
4857
|
+
rect(25,9,8,8);
|
|
4858
|
+
|
|
4859
|
+
// cab
|
|
4860
|
+
rect(25,17,7,22,color());
|
|
4861
|
+
rect(11,40,14,-23,color(1,1));
|
|
4862
|
+
rect(11,17,14,17,color(1,2));
|
|
4863
|
+
rect(11,17,14,9,color(1,3));
|
|
4864
|
+
rect(15,31,6,-9,color(2,2));
|
|
4865
|
+
circle(15,23,5,0,PI/2,color(2,4),1);
|
|
4866
|
+
rect(25,17,-14,23);
|
|
4867
|
+
rect(21,22,-6,9);
|
|
4868
|
+
|
|
4869
|
+
// little stack
|
|
4870
|
+
rect(37,14,9,6,color(3,2));
|
|
4871
|
+
rect(37,14,4,6,color(3,3));
|
|
4872
|
+
rect(37,14,9,6);
|
|
4873
|
+
|
|
4874
|
+
// big stack
|
|
4875
|
+
rect(50,20,10,-10,color(0,1));
|
|
4876
|
+
rect(50,20,6,-10,color(0,2));
|
|
4877
|
+
rect(50,20,3,-10,color(0,3));
|
|
4878
|
+
rect(50,10,10,10);
|
|
4879
|
+
circle(55,2,11.4,.5,PI-.5,color(3,3));
|
|
4880
|
+
circle(55,2,11.4,.5,PI/2,color(3,2),1);
|
|
4881
|
+
circle(55,2,11.4,.5,PI-.5);
|
|
4882
|
+
rect(45,7,20,-7,color(0,2));
|
|
4883
|
+
rect(45,0,20,3,color(0,3));
|
|
4884
|
+
rect(45,0,20,7);
|
|
4885
|
+
|
|
4886
|
+
// engine
|
|
4887
|
+
for (let i=5; i--;)
|
|
4888
|
+
{
|
|
4889
|
+
// stagger radius to fix slight seam
|
|
4890
|
+
circle(60-i*6,30, 9.9,0,2*PI,color(i+2,3));
|
|
4891
|
+
circle(60-i*6,30,10.0,-.5,PI+.5,color(i+2,2));
|
|
4892
|
+
circle(60-i*6,30,10.1,.5,PI-.5,color(i+2,1));
|
|
4893
|
+
}
|
|
4894
|
+
|
|
4895
|
+
// engine outline
|
|
4896
|
+
circle(36,30,10,PI/2,PI*3/2);
|
|
4897
|
+
circle(47,30,10,PI/2,PI*3/2);
|
|
4898
|
+
circle(60,30,10);
|
|
4899
|
+
line(36,20,60,20);
|
|
4900
|
+
|
|
4901
|
+
// engine front light
|
|
4902
|
+
circle(60,30,4,PI,3*PI,color(3,2));
|
|
4903
|
+
circle(60,30,4,PI,2*PI,color(3,3));
|
|
4904
|
+
circle(60,30,4,PI,3*PI);
|
|
4905
|
+
|
|
4906
|
+
// front brush
|
|
4907
|
+
for (let i=6; i--;)
|
|
4908
|
+
{
|
|
4909
|
+
x.beginPath();
|
|
4910
|
+
x.lineTo(53,54);
|
|
4911
|
+
x.lineTo(53,40);
|
|
4912
|
+
x.lineTo(53+(1+i*2.9)*p,40);
|
|
4913
|
+
x.lineTo(53+(4+i*3.5)*p,54);
|
|
4914
|
+
x.fillStyle = color(0,i%2+2);
|
|
4915
|
+
x.fill() || i%2 && x.stroke();
|
|
4916
|
+
}
|
|
4917
|
+
|
|
4918
|
+
// wheels
|
|
4919
|
+
rect(6,40,5,5);
|
|
4920
|
+
rect(6,40,5,5,color());
|
|
4921
|
+
rect(15,54,38,-14,color());
|
|
4922
|
+
for (let i=3; i--;)
|
|
4923
|
+
for (let j=2; j--;)
|
|
4924
|
+
{
|
|
4925
|
+
circle(15*i+15,47,j?7:1,PI,3*PI,color(i,3));
|
|
4926
|
+
x.stroke();
|
|
4927
|
+
circle(15*i+15,47,j?7:1,0,PI,color(i,2));
|
|
4928
|
+
x.stroke();
|
|
4929
|
+
}
|
|
4930
|
+
line(6,40,68,40); // center
|
|
4931
|
+
line(77,54,4,54); // bottom
|
|
4932
|
+
|
|
4933
|
+
// draw engine name
|
|
4934
|
+
const s = engineName;
|
|
4935
|
+
x.font = '900 16px arial';
|
|
4936
|
+
x.textAlign = 'center';
|
|
4937
|
+
x.textBaseline = 'top';
|
|
4938
|
+
x.lineWidth = 1+p*3;
|
|
4939
|
+
let w2 = 0;
|
|
4940
|
+
for (let i=0; i<s.length; ++i)
|
|
4941
|
+
w2 += x.measureText(s[i]).width;
|
|
4942
|
+
for (let j=2; j--;)
|
|
4943
|
+
for (let i=0, X=41-w2/2; i<s.length; ++i)
|
|
4944
|
+
{
|
|
4945
|
+
x.fillStyle = color(i,2);
|
|
4946
|
+
const w = x.measureText(s[i]).width;
|
|
4947
|
+
x[j?'strokeText':'fillText'](s[i],X+w/2,55.5,17*p);
|
|
4948
|
+
X += w;
|
|
4949
|
+
}
|
|
4950
|
+
|
|
4951
|
+
x.restore();
|
|
4748
4952
|
}
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
<link rel=icon type=image/png href=../favicon.png>
|
|
6
6
|
</head><body>
|
|
7
7
|
|
|
8
|
-
<script src=../../build/littlejs.js?
|
|
9
|
-
<script src=gameObjects.js?
|
|
10
|
-
<script src=game.js?
|
|
8
|
+
<script src=../../build/littlejs.js?188></script>
|
|
9
|
+
<script src=gameObjects.js?188></script>
|
|
10
|
+
<script src=game.js?188></script>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</head><body>
|
|
7
7
|
|
|
8
8
|
<!-- LittleJS Engine -->
|
|
9
|
-
<script src=../../build/littlejs.js?
|
|
9
|
+
<script src=../../build/littlejs.js?188></script>
|
|
10
10
|
|
|
11
11
|
<!-- Add your game scripts here -->
|
|
12
|
-
<script src=game.js?
|
|
12
|
+
<script src=game.js?188></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?
|
|
5
|
-
<script src=../../src/engineUtilities.js?
|
|
6
|
-
<script src=../../src/engineSettings.js?
|
|
7
|
-
<script src=../../src/engineObject.js?
|
|
8
|
-
<script src=../../src/engineDraw.js?
|
|
9
|
-
<script src=../../src/engineInput.js?
|
|
10
|
-
<script src=../../src/engineAudio.js?
|
|
11
|
-
<script src=../../src/engineTileLayer.js?
|
|
12
|
-
<script src=../../src/engineParticles.js?
|
|
13
|
-
<script src=../../src/engineMedals.js?
|
|
14
|
-
<script src=../../src/engineWebGL.js?
|
|
15
|
-
<script src=../../src/engine.js?
|
|
4
|
+
<script src=../../src/engineDebug.js?188></script>
|
|
5
|
+
<script src=../../src/engineUtilities.js?188></script>
|
|
6
|
+
<script src=../../src/engineSettings.js?188></script>
|
|
7
|
+
<script src=../../src/engineObject.js?188></script>
|
|
8
|
+
<script src=../../src/engineDraw.js?188></script>
|
|
9
|
+
<script src=../../src/engineInput.js?188></script>
|
|
10
|
+
<script src=../../src/engineAudio.js?188></script>
|
|
11
|
+
<script src=../../src/engineTileLayer.js?188></script>
|
|
12
|
+
<script src=../../src/engineParticles.js?188></script>
|
|
13
|
+
<script src=../../src/engineMedals.js?188></script>
|
|
14
|
+
<script src=../../src/engineWebGL.js?188></script>
|
|
15
|
+
<script src=../../src/engine.js?188></script>
|
|
16
16
|
|
|
17
17
|
<!-- Add your game scripts here -->
|
|
18
|
-
<script src=game.js?
|
|
18
|
+
<script src=game.js?188></script>
|
|
Binary file
|
package/examples/module/game.js
CHANGED
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
import * as LittleJS from '../../build/littlejs.esm.js';
|
|
11
11
|
const {Vector2, Color, Timer, vec2, tile} = LittleJS;
|
|
12
12
|
|
|
13
|
+
// show the LittleJS splash screen
|
|
14
|
+
LittleJS.setShowSplashScreen(1);
|
|
15
|
+
|
|
13
16
|
// sound effects
|
|
14
17
|
const sound_click = new LittleJS.Sound([1,.5]);
|
|
15
18
|
|