littlejsengine 1.9.0 → 1.9.2
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 +7 -7
- package/{build → dist}/littlejs.d.ts +84 -77
- package/{build → dist}/littlejs.esm.js +245 -143
- package/dist/littlejs.esm.min.js +1 -0
- package/{build → dist}/littlejs.js +245 -143
- package/dist/littlejs.min.js +1 -0
- package/{build → dist}/littlejs.release.js +239 -141
- 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 +2 -2
- package/examples/js13k/game.js +10 -9
- package/examples/js13k/index.html +13 -13
- package/examples/js13k/tiles.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/gameTileData.tmx +143 -0
- package/examples/platformer/data/gameTileData.tsx +4 -0
- package/examples/platformer/game.js +0 -1
- package/examples/platformer/gameCharacter.js +1 -1
- package/examples/platformer/gameEffects.js +42 -110
- package/examples/platformer/gameLevel.js +149 -183
- package/examples/platformer/gameObjects.js +61 -16
- package/examples/platformer/gamePlayer.js +3 -2
- package/examples/platformer/gameTileData.js +181 -0
- 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/starter/build.js +2 -2
- 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/src/engine.js +1 -1
- package/src/engineAudio.js +4 -10
- package/src/engineBuild.js +9 -2
- package/src/engineDebug.js +6 -2
- package/src/engineDraw.js +27 -27
- package/src/engineInput.js +7 -7
- package/src/engineMedals.js +2 -2
- package/src/engineObject.js +7 -7
- package/src/engineParticles.js +9 -9
- package/src/engineTileLayer.js +38 -33
- package/src/engineUtilities.js +136 -35
- package/src/engineWebGL.js +8 -10
- package/build/littlejs.esm.min.js +0 -1
- package/build/littlejs.min.js +0 -1
|
@@ -58,9 +58,13 @@ let debugPrimitives = [], debugPhysics = false, debugRaycast = false, debugParti
|
|
|
58
58
|
|
|
59
59
|
/** Asserts if the experssion is false, does not do anything in release builds
|
|
60
60
|
* @param {Boolean} assert
|
|
61
|
-
* @param {Object} output
|
|
61
|
+
* @param {Object} [output]
|
|
62
62
|
* @memberof Debug */
|
|
63
|
-
function ASSERT(assert, output)
|
|
63
|
+
function ASSERT(assert, output)
|
|
64
|
+
{
|
|
65
|
+
if (enableAsserts)
|
|
66
|
+
output ? console.assert(assert, output) : console.assert(assert);
|
|
67
|
+
}
|
|
64
68
|
|
|
65
69
|
/** Draw a debug rectangle in world space
|
|
66
70
|
* @param {Vector2} pos
|
|
@@ -534,13 +538,13 @@ function smoothStep(percent) { return percent * percent * (3 - 2 * percent); }
|
|
|
534
538
|
function nearestPowerOfTwo(value) { return 2**Math.ceil(Math.log2(value)); }
|
|
535
539
|
|
|
536
540
|
/** Returns true if two axis aligned bounding boxes are overlapping
|
|
537
|
-
* @param {Vector2} pointA
|
|
538
|
-
* @param {Vector2} sizeA
|
|
539
|
-
* @param {Vector2} pointB
|
|
540
|
-
* @param {Vector2} sizeB
|
|
541
|
-
* @return {Boolean}
|
|
541
|
+
* @param {Vector2} pointA - Center of box A
|
|
542
|
+
* @param {Vector2} sizeA - Size of box A
|
|
543
|
+
* @param {Vector2} pointB - Center of box B
|
|
544
|
+
* @param {Vector2} [sizeB=(0,0)] - Size of box B, a point if undefined
|
|
545
|
+
* @return {Boolean} - True if overlapping
|
|
542
546
|
* @memberof Utilities */
|
|
543
|
-
function isOverlapping(pointA, sizeA, pointB, sizeB)
|
|
547
|
+
function isOverlapping(pointA, sizeA, pointB, sizeB=vec2())
|
|
544
548
|
{
|
|
545
549
|
return abs(pointA.x - pointB.x)*2 < sizeA.x + sizeB.x
|
|
546
550
|
&& abs(pointA.y - pointB.y)*2 < sizeA.y + sizeB.y;
|
|
@@ -600,8 +604,8 @@ function randInCircle(radius=1, minRadius=0)
|
|
|
600
604
|
{ return radius > 0 ? randVector(radius * rand(minRadius / radius, 1)**.5) : new Vector2; }
|
|
601
605
|
|
|
602
606
|
/** Returns a random color between the two passed in colors, combine components if linear
|
|
603
|
-
* @param {Color} [colorA=
|
|
604
|
-
* @param {Color} [colorB=
|
|
607
|
+
* @param {Color} [colorA=(1,1,1,1)]
|
|
608
|
+
* @param {Color} [colorB=(0,0,0,1)]
|
|
605
609
|
* @param {Boolean} [linear]
|
|
606
610
|
* @return {Color}
|
|
607
611
|
* @memberof Random */
|
|
@@ -672,7 +676,11 @@ class RandomGenerator
|
|
|
672
676
|
* @memberof Utilities
|
|
673
677
|
*/
|
|
674
678
|
function vec2(x=0, y)
|
|
675
|
-
{
|
|
679
|
+
{
|
|
680
|
+
return typeof x === 'number' ?
|
|
681
|
+
new Vector2(x, y == undefined? x : y) :
|
|
682
|
+
new Vector2(x.x, x.y);
|
|
683
|
+
}
|
|
676
684
|
|
|
677
685
|
/**
|
|
678
686
|
* Check if object is a valid Vector2
|
|
@@ -680,7 +688,7 @@ function vec2(x=0, y)
|
|
|
680
688
|
* @return {Boolean}
|
|
681
689
|
* @memberof Utilities
|
|
682
690
|
*/
|
|
683
|
-
function isVector2(v) { return
|
|
691
|
+
function isVector2(v) { return v instanceof Vector2; }
|
|
684
692
|
|
|
685
693
|
/**
|
|
686
694
|
* 2D Vector object with vector math library
|
|
@@ -711,27 +719,47 @@ class Vector2
|
|
|
711
719
|
/** Returns a copy of this vector plus the vector passed in
|
|
712
720
|
* @param {Vector2} v - other vector
|
|
713
721
|
* @return {Vector2} */
|
|
714
|
-
add(v)
|
|
722
|
+
add(v)
|
|
723
|
+
{
|
|
724
|
+
ASSERT(isVector2(v));
|
|
725
|
+
return new Vector2(this.x + v.x, this.y + v.y);
|
|
726
|
+
}
|
|
715
727
|
|
|
716
728
|
/** Returns a copy of this vector minus the vector passed in
|
|
717
729
|
* @param {Vector2} v - other vector
|
|
718
730
|
* @return {Vector2} */
|
|
719
|
-
subtract(v)
|
|
731
|
+
subtract(v)
|
|
732
|
+
{
|
|
733
|
+
ASSERT(isVector2(v));
|
|
734
|
+
return new Vector2(this.x - v.x, this.y - v.y);
|
|
735
|
+
}
|
|
720
736
|
|
|
721
737
|
/** Returns a copy of this vector times the vector passed in
|
|
722
738
|
* @param {Vector2} v - other vector
|
|
723
739
|
* @return {Vector2} */
|
|
724
|
-
multiply(v)
|
|
740
|
+
multiply(v)
|
|
741
|
+
{
|
|
742
|
+
ASSERT(isVector2(v));
|
|
743
|
+
return new Vector2(this.x * v.x, this.y * v.y);
|
|
744
|
+
}
|
|
725
745
|
|
|
726
746
|
/** Returns a copy of this vector divided by the vector passed in
|
|
727
747
|
* @param {Vector2} v - other vector
|
|
728
748
|
* @return {Vector2} */
|
|
729
|
-
divide(v)
|
|
749
|
+
divide(v)
|
|
750
|
+
{
|
|
751
|
+
ASSERT(isVector2(v));
|
|
752
|
+
return new Vector2(this.x / v.x, this.y / v.y);
|
|
753
|
+
}
|
|
730
754
|
|
|
731
755
|
/** Returns a copy of this vector scaled by the vector passed in
|
|
732
756
|
* @param {Number} s - scale
|
|
733
757
|
* @return {Vector2} */
|
|
734
|
-
scale(s)
|
|
758
|
+
scale(s)
|
|
759
|
+
{
|
|
760
|
+
ASSERT(!isVector2(s));
|
|
761
|
+
return new Vector2(this.x * s, this.y * s);
|
|
762
|
+
}
|
|
735
763
|
|
|
736
764
|
/** Returns the length of this vector
|
|
737
765
|
* @return {Number} */
|
|
@@ -744,32 +772,56 @@ class Vector2
|
|
|
744
772
|
/** Returns the distance from this vector to vector passed in
|
|
745
773
|
* @param {Vector2} v - other vector
|
|
746
774
|
* @return {Number} */
|
|
747
|
-
distance(v)
|
|
775
|
+
distance(v)
|
|
776
|
+
{
|
|
777
|
+
ASSERT(isVector2(v));
|
|
778
|
+
return this.distanceSquared(v)**.5;
|
|
779
|
+
}
|
|
748
780
|
|
|
749
781
|
/** Returns the distance squared from this vector to vector passed in
|
|
750
782
|
* @param {Vector2} v - other vector
|
|
751
783
|
* @return {Number} */
|
|
752
|
-
distanceSquared(v)
|
|
784
|
+
distanceSquared(v)
|
|
785
|
+
{
|
|
786
|
+
ASSERT(isVector2(v));
|
|
787
|
+
return (this.x - v.x)**2 + (this.y - v.y)**2;
|
|
788
|
+
}
|
|
753
789
|
|
|
754
790
|
/** Returns a new vector in same direction as this one with the length passed in
|
|
755
791
|
* @param {Number} [length]
|
|
756
792
|
* @return {Vector2} */
|
|
757
|
-
normalize(length=1)
|
|
793
|
+
normalize(length=1)
|
|
794
|
+
{
|
|
795
|
+
const l = this.length();
|
|
796
|
+
return l ? this.scale(length/l) : new Vector2(0, length);
|
|
797
|
+
}
|
|
758
798
|
|
|
759
799
|
/** Returns a new vector clamped to length passed in
|
|
760
800
|
* @param {Number} [length]
|
|
761
801
|
* @return {Vector2} */
|
|
762
|
-
clampLength(length=1)
|
|
802
|
+
clampLength(length=1)
|
|
803
|
+
{
|
|
804
|
+
const l = this.length();
|
|
805
|
+
return l > length ? this.scale(length/l) : this;
|
|
806
|
+
}
|
|
763
807
|
|
|
764
808
|
/** Returns the dot product of this and the vector passed in
|
|
765
809
|
* @param {Vector2} v - other vector
|
|
766
810
|
* @return {Number} */
|
|
767
|
-
dot(v)
|
|
811
|
+
dot(v)
|
|
812
|
+
{
|
|
813
|
+
ASSERT(isVector2(v));
|
|
814
|
+
return this.x*v.x + this.y*v.y;
|
|
815
|
+
}
|
|
768
816
|
|
|
769
817
|
/** Returns the cross product of this and the vector passed in
|
|
770
818
|
* @param {Vector2} v - other vector
|
|
771
819
|
* @return {Number} */
|
|
772
|
-
cross(v)
|
|
820
|
+
cross(v)
|
|
821
|
+
{
|
|
822
|
+
ASSERT(isVector2(v));
|
|
823
|
+
return this.x*v.y - this.y*v.x;
|
|
824
|
+
}
|
|
773
825
|
|
|
774
826
|
/** Returns the angle of this vector, up is angle 0
|
|
775
827
|
* @return {Number} */
|
|
@@ -780,7 +832,11 @@ class Vector2
|
|
|
780
832
|
* @param {Number} [length]
|
|
781
833
|
* @return {Vector2} */
|
|
782
834
|
setAngle(angle=0, length=1)
|
|
783
|
-
{
|
|
835
|
+
{
|
|
836
|
+
this.x = length*Math.sin(angle);
|
|
837
|
+
this.y = length*Math.cos(angle);
|
|
838
|
+
return this;
|
|
839
|
+
}
|
|
784
840
|
|
|
785
841
|
/** Returns copy of this vector rotated by the angle passed in
|
|
786
842
|
* @param {Number} angle
|
|
@@ -791,9 +847,20 @@ class Vector2
|
|
|
791
847
|
return new Vector2(this.x*c - this.y*s, this.x*s + this.y*c);
|
|
792
848
|
}
|
|
793
849
|
|
|
850
|
+
/** Set the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)
|
|
851
|
+
* @param {Number} [direction]
|
|
852
|
+
* @param {Number} [length] */
|
|
853
|
+
setDirection(direction, length=1)
|
|
854
|
+
{
|
|
855
|
+
ASSERT(direction==0 || direction==1 || direction==2 || direction==3);
|
|
856
|
+
return vec2(direction%2 ? direction-1 ? -length : length : 0,
|
|
857
|
+
direction%2 ? 0 : direction ? -length : length);
|
|
858
|
+
}
|
|
859
|
+
|
|
794
860
|
/** Returns the integer direction of this vector, corrosponding to multiples of 90 degree rotation (0-3)
|
|
795
861
|
* @return {Number} */
|
|
796
|
-
direction()
|
|
862
|
+
direction()
|
|
863
|
+
{ return abs(this.x) > abs(this.y) ? this.x < 0 ? 3 : 1 : this.y < 0 ? 2 : 0; }
|
|
797
864
|
|
|
798
865
|
/** Returns a copy of this vector that has been inverted
|
|
799
866
|
* @return {Vector2} */
|
|
@@ -812,24 +879,34 @@ class Vector2
|
|
|
812
879
|
* @param {Number} percent
|
|
813
880
|
* @return {Vector2} */
|
|
814
881
|
lerp(v, percent)
|
|
815
|
-
{
|
|
882
|
+
{
|
|
883
|
+
ASSERT(isVector2(v));
|
|
884
|
+
return this.add(v.subtract(this).scale(clamp(percent)));
|
|
885
|
+
}
|
|
816
886
|
|
|
817
887
|
/** Returns true if this vector is within the bounds of an array size passed in
|
|
818
888
|
* @param {Vector2} arraySize
|
|
819
889
|
* @return {Boolean} */
|
|
820
|
-
arrayCheck(arraySize)
|
|
890
|
+
arrayCheck(arraySize)
|
|
891
|
+
{
|
|
892
|
+
ASSERT(isVector2(arraySize));
|
|
893
|
+
return this.x >= 0 && this.y >= 0 && this.x < arraySize.x && this.y < arraySize.y;
|
|
894
|
+
}
|
|
821
895
|
|
|
822
896
|
/** Returns this vector expressed as a string
|
|
823
897
|
* @param {Number} digits - precision to display
|
|
824
898
|
* @return {String} */
|
|
825
899
|
toString(digits=3)
|
|
826
|
-
{
|
|
900
|
+
{
|
|
901
|
+
if (debug)
|
|
902
|
+
return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`;
|
|
903
|
+
}
|
|
827
904
|
}
|
|
828
905
|
|
|
829
906
|
///////////////////////////////////////////////////////////////////////////////
|
|
830
907
|
|
|
831
908
|
/**
|
|
832
|
-
* Create a color object with RGBA values
|
|
909
|
+
* Create a color object with RGBA values, white by default
|
|
833
910
|
* @param {Number} [r=1] - red
|
|
834
911
|
* @param {Number} [g=1] - green
|
|
835
912
|
* @param {Number} [b=1] - blue
|
|
@@ -840,7 +917,7 @@ class Vector2
|
|
|
840
917
|
function rgb(r, g, b, a) { return new Color(r, g, b, a); }
|
|
841
918
|
|
|
842
919
|
/**
|
|
843
|
-
* Create a color object with HSLA values
|
|
920
|
+
* Create a color object with HSLA values, white by default
|
|
844
921
|
* @param {Number} [h=0] - hue
|
|
845
922
|
* @param {Number} [s=0] - saturation
|
|
846
923
|
* @param {Number} [l=1] - lightness
|
|
@@ -850,14 +927,22 @@ function rgb(r, g, b, a) { return new Color(r, g, b, a); }
|
|
|
850
927
|
*/
|
|
851
928
|
function hsl(h, s, l, a) { return new Color().setHSLA(h, s, l, a); }
|
|
852
929
|
|
|
930
|
+
/**
|
|
931
|
+
* Check if object is a valid Color
|
|
932
|
+
* @param {any} c
|
|
933
|
+
* @return {Boolean}
|
|
934
|
+
* @memberof Utilities
|
|
935
|
+
*/
|
|
936
|
+
function isColor(c) { return c instanceof Color; }
|
|
937
|
+
|
|
853
938
|
/**
|
|
854
939
|
* Color object (red, green, blue, alpha) with some helpful functions
|
|
855
940
|
* @example
|
|
856
941
|
* let a = new Color; // white
|
|
857
942
|
* let b = new Color(1, 0, 0); // red
|
|
858
943
|
* let c = new Color(0, 0, 0, 0); // transparent black
|
|
859
|
-
* let d =
|
|
860
|
-
* let e =
|
|
944
|
+
* let d = rgb(0, 0, 1); // blue using rgb color
|
|
945
|
+
* let e = hsl(.3, 1, .5); // green using hsl color
|
|
861
946
|
*/
|
|
862
947
|
class Color
|
|
863
948
|
{
|
|
@@ -885,22 +970,38 @@ class Color
|
|
|
885
970
|
/** Returns a copy of this color plus the color passed in
|
|
886
971
|
* @param {Color} c - other color
|
|
887
972
|
* @return {Color} */
|
|
888
|
-
add(c)
|
|
973
|
+
add(c)
|
|
974
|
+
{
|
|
975
|
+
ASSERT(isColor(c));
|
|
976
|
+
return new Color(this.r+c.r, this.g+c.g, this.b+c.b, this.a+c.a);
|
|
977
|
+
}
|
|
889
978
|
|
|
890
979
|
/** Returns a copy of this color minus the color passed in
|
|
891
980
|
* @param {Color} c - other color
|
|
892
981
|
* @return {Color} */
|
|
893
|
-
subtract(c)
|
|
982
|
+
subtract(c)
|
|
983
|
+
{
|
|
984
|
+
ASSERT(isColor(c));
|
|
985
|
+
return new Color(this.r-c.r, this.g-c.g, this.b-c.b, this.a-c.a);
|
|
986
|
+
}
|
|
894
987
|
|
|
895
988
|
/** Returns a copy of this color times the color passed in
|
|
896
989
|
* @param {Color} c - other color
|
|
897
990
|
* @return {Color} */
|
|
898
|
-
multiply(c)
|
|
991
|
+
multiply(c)
|
|
992
|
+
{
|
|
993
|
+
ASSERT(isColor(c));
|
|
994
|
+
return new Color(this.r*c.r, this.g*c.g, this.b*c.b, this.a*c.a);
|
|
995
|
+
}
|
|
899
996
|
|
|
900
997
|
/** Returns a copy of this color divided by the color passed in
|
|
901
998
|
* @param {Color} c - other color
|
|
902
999
|
* @return {Color} */
|
|
903
|
-
divide(c)
|
|
1000
|
+
divide(c)
|
|
1001
|
+
{
|
|
1002
|
+
ASSERT(isColor(c));
|
|
1003
|
+
return new Color(this.r/c.r, this.g/c.g, this.b/c.b, this.a/c.a);
|
|
1004
|
+
}
|
|
904
1005
|
|
|
905
1006
|
/** Returns a copy of this color scaled by the value passed in, alpha can be scaled separately
|
|
906
1007
|
* @param {Number} scale
|
|
@@ -917,7 +1018,11 @@ class Color
|
|
|
917
1018
|
* @param {Color} c - other color
|
|
918
1019
|
* @param {Number} percent
|
|
919
1020
|
* @return {Color} */
|
|
920
|
-
lerp(c, percent)
|
|
1021
|
+
lerp(c, percent)
|
|
1022
|
+
{
|
|
1023
|
+
ASSERT(isColor(c));
|
|
1024
|
+
return this.add(c.subtract(this).scale(clamp(percent)));
|
|
1025
|
+
}
|
|
921
1026
|
|
|
922
1027
|
/** Sets this color given a hue, saturation, lightness, and alpha
|
|
923
1028
|
* @param {Number} [h] - hue
|
|
@@ -1557,12 +1662,12 @@ function setDebugKey(key) { debugKey = key; }
|
|
|
1557
1662
|
class EngineObject
|
|
1558
1663
|
{
|
|
1559
1664
|
/** Create an engine object and adds it to the list of objects
|
|
1560
|
-
* @param {Vector2} [pos=
|
|
1561
|
-
* @param {Vector2} [size=
|
|
1562
|
-
* @param {TileInfo} [tileInfo]
|
|
1563
|
-
* @param {Number} [angle]
|
|
1564
|
-
* @param {Color} [color=
|
|
1565
|
-
* @param {Number} [renderOrder]
|
|
1665
|
+
* @param {Vector2} [pos=(0,0)] - World space position of the object
|
|
1666
|
+
* @param {Vector2} [size=(1,1)] - World space size of the object
|
|
1667
|
+
* @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
|
|
1668
|
+
* @param {Number} [angle] - Angle the object is rotated by
|
|
1669
|
+
* @param {Color} [color=(1,1,1,1)] - Color to apply to tile when rendered
|
|
1670
|
+
* @param {Number} [renderOrder] - Objects sorted by renderOrder before being rendered
|
|
1566
1671
|
*/
|
|
1567
1672
|
constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color, renderOrder=0)
|
|
1568
1673
|
{
|
|
@@ -1862,7 +1967,7 @@ class EngineObject
|
|
|
1862
1967
|
|
|
1863
1968
|
/** Attaches a child to this with a given local transform
|
|
1864
1969
|
* @param {EngineObject} child
|
|
1865
|
-
* @param {Vector2} [localPos=
|
|
1970
|
+
* @param {Vector2} [localPos=(0,0)]
|
|
1866
1971
|
* @param {Number} [localAngle] */
|
|
1867
1972
|
addChild(child, localPos=vec2(), localAngle=0)
|
|
1868
1973
|
{
|
|
@@ -1979,7 +2084,7 @@ let drawCount;
|
|
|
1979
2084
|
* Create a tile info object
|
|
1980
2085
|
* - This can take vecs or floats for easier use and conversion
|
|
1981
2086
|
* - If an index is passed in, the tile size and index will determine the position
|
|
1982
|
-
* @param {(Number|Vector2)} [pos=
|
|
2087
|
+
* @param {(Number|Vector2)} [pos=(0,0)] - Top left corner of tile in pixels or index
|
|
1983
2088
|
* @param {(Number|Vector2)} [size=tileSizeDefault] - Size of tile in pixels
|
|
1984
2089
|
* @param {Number} [textureIndex] - Texture index to use
|
|
1985
2090
|
* @return {TileInfo}
|
|
@@ -2022,7 +2127,7 @@ function tile(pos=vec2(), size=tileSizeDefault, textureIndex=0)
|
|
|
2022
2127
|
class TileInfo
|
|
2023
2128
|
{
|
|
2024
2129
|
/** Create a tile info object
|
|
2025
|
-
* @param {Vector2} [pos=
|
|
2130
|
+
* @param {Vector2} [pos=(0,0)] - Top left corner of tile in pixels
|
|
2026
2131
|
* @param {Vector2} [size=tileSizeDefault] - Size of tile in pixels
|
|
2027
2132
|
* @param {Number} [textureIndex] - Texture index to use
|
|
2028
2133
|
*/
|
|
@@ -2099,16 +2204,16 @@ function worldToScreen(worldPos)
|
|
|
2099
2204
|
}
|
|
2100
2205
|
|
|
2101
2206
|
/** Draw textured tile centered in world space, with color applied if using WebGL
|
|
2102
|
-
* @param {Vector2} pos
|
|
2103
|
-
* @param {Vector2} [size=
|
|
2104
|
-
* @param {TileInfo}[tileInfo]
|
|
2105
|
-
* @param {Color} [color=
|
|
2106
|
-
* @param {Number} [angle]
|
|
2107
|
-
* @param {Boolean} [mirror]
|
|
2108
|
-
* @param {Color} [additiveColor=
|
|
2109
|
-
* @param {Boolean} [useWebGL=glEnable]
|
|
2110
|
-
* @param {Boolean} [screenSpace]
|
|
2111
|
-
* @param {CanvasRenderingContext2D} [context]
|
|
2207
|
+
* @param {Vector2} pos - Center of the tile in world space
|
|
2208
|
+
* @param {Vector2} [size=(1,1)] - Size of the tile in world space
|
|
2209
|
+
* @param {TileInfo}[tileInfo] - Tile info to use, untextured if undefined
|
|
2210
|
+
* @param {Color} [color=(1,1,1,1)] - Color to modulate with
|
|
2211
|
+
* @param {Number} [angle] - Angle to rotate by
|
|
2212
|
+
* @param {Boolean} [mirror] - If true image is flipped along the Y axis
|
|
2213
|
+
* @param {Color} [additiveColor=(0,0,0,0)] - Additive color to be applied
|
|
2214
|
+
* @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
|
|
2215
|
+
* @param {Boolean} [screenSpace=false] - If true the pos and size are in screen space
|
|
2216
|
+
* @param {CanvasRenderingContext2D} [context] - Canvas 2D context to draw to
|
|
2112
2217
|
* @memberof Draw */
|
|
2113
2218
|
function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
|
|
2114
2219
|
angle=0, mirror, additiveColor=new Color(0,0,0,0), useWebGL=glEnable, screenSpace, context)
|
|
@@ -2176,11 +2281,11 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
|
|
|
2176
2281
|
|
|
2177
2282
|
/** Draw colored rect centered on pos
|
|
2178
2283
|
* @param {Vector2} pos
|
|
2179
|
-
* @param {Vector2} [size=
|
|
2180
|
-
* @param {Color} [color=
|
|
2284
|
+
* @param {Vector2} [size=(1,1)]
|
|
2285
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
2181
2286
|
* @param {Number} [angle]
|
|
2182
2287
|
* @param {Boolean} [useWebGL=glEnable]
|
|
2183
|
-
* @param {Boolean} [screenSpace]
|
|
2288
|
+
* @param {Boolean} [screenSpace=false]
|
|
2184
2289
|
* @param {CanvasRenderingContext2D} [context]
|
|
2185
2290
|
* @memberof Draw */
|
|
2186
2291
|
function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
@@ -2190,8 +2295,8 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
|
2190
2295
|
|
|
2191
2296
|
/** Draw colored polygon using passed in points
|
|
2192
2297
|
* @param {Array} points - Array of Vector2 points
|
|
2193
|
-
* @param {Color} [color=
|
|
2194
|
-
* @param {Boolean} [screenSpace]
|
|
2298
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
2299
|
+
* @param {Boolean} [screenSpace=false]
|
|
2195
2300
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
2196
2301
|
* @memberof Draw */
|
|
2197
2302
|
function drawPoly(points, color=new Color, screenSpace, context=mainContext)
|
|
@@ -2207,9 +2312,9 @@ function drawPoly(points, color=new Color, screenSpace, context=mainContext)
|
|
|
2207
2312
|
* @param {Vector2} posA
|
|
2208
2313
|
* @param {Vector2} posB
|
|
2209
2314
|
* @param {Number} [thickness]
|
|
2210
|
-
* @param {Color} [color=
|
|
2315
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
2211
2316
|
* @param {Boolean} [useWebGL=glEnable]
|
|
2212
|
-
* @param {Boolean} [screenSpace]
|
|
2317
|
+
* @param {Boolean} [screenSpace=false]
|
|
2213
2318
|
* @param {CanvasRenderingContext2D} [context]
|
|
2214
2319
|
* @memberof Draw */
|
|
2215
2320
|
function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
|
|
@@ -2225,7 +2330,7 @@ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, contex
|
|
|
2225
2330
|
* @param {Number} angle
|
|
2226
2331
|
* @param {Boolean} mirror
|
|
2227
2332
|
* @param {Function} drawFunction
|
|
2228
|
-
* @param {Boolean} [screenSpace]
|
|
2333
|
+
* @param {Boolean} [screenSpace=false]
|
|
2229
2334
|
* @param {CanvasRenderingContext2D} [context=mainContext]
|
|
2230
2335
|
* @memberof Draw */
|
|
2231
2336
|
function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, context=mainContext)
|
|
@@ -2267,9 +2372,9 @@ function setBlendMode(additive, useWebGL=glEnable, context)
|
|
|
2267
2372
|
* @param {String} text
|
|
2268
2373
|
* @param {Vector2} pos
|
|
2269
2374
|
* @param {Number} [size]
|
|
2270
|
-
* @param {Color} [color=
|
|
2375
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
2271
2376
|
* @param {Number} [lineWidth]
|
|
2272
|
-
* @param {Color} [lineColor=
|
|
2377
|
+
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2273
2378
|
* @param {CanvasTextAlign} [textAlign='center']
|
|
2274
2379
|
* @param {String} [font=fontDefault]
|
|
2275
2380
|
* @param {CanvasRenderingContext2D} [context=overlayContext]
|
|
@@ -2284,9 +2389,9 @@ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, f
|
|
|
2284
2389
|
* @param {String} text
|
|
2285
2390
|
* @param {Vector2} pos
|
|
2286
2391
|
* @param {Number} [size]
|
|
2287
|
-
* @param {Color} [color=
|
|
2392
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
2288
2393
|
* @param {Number} [lineWidth]
|
|
2289
|
-
* @param {Color} [lineColor=
|
|
2394
|
+
* @param {Color} [lineColor=(0,0,0,1)]
|
|
2290
2395
|
* @param {CanvasTextAlign} [textAlign]
|
|
2291
2396
|
* @param {String} [font=fontDefault]
|
|
2292
2397
|
* @param {CanvasRenderingContext2D} [context=overlayContext]
|
|
@@ -2329,9 +2434,9 @@ let engineFontImage;
|
|
|
2329
2434
|
class FontImage
|
|
2330
2435
|
{
|
|
2331
2436
|
/** Create an image font
|
|
2332
|
-
* @param {HTMLImageElement} [image]
|
|
2333
|
-
* @param {Vector2} [tileSize=
|
|
2334
|
-
* @param {Vector2} [paddingSize=
|
|
2437
|
+
* @param {HTMLImageElement} [image] - Image for the font, if undefined default font is used
|
|
2438
|
+
* @param {Vector2} [tileSize=(8,8)] - Size of the font source tiles
|
|
2439
|
+
* @param {Vector2} [paddingSize=(0,1)] - How much extra space to add between characters
|
|
2335
2440
|
* @param {CanvasRenderingContext2D} [context=overlayContext] - context to draw to
|
|
2336
2441
|
*/
|
|
2337
2442
|
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), context=overlayContext)
|
|
@@ -2609,10 +2714,10 @@ function inputUpdatePost()
|
|
|
2609
2714
|
///////////////////////////////////////////////////////////////////////////////
|
|
2610
2715
|
// Mouse event handlers
|
|
2611
2716
|
|
|
2612
|
-
onmousedown = (e)=> {isUsingGamepad = false; inputData[0][e.button] = 3;
|
|
2717
|
+
onmousedown = (e)=> {isUsingGamepad = false; inputData[0][e.button] = 3; mousePosScreen = mouseToScreen(e); e.button && e.preventDefault();}
|
|
2613
2718
|
onmouseup = (e)=> inputData[0][e.button] = inputData[0][e.button] & 2 | 4;
|
|
2614
2719
|
onmousemove = (e)=> mousePosScreen = mouseToScreen(e);
|
|
2615
|
-
onwheel = (e)=> e.ctrlKey
|
|
2720
|
+
onwheel = (e)=> mouseWheel = e.ctrlKey ? 0 : sign(e.deltaY);
|
|
2616
2721
|
oncontextmenu = (e)=> false; // prevent right click menu
|
|
2617
2722
|
|
|
2618
2723
|
// convert a mouse or touch event position to screen space
|
|
@@ -2706,7 +2811,7 @@ function gamepadsUpdate()
|
|
|
2706
2811
|
///////////////////////////////////////////////////////////////////////////////
|
|
2707
2812
|
|
|
2708
2813
|
/** Pulse the vibration hardware if it exists
|
|
2709
|
-
* @param {Number} [pattern] -
|
|
2814
|
+
* @param {Number|Array} [pattern] - single value in ms or vibration interval array
|
|
2710
2815
|
* @memberof Input */
|
|
2711
2816
|
function vibrate(pattern=100)
|
|
2712
2817
|
{ vibrateEnable && navigator && navigator.vibrate && navigator.vibrate(pattern); }
|
|
@@ -2732,9 +2837,9 @@ if (isTouchDevice)
|
|
|
2732
2837
|
// handle all touch events the same way
|
|
2733
2838
|
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
2734
2839
|
{
|
|
2735
|
-
// fix stalled audio
|
|
2736
|
-
if (soundEnable)
|
|
2737
|
-
|
|
2840
|
+
// fix stalled audio requiring user interaction
|
|
2841
|
+
if (soundEnable && audioContext && audioContext.state != 'running')
|
|
2842
|
+
zzfx(0);
|
|
2738
2843
|
|
|
2739
2844
|
// check if touching and pass to mouse events
|
|
2740
2845
|
const touching = e.touches.length;
|
|
@@ -2880,7 +2985,7 @@ function touchGamepadRender()
|
|
|
2880
2985
|
const rightCenter = vec2(mainCanvasSize.x-touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
2881
2986
|
for (let i=4; i--;)
|
|
2882
2987
|
{
|
|
2883
|
-
const pos = rightCenter.add(vec2().
|
|
2988
|
+
const pos = rightCenter.add(vec2().setDirection(i, touchGamepadSize/2));
|
|
2884
2989
|
overlayContext.fillStyle = touchGamepadButtons[i] ? '#fff' : '#000';
|
|
2885
2990
|
overlayContext.beginPath();
|
|
2886
2991
|
overlayContext.arc(pos.x, pos.y, touchGamepadSize/4, 0,9);
|
|
@@ -3039,22 +3144,19 @@ class SoundWave extends Sound
|
|
|
3039
3144
|
this.randomness = randomness;
|
|
3040
3145
|
|
|
3041
3146
|
if (!soundEnable) return;
|
|
3042
|
-
if (!soundDecoderContext)
|
|
3043
|
-
soundDecoderContext = new AudioContext;
|
|
3044
3147
|
|
|
3045
3148
|
fetch(filename)
|
|
3046
3149
|
.then(response => response.arrayBuffer())
|
|
3047
|
-
.then(arrayBuffer =>
|
|
3150
|
+
.then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
|
|
3048
3151
|
.then(audioBuffer =>
|
|
3049
3152
|
{
|
|
3050
3153
|
this.sampleChannels = [];
|
|
3051
3154
|
for (let i = audioBuffer.numberOfChannels; i--;)
|
|
3052
|
-
this.sampleChannels[i] = audioBuffer.getChannelData(i);
|
|
3155
|
+
this.sampleChannels[i] = Array.from(audioBuffer.getChannelData(i));
|
|
3053
3156
|
this.sampleRate = audioBuffer.sampleRate;
|
|
3054
3157
|
});
|
|
3055
3158
|
}
|
|
3056
3159
|
}
|
|
3057
|
-
let soundDecoderContext; // audio context used only to decode audio files
|
|
3058
3160
|
|
|
3059
3161
|
/**
|
|
3060
3162
|
* Music Object - Stores a zzfx music track for later use
|
|
@@ -3168,8 +3270,9 @@ function getNoteFrequency(semitoneOffset, rootFrequency=220)
|
|
|
3168
3270
|
///////////////////////////////////////////////////////////////////////////////
|
|
3169
3271
|
|
|
3170
3272
|
/** Audio context used by the engine
|
|
3273
|
+
* @type {AudioContext}
|
|
3171
3274
|
* @memberof Audio */
|
|
3172
|
-
let audioContext;
|
|
3275
|
+
let audioContext = new AudioContext;
|
|
3173
3276
|
|
|
3174
3277
|
/** Play cached audio samples with given settings
|
|
3175
3278
|
* @param {Array} sampleChannels - Array of arrays of samples to play (for stereo playback)
|
|
@@ -3184,10 +3287,6 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=false, sample
|
|
|
3184
3287
|
{
|
|
3185
3288
|
if (!soundEnable) return;
|
|
3186
3289
|
|
|
3187
|
-
// create audio context if needed
|
|
3188
|
-
if (!audioContext)
|
|
3189
|
-
audioContext = new AudioContext;
|
|
3190
|
-
|
|
3191
3290
|
// prevent sounds from building up if they can't be played
|
|
3192
3291
|
if (audioContext.state != 'running')
|
|
3193
3292
|
{
|
|
@@ -3513,7 +3612,7 @@ function getTileCollisionData(pos)
|
|
|
3513
3612
|
|
|
3514
3613
|
/** Check if collision with another object should occur
|
|
3515
3614
|
* @param {Vector2} pos
|
|
3516
|
-
* @param {Vector2} [size=
|
|
3615
|
+
* @param {Vector2} [size=(1,1)]
|
|
3517
3616
|
* @param {EngineObject} [object]
|
|
3518
3617
|
* @return {Boolean}
|
|
3519
3618
|
* @memberof TileCollision */
|
|
@@ -3598,7 +3697,7 @@ class TileLayerData
|
|
|
3598
3697
|
* @param {Number} [direction] - Integer direction of tile, in 90 degree increments
|
|
3599
3698
|
* @param {Boolean} [mirror] - If the tile should be mirrored along the x axis
|
|
3600
3699
|
* @param {Color} [color] - Color of the tile */
|
|
3601
|
-
constructor(tile, direction=0, mirror=false, color=new Color
|
|
3700
|
+
constructor(tile, direction=0, mirror=false, color=new Color)
|
|
3602
3701
|
{
|
|
3603
3702
|
/** @property {Number} - The tile to use, untextured if undefined */
|
|
3604
3703
|
this.tile = tile;
|
|
@@ -3629,11 +3728,11 @@ class TileLayerData
|
|
|
3629
3728
|
class TileLayer extends EngineObject
|
|
3630
3729
|
{
|
|
3631
3730
|
/** Create a tile layer object
|
|
3632
|
-
* @param {Vector2} [position=
|
|
3731
|
+
* @param {Vector2} [position=(0,0)] - World space position
|
|
3633
3732
|
* @param {Vector2} [size=tileCollisionSize] - World space size
|
|
3634
|
-
* @param {TileInfo} [tileInfo]
|
|
3635
|
-
* @param {Vector2} [scale=
|
|
3636
|
-
* @param {Number} [renderOrder]
|
|
3733
|
+
* @param {TileInfo} [tileInfo] - Tile info for layer
|
|
3734
|
+
* @param {Vector2} [scale=(1,1)] - How much to scale this layer when rendered
|
|
3735
|
+
* @param {Number} [renderOrder] - Objects are sorted by renderOrder
|
|
3637
3736
|
*/
|
|
3638
3737
|
constructor(position, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderOrder=0)
|
|
3639
3738
|
{
|
|
@@ -3694,16 +3793,18 @@ class TileLayer extends EngineObject
|
|
|
3694
3793
|
}
|
|
3695
3794
|
|
|
3696
3795
|
/** Draw all the tile data to an offscreen canvas
|
|
3697
|
-
* - This may be slow in some browsers
|
|
3698
|
-
*/
|
|
3796
|
+
* - This may be slow in some browsers but only needs to be done once */
|
|
3699
3797
|
redraw()
|
|
3700
3798
|
{
|
|
3701
3799
|
this.redrawStart(true);
|
|
3702
|
-
this.
|
|
3800
|
+
for (let x = this.size.x; x--;)
|
|
3801
|
+
for (let y = this.size.y; y--;)
|
|
3802
|
+
this.drawTileData(vec2(x,y), false);
|
|
3703
3803
|
this.redrawEnd();
|
|
3704
3804
|
}
|
|
3705
3805
|
|
|
3706
3806
|
/** Call to start the redraw process
|
|
3807
|
+
* - This can be used to manually update small parts of the level
|
|
3707
3808
|
* @param {Boolean} [clear] - Should it clear the canvas before drawing */
|
|
3708
3809
|
redrawStart(clear=false)
|
|
3709
3810
|
{
|
|
@@ -3711,17 +3812,19 @@ class TileLayer extends EngineObject
|
|
|
3711
3812
|
/** @type {[HTMLCanvasElement, CanvasRenderingContext2D, Vector2, Vector2, number]} */
|
|
3712
3813
|
this.savedRenderSettings = [mainCanvas, mainContext, mainCanvasSize, cameraPos, cameraScale];
|
|
3713
3814
|
|
|
3714
|
-
//
|
|
3815
|
+
// use webgl rendering system to render the tiles if enabled
|
|
3816
|
+
// this works by temporally taking control of the rendering system
|
|
3715
3817
|
mainCanvas = this.canvas;
|
|
3716
3818
|
mainContext = this.context;
|
|
3819
|
+
mainCanvasSize = this.size.multiply(this.tileInfo.size);
|
|
3717
3820
|
cameraPos = this.size.scale(.5);
|
|
3718
3821
|
cameraScale = this.tileInfo.size.x;
|
|
3719
3822
|
|
|
3720
3823
|
if (clear)
|
|
3721
3824
|
{
|
|
3722
3825
|
// clear and set size
|
|
3723
|
-
mainCanvas.width =
|
|
3724
|
-
mainCanvas.height =
|
|
3826
|
+
mainCanvas.width = mainCanvasSize.x;
|
|
3827
|
+
mainCanvas.height = mainCanvasSize.y;
|
|
3725
3828
|
}
|
|
3726
3829
|
|
|
3727
3830
|
// begin a new render for the tile canvas
|
|
@@ -3739,32 +3842,33 @@ class TileLayer extends EngineObject
|
|
|
3739
3842
|
[mainCanvas, mainContext, mainCanvasSize, cameraPos, cameraScale] = this.savedRenderSettings;
|
|
3740
3843
|
}
|
|
3741
3844
|
|
|
3742
|
-
/** Draw the tile at a given position
|
|
3743
|
-
*
|
|
3744
|
-
|
|
3845
|
+
/** Draw the tile at a given position in the tile grid
|
|
3846
|
+
* This can be used to clear out tiles when they are destroyed
|
|
3847
|
+
* Tiles can also be redrawn if isinde a redrawStart/End block
|
|
3848
|
+
* @param {Vector2} layerPos
|
|
3849
|
+
* @param {Boolean} [clear] - should the old tile be cleared out
|
|
3850
|
+
*/
|
|
3851
|
+
drawTileData(layerPos, clear=true)
|
|
3745
3852
|
{
|
|
3746
|
-
//
|
|
3747
|
-
const
|
|
3748
|
-
|
|
3853
|
+
// clear out where the tile was, for full opaque tiles this can be skipped
|
|
3854
|
+
const s = this.tileInfo.size;
|
|
3855
|
+
if (clear)
|
|
3856
|
+
{
|
|
3857
|
+
const pos = layerPos.multiply(s);
|
|
3858
|
+
this.context.clearRect(pos.x, this.canvas.height-pos.y, s.x, -s.y);
|
|
3859
|
+
}
|
|
3749
3860
|
|
|
3750
3861
|
// draw the tile if not undefined
|
|
3751
3862
|
const d = this.getData(layerPos);
|
|
3752
3863
|
if (d.tile != undefined)
|
|
3753
3864
|
{
|
|
3865
|
+
const pos = this.pos.add(layerPos).add(vec2(.5));
|
|
3754
3866
|
ASSERT(mainContext == this.context, 'must call redrawStart() before drawing tiles');
|
|
3755
|
-
const tileInfo = tile(d.tile,
|
|
3867
|
+
const tileInfo = tile(d.tile, s, this.tileInfo.textureIndex);
|
|
3756
3868
|
drawTile(pos, vec2(1), tileInfo, d.color, d.direction*PI/2, d.mirror);
|
|
3757
3869
|
}
|
|
3758
3870
|
}
|
|
3759
3871
|
|
|
3760
|
-
/** Draw all the tiles in this layer */
|
|
3761
|
-
drawAllTileData()
|
|
3762
|
-
{
|
|
3763
|
-
for (let x = this.size.x; x--;)
|
|
3764
|
-
for (let y = this.size.y; y--;)
|
|
3765
|
-
this.drawTileData(vec2(x,y));
|
|
3766
|
-
}
|
|
3767
|
-
|
|
3768
3872
|
/** Draw directly to the 2D canvas in world space (bipass webgl)
|
|
3769
3873
|
* @param {Vector2} pos
|
|
3770
3874
|
* @param {Vector2} size
|
|
@@ -3784,11 +3888,11 @@ class TileLayer extends EngineObject
|
|
|
3784
3888
|
context.restore();
|
|
3785
3889
|
}
|
|
3786
3890
|
|
|
3787
|
-
/** Draw a tile directly onto the layer canvas
|
|
3891
|
+
/** Draw a tile directly onto the layer canvas in world space
|
|
3788
3892
|
* @param {Vector2} pos
|
|
3789
|
-
* @param {Vector2} [size=
|
|
3893
|
+
* @param {Vector2} [size=(1,1)]
|
|
3790
3894
|
* @param {TileInfo} [tileInfo]
|
|
3791
|
-
* @param {Color} [color=
|
|
3895
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
3792
3896
|
* @param {Number} [angle=0]
|
|
3793
3897
|
* @param {Boolean} [mirror=0] */
|
|
3794
3898
|
drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle, mirror)
|
|
@@ -3813,10 +3917,10 @@ class TileLayer extends EngineObject
|
|
|
3813
3917
|
});
|
|
3814
3918
|
}
|
|
3815
3919
|
|
|
3816
|
-
/** Draw a rectangle directly onto the layer canvas
|
|
3920
|
+
/** Draw a rectangle directly onto the layer canvas in world space
|
|
3817
3921
|
* @param {Vector2} pos
|
|
3818
|
-
* @param {Vector2} [size=
|
|
3819
|
-
* @param {Color} [color=
|
|
3922
|
+
* @param {Vector2} [size=(1,1)]
|
|
3923
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
3820
3924
|
* @param {Number} [angle=0] */
|
|
3821
3925
|
drawRect(pos, size, color, angle)
|
|
3822
3926
|
{ this.drawTile(pos, size, undefined, color, angle); }
|
|
@@ -3833,12 +3937,12 @@ class TileLayer extends EngineObject
|
|
|
3833
3937
|
* @example
|
|
3834
3938
|
* // create a particle emitter
|
|
3835
3939
|
* let pos = vec2(2,3);
|
|
3836
|
-
* let
|
|
3940
|
+
* let particleEmitter = new ParticleEmitter
|
|
3837
3941
|
* (
|
|
3838
|
-
* pos, 0, 1, 0, 500, PI,
|
|
3839
|
-
* tile(0, 16),
|
|
3840
|
-
*
|
|
3841
|
-
*
|
|
3942
|
+
* pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
|
|
3943
|
+
* tile(0, 16), // tileInfo
|
|
3944
|
+
* rgb(1,1,1), rgb(0,0,0), // colorStartA, colorStartB
|
|
3945
|
+
* rgb(1,1,1,0), rgb(0,0,0,0), // colorEndA, colorEndB
|
|
3842
3946
|
* 2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
|
|
3843
3947
|
* .99, 1, 1, PI, .05, // damping, angleDamping, gravityScale, particleCone, fadeRate,
|
|
3844
3948
|
* .5, 1 // randomness, collide, additive, randomColorLinear, renderOrder
|
|
@@ -3854,10 +3958,10 @@ class ParticleEmitter extends EngineObject
|
|
|
3854
3958
|
* @param {Number} [emitRate] - How many particles per second to spawn, does not emit if 0
|
|
3855
3959
|
* @param {Number} [emitConeAngle=PI] - Local angle to apply velocity to particles from emitter
|
|
3856
3960
|
* @param {TileInfo} [tileInfo] - Tile info to render particles (undefined is untextured)
|
|
3857
|
-
* @param {Color} [colorStartA=
|
|
3858
|
-
* @param {Color} [colorStartB=
|
|
3859
|
-
* @param {Color} [colorEndA=
|
|
3860
|
-
* @param {Color} [colorEndB=
|
|
3961
|
+
* @param {Color} [colorStartA=(1,1,1,1)] - Color at start of life 1, randomized between start colors
|
|
3962
|
+
* @param {Color} [colorStartB=(1,1,1,1)] - Color at start of life 2, randomized between start colors
|
|
3963
|
+
* @param {Color} [colorEndA=(1,1,1,0)] - Color at end of life 1, randomized between end colors
|
|
3964
|
+
* @param {Color} [colorEndB=(1,1,1,0)] - Color at end of life 2, randomized between end colors
|
|
3861
3965
|
* @param {Number} [particleTime] - How long particles live
|
|
3862
3966
|
* @param {Number} [sizeStart] - How big are particles at start
|
|
3863
3967
|
* @param {Number} [sizeEnd] - How big are particles at end
|
|
@@ -4245,8 +4349,8 @@ class Medal
|
|
|
4245
4349
|
// draw containing rect and clip to that region
|
|
4246
4350
|
context.save();
|
|
4247
4351
|
context.beginPath();
|
|
4248
|
-
context.fillStyle =
|
|
4249
|
-
context.strokeStyle =
|
|
4352
|
+
context.fillStyle = new Color(.9,.9,.9).toString();
|
|
4353
|
+
context.strokeStyle = new Color(0,0,0).toString();
|
|
4250
4354
|
context.lineWidth = 3;
|
|
4251
4355
|
context.rect(x, y, width, medalDisplaySize.y);
|
|
4252
4356
|
context.fill();
|
|
@@ -4695,8 +4799,10 @@ function glCopyToContext(context, forceDraw=false)
|
|
|
4695
4799
|
* @memberof WebGL */
|
|
4696
4800
|
function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdditive=0)
|
|
4697
4801
|
{
|
|
4802
|
+
ASSERT(typeof rgba == 'number' && typeof rgbaAdditive == 'number', 'invalid color');
|
|
4803
|
+
|
|
4698
4804
|
// flush if there is not enough room or if different blend mode
|
|
4699
|
-
if (glInstanceCount >= gl_MAX_INSTANCES
|
|
4805
|
+
if (glInstanceCount >= gl_MAX_INSTANCES || glBatchAdditive != glAdditive)
|
|
4700
4806
|
glFlush();
|
|
4701
4807
|
|
|
4702
4808
|
let offset = glInstanceCount * gl_INDICIES_PER_INSTANCE;
|
|
@@ -4723,7 +4829,7 @@ let glPostShader, glPostArrayBuffer, glPostTexture, glPostIncludeOverlay;
|
|
|
4723
4829
|
* @param {String} shaderCode
|
|
4724
4830
|
* @param {Boolean} includeOverlay
|
|
4725
4831
|
* @memberof WebGL */
|
|
4726
|
-
function glInitPostProcess(shaderCode, includeOverlay)
|
|
4832
|
+
function glInitPostProcess(shaderCode, includeOverlay=false)
|
|
4727
4833
|
{
|
|
4728
4834
|
ASSERT(!glPostShader, 'can only have 1 post effects shader');
|
|
4729
4835
|
|
|
@@ -4759,6 +4865,8 @@ function glInitPostProcess(shaderCode, includeOverlay)
|
|
|
4759
4865
|
|
|
4760
4866
|
// hide the original 2d canvas
|
|
4761
4867
|
mainCanvas.style.visibility = 'hidden';
|
|
4868
|
+
if (glPostIncludeOverlay)
|
|
4869
|
+
overlayCanvas.style.visibility = 'hidden';
|
|
4762
4870
|
}
|
|
4763
4871
|
|
|
4764
4872
|
// Render the post processing shader, called automatically by the engine
|
|
@@ -4779,14 +4887,8 @@ function glRenderPostProcess()
|
|
|
4779
4887
|
glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
|
|
4780
4888
|
}
|
|
4781
4889
|
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
// copy overlay canvas so it will be included in post processing
|
|
4785
|
-
mainContext.drawImage(overlayCanvas, 0, 0);
|
|
4786
|
-
|
|
4787
|
-
// clear overlay canvas
|
|
4788
|
-
overlayCanvas.width = mainCanvas.width;
|
|
4789
|
-
}
|
|
4890
|
+
// copy overlay canvas so it will be included in post processing
|
|
4891
|
+
glPostIncludeOverlay && mainContext.drawImage(overlayCanvas, 0, 0);
|
|
4790
4892
|
|
|
4791
4893
|
// setup shader program to draw one triangle
|
|
4792
4894
|
glContext.useProgram(glPostShader);
|
|
@@ -4880,7 +4982,7 @@ const engineName = 'LittleJS';
|
|
|
4880
4982
|
* @type {String}
|
|
4881
4983
|
* @default
|
|
4882
4984
|
* @memberof Engine */
|
|
4883
|
-
const engineVersion = '1.9.
|
|
4985
|
+
const engineVersion = '1.9.2';
|
|
4884
4986
|
|
|
4885
4987
|
/** Frames per second to update objects
|
|
4886
4988
|
* @type {Number}
|