q5play 4.0.6 → 4.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/q5play.d.ts +8 -0
- package/q5play.js +94 -35
package/package.json
CHANGED
package/q5play.d.ts
CHANGED
|
@@ -70,6 +70,14 @@ declare global {
|
|
|
70
70
|
* @default false
|
|
71
71
|
*/
|
|
72
72
|
renderStats: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Runs automatically before each draw function call.
|
|
75
|
+
*/
|
|
76
|
+
update(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Runs automatically after each draw function call.
|
|
79
|
+
*/
|
|
80
|
+
postDraw(): void;
|
|
73
81
|
}
|
|
74
82
|
const q5play: Q5Play;
|
|
75
83
|
|
package/q5play.js
CHANGED
|
@@ -248,6 +248,9 @@ async function q5playPreSetup(q) {
|
|
|
248
248
|
this.os = {};
|
|
249
249
|
this.context = 'web';
|
|
250
250
|
|
|
251
|
+
this.update = () => q5playUpdate.call($, q);
|
|
252
|
+
this.postdraw = () => q5playPostDraw.call($, q);
|
|
253
|
+
|
|
251
254
|
if (window.matchMedia) {
|
|
252
255
|
this.hasMouse = window.matchMedia('(any-hover: none)').matches ? false : true;
|
|
253
256
|
} else this.hasMouse = true;
|
|
@@ -331,7 +334,8 @@ async function q5playPreSetup(q) {
|
|
|
331
334
|
|
|
332
335
|
// in q5play the default angle mode is degrees
|
|
333
336
|
const DEGREES = $.DEGREES,
|
|
334
|
-
DEGTORAD = Math.PI / 180
|
|
337
|
+
DEGTORAD = Math.PI / 180,
|
|
338
|
+
RADTODEG = 180 / Math.PI;
|
|
335
339
|
$.angleMode(DEGREES);
|
|
336
340
|
|
|
337
341
|
// in q5play the default color mode is float RGB
|
|
@@ -1001,6 +1005,7 @@ async function q5playPreSetup(q) {
|
|
|
1001
1005
|
if (!group.visualOnly) {
|
|
1002
1006
|
const def = new b2DefaultBodyDef();
|
|
1003
1007
|
def.type = bodyTypes[this._phys];
|
|
1008
|
+
def.allowFastRotation = true;
|
|
1004
1009
|
this.bdID = b2CreateBody(wID, def);
|
|
1005
1010
|
this._physicsEnabled = true;
|
|
1006
1011
|
|
|
@@ -5345,6 +5350,7 @@ async function q5playPreSetup(q) {
|
|
|
5345
5350
|
this.type = type ??= 'glue';
|
|
5346
5351
|
this.visible = true;
|
|
5347
5352
|
this.deleted = false;
|
|
5353
|
+
this._springiness = 0;
|
|
5348
5354
|
|
|
5349
5355
|
if (!a._shapes.length) a.addDefaultSensors();
|
|
5350
5356
|
if (!b._shapes.length) b.addDefaultSensors();
|
|
@@ -5533,6 +5539,7 @@ async function q5playPreSetup(q) {
|
|
|
5533
5539
|
|
|
5534
5540
|
_springMap(val) {
|
|
5535
5541
|
if (val > 0) {
|
|
5542
|
+
this._springiness = val;
|
|
5536
5543
|
if (val < 0.1) {
|
|
5537
5544
|
val = $.map(val, 0, 0.1, 30, 4);
|
|
5538
5545
|
} else if (val < 0.5) {
|
|
@@ -5569,7 +5576,7 @@ async function q5playPreSetup(q) {
|
|
|
5569
5576
|
}
|
|
5570
5577
|
|
|
5571
5578
|
get springiness() {
|
|
5572
|
-
return
|
|
5579
|
+
return this._springiness;
|
|
5573
5580
|
}
|
|
5574
5581
|
set springiness(val) {
|
|
5575
5582
|
val = this._springMap(val);
|
|
@@ -5645,7 +5652,7 @@ async function q5playPreSetup(q) {
|
|
|
5645
5652
|
}
|
|
5646
5653
|
|
|
5647
5654
|
get springiness() {
|
|
5648
|
-
return
|
|
5655
|
+
return this._springiness;
|
|
5649
5656
|
}
|
|
5650
5657
|
set springiness(val) {
|
|
5651
5658
|
val = this._springMap(val);
|
|
@@ -5689,15 +5696,20 @@ async function q5playPreSetup(q) {
|
|
|
5689
5696
|
constructor(spriteA, spriteB) {
|
|
5690
5697
|
super(spriteA, spriteB, 'wheel');
|
|
5691
5698
|
|
|
5699
|
+
this._angle = $._angleMode == DEGREES ? 90 : Math.PI / 2;
|
|
5700
|
+
this._motorEnabled = false;
|
|
5701
|
+
|
|
5692
5702
|
let j = this._init(b2DefaultWheelJointDef(wID));
|
|
5693
5703
|
j.enableSpring = true;
|
|
5694
5704
|
j.hertz = 4;
|
|
5695
5705
|
j.dampingRatio = 0.7;
|
|
5696
|
-
j.enableMotor =
|
|
5706
|
+
j.enableMotor = false; // neutral by default
|
|
5697
5707
|
j.maxMotorTorque = 1000;
|
|
5698
5708
|
|
|
5699
5709
|
this.jID = b2CreateWheelJoint(wID, j);
|
|
5700
5710
|
jointDict[this.jID.index1] = this;
|
|
5711
|
+
|
|
5712
|
+
this._springiness = 0.1;
|
|
5701
5713
|
}
|
|
5702
5714
|
|
|
5703
5715
|
_init(j) {
|
|
@@ -5707,11 +5719,12 @@ async function q5playPreSetup(q) {
|
|
|
5707
5719
|
j.base.bodyIdA = a.bdID;
|
|
5708
5720
|
j.base.bodyIdB = b.bdID;
|
|
5709
5721
|
|
|
5710
|
-
|
|
5722
|
+
let rad = this._angle;
|
|
5723
|
+
if ($._angleMode == DEGREES) rad *= DEGTORAD;
|
|
5724
|
+
j.base.localFrameA.q.SetAngle(rad);
|
|
5711
5725
|
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
// j.base.localFrameA.q = b2InvMulRot(qA, qB);
|
|
5726
|
+
let pivot = scaleTo(b.x, b.y);
|
|
5727
|
+
j.base.localFrameA.p = b2Body_GetLocalPoint(a.bdID, pivot);
|
|
5715
5728
|
|
|
5716
5729
|
return j;
|
|
5717
5730
|
}
|
|
@@ -5724,9 +5737,12 @@ async function q5playPreSetup(q) {
|
|
|
5724
5737
|
set angle(val) {
|
|
5725
5738
|
if (val == this._angle) return;
|
|
5726
5739
|
this._angle = val;
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5740
|
+
let rad = $._angleMode == DEGREES ? val * DEGTORAD : val;
|
|
5741
|
+
|
|
5742
|
+
let t = b2Joint_GetLocalFrameA(this.jID);
|
|
5743
|
+
t.q.SetAngle(rad);
|
|
5744
|
+
b2Joint_SetLocalFrameA(this.jID, t);
|
|
5745
|
+
b2Joint_WakeBodies(this.jID);
|
|
5730
5746
|
}
|
|
5731
5747
|
|
|
5732
5748
|
get springEnabled() {
|
|
@@ -5737,7 +5753,7 @@ async function q5playPreSetup(q) {
|
|
|
5737
5753
|
}
|
|
5738
5754
|
|
|
5739
5755
|
get springiness() {
|
|
5740
|
-
return
|
|
5756
|
+
return this._springiness;
|
|
5741
5757
|
}
|
|
5742
5758
|
set springiness(val) {
|
|
5743
5759
|
val = this._springMap(val);
|
|
@@ -5775,13 +5791,16 @@ async function q5playPreSetup(q) {
|
|
|
5775
5791
|
}
|
|
5776
5792
|
set motorEnabled(val) {
|
|
5777
5793
|
Box2D.b2WheelJoint_EnableMotor(this.jID, val);
|
|
5794
|
+
this._motorEnabled = val;
|
|
5778
5795
|
}
|
|
5779
5796
|
|
|
5780
5797
|
get maxPower() {
|
|
5781
5798
|
return Box2D.b2WheelJoint_GetMaxMotorTorque(this.jID);
|
|
5782
5799
|
}
|
|
5783
5800
|
set maxPower(val) {
|
|
5801
|
+
if (val > 0 && !this._motorEnabled) this.motorEnabled = true;
|
|
5784
5802
|
Box2D.b2WheelJoint_SetMaxMotorTorque(this.jID, val);
|
|
5803
|
+
b2Joint_WakeBodies(this.jID);
|
|
5785
5804
|
}
|
|
5786
5805
|
|
|
5787
5806
|
get power() {
|
|
@@ -5789,10 +5808,14 @@ async function q5playPreSetup(q) {
|
|
|
5789
5808
|
}
|
|
5790
5809
|
|
|
5791
5810
|
get speed() {
|
|
5811
|
+
// if in neutral, return the wheel's angular velocity
|
|
5812
|
+
if (!this._motorEnabled) return this.spriteB.rotationSpeed;
|
|
5792
5813
|
return Box2D.b2WheelJoint_GetMotorSpeed(this.jID);
|
|
5793
5814
|
}
|
|
5794
5815
|
set speed(val) {
|
|
5816
|
+
if (!this._motorEnabled) this.motorEnabled = true;
|
|
5795
5817
|
Box2D.b2WheelJoint_SetMotorSpeed(this.jID, val);
|
|
5818
|
+
b2Joint_WakeBodies(this.jID);
|
|
5796
5819
|
}
|
|
5797
5820
|
};
|
|
5798
5821
|
|
|
@@ -5820,7 +5843,7 @@ async function q5playPreSetup(q) {
|
|
|
5820
5843
|
}
|
|
5821
5844
|
|
|
5822
5845
|
get springiness() {
|
|
5823
|
-
return
|
|
5846
|
+
return this._springiness;
|
|
5824
5847
|
}
|
|
5825
5848
|
set springiness(val) {
|
|
5826
5849
|
val = this._springMap(val);
|
|
@@ -5860,8 +5883,8 @@ async function q5playPreSetup(q) {
|
|
|
5860
5883
|
max = val[1];
|
|
5861
5884
|
}
|
|
5862
5885
|
if ($._angleMode == DEGREES) {
|
|
5863
|
-
min *=
|
|
5864
|
-
max *=
|
|
5886
|
+
min *= DEGTORAD;
|
|
5887
|
+
max *= DEGTORAD;
|
|
5865
5888
|
}
|
|
5866
5889
|
Box2D.b2RevoluteJoint_SetLimits(this.jID, min, max);
|
|
5867
5890
|
}
|
|
@@ -5890,8 +5913,6 @@ async function q5playPreSetup(q) {
|
|
|
5890
5913
|
set maxPower(val) {
|
|
5891
5914
|
Box2D.b2RevoluteJoint_SetMaxMotorTorque(this.jID, val);
|
|
5892
5915
|
}
|
|
5893
|
-
|
|
5894
|
-
_display() {}
|
|
5895
5916
|
};
|
|
5896
5917
|
|
|
5897
5918
|
$.SliderJoint = class extends $.Joint {
|
|
@@ -5899,17 +5920,39 @@ async function q5playPreSetup(q) {
|
|
|
5899
5920
|
super(spriteA, spriteB, 'slider');
|
|
5900
5921
|
|
|
5901
5922
|
let j = this._init(b2DefaultPrismaticJointDef());
|
|
5902
|
-
j.enableLimit =
|
|
5903
|
-
j.lowerTranslation = -1;
|
|
5904
|
-
j.upperTranslation = 1;
|
|
5923
|
+
j.enableLimit = false;
|
|
5905
5924
|
j.enableMotor = true;
|
|
5906
|
-
j.maxMotorForce =
|
|
5925
|
+
j.maxMotorForce = 10;
|
|
5907
5926
|
j.motorSpeed = 0;
|
|
5908
5927
|
|
|
5909
5928
|
this.jID = b2CreatePrismaticJoint(wID, j);
|
|
5910
5929
|
jointDict[this.jID.index1] = this;
|
|
5911
5930
|
}
|
|
5912
5931
|
|
|
5932
|
+
_init(j) {
|
|
5933
|
+
let a = this.spriteA,
|
|
5934
|
+
b = this.spriteB;
|
|
5935
|
+
|
|
5936
|
+
j.base.bodyIdA = a.bdID;
|
|
5937
|
+
j.base.bodyIdB = b.bdID;
|
|
5938
|
+
|
|
5939
|
+
// set the anchor at sprite A's position in B's local frame
|
|
5940
|
+
j.base.localFrameB.p = b2Body_GetLocalPoint(b.bdID, scaleTo(a.x, a.y));
|
|
5941
|
+
|
|
5942
|
+
// align the slide axis with the vector from A to B
|
|
5943
|
+
let dx = b.x - a.x;
|
|
5944
|
+
let dy = b.y - a.y;
|
|
5945
|
+
let len = Math.sqrt(dx * dx + dy * dy);
|
|
5946
|
+
let angle = len > 0 ? Math.atan2(dy, dx) : 0;
|
|
5947
|
+
|
|
5948
|
+
let qA = b2Body_GetRotation(a.bdID);
|
|
5949
|
+
let qB = b2Body_GetRotation(b.bdID);
|
|
5950
|
+
j.base.localFrameA.q.SetAngle(angle - qA.GetAngle());
|
|
5951
|
+
j.base.localFrameB.q.SetAngle(angle - qB.GetAngle());
|
|
5952
|
+
|
|
5953
|
+
return j;
|
|
5954
|
+
}
|
|
5955
|
+
|
|
5913
5956
|
get translation() {
|
|
5914
5957
|
return Box2D.b2PrismaticJoint_GetTranslation(this.jID) * meterSize;
|
|
5915
5958
|
}
|
|
@@ -5940,6 +5983,21 @@ async function q5playPreSetup(q) {
|
|
|
5940
5983
|
max = val[1];
|
|
5941
5984
|
}
|
|
5942
5985
|
Box2D.b2PrismaticJoint_SetLimits(this.jID, min / meterSize, max / meterSize);
|
|
5986
|
+
Box2D.b2PrismaticJoint_EnableLimit(this.jID, true);
|
|
5987
|
+
}
|
|
5988
|
+
|
|
5989
|
+
set limits(val) {
|
|
5990
|
+
let min, max;
|
|
5991
|
+
if (typeof val == 'number') {
|
|
5992
|
+
val /= 2;
|
|
5993
|
+
min = -val;
|
|
5994
|
+
max = val;
|
|
5995
|
+
} else {
|
|
5996
|
+
min = val[0];
|
|
5997
|
+
max = val[1];
|
|
5998
|
+
}
|
|
5999
|
+
Box2D.b2PrismaticJoint_SetLimits(this.jID, min / meterSize, max / meterSize);
|
|
6000
|
+
Box2D.b2PrismaticJoint_EnableLimit(this.jID, true);
|
|
5943
6001
|
}
|
|
5944
6002
|
|
|
5945
6003
|
get springEnabled() {
|
|
@@ -5950,10 +6008,10 @@ async function q5playPreSetup(q) {
|
|
|
5950
6008
|
}
|
|
5951
6009
|
|
|
5952
6010
|
get springiness() {
|
|
5953
|
-
return
|
|
6011
|
+
return this._springiness;
|
|
5954
6012
|
}
|
|
5955
6013
|
set springiness(val) {
|
|
5956
|
-
val = this._springMap
|
|
6014
|
+
val = this._springMap(val);
|
|
5957
6015
|
Box2D.b2PrismaticJoint_SetSpringHertz(this.jID, val);
|
|
5958
6016
|
}
|
|
5959
6017
|
|
|
@@ -5976,6 +6034,7 @@ async function q5playPreSetup(q) {
|
|
|
5976
6034
|
}
|
|
5977
6035
|
set speed(val) {
|
|
5978
6036
|
Box2D.b2PrismaticJoint_SetMotorSpeed(this.jID, val);
|
|
6037
|
+
b2Joint_WakeBodies(this.jID);
|
|
5979
6038
|
}
|
|
5980
6039
|
|
|
5981
6040
|
get maxPower() {
|
|
@@ -5989,14 +6048,14 @@ async function q5playPreSetup(q) {
|
|
|
5989
6048
|
return Box2D.b2PrismaticJoint_GetMotorForce(this.jID);
|
|
5990
6049
|
}
|
|
5991
6050
|
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
6051
|
+
get energy() {
|
|
6052
|
+
return Box2D.b2PrismaticJoint_GetSpeed(this.jID);
|
|
6053
|
+
}
|
|
5995
6054
|
};
|
|
5996
6055
|
|
|
5997
6056
|
$.GrabberJoint = class extends $.Joint {
|
|
5998
|
-
constructor(
|
|
5999
|
-
sprite ??=
|
|
6057
|
+
constructor(grabPoint, sprite) {
|
|
6058
|
+
sprite ??= grabPoint;
|
|
6000
6059
|
super(sprite, sprite, 'grabber');
|
|
6001
6060
|
|
|
6002
6061
|
let bd = b2DefaultBodyDef();
|
|
@@ -6022,11 +6081,11 @@ async function q5playPreSetup(q) {
|
|
|
6022
6081
|
|
|
6023
6082
|
this.jID = b2CreateMotorJoint(wID, j);
|
|
6024
6083
|
|
|
6025
|
-
let offX = sprite.x - (
|
|
6026
|
-
offY = sprite.y - (
|
|
6084
|
+
let offX = sprite.x - (grabPoint[0] || grabPoint.x),
|
|
6085
|
+
offY = sprite.y - (grabPoint[1] || grabPoint.y);
|
|
6027
6086
|
if (!isSlop(offX) || !isSlop(offY)) {
|
|
6028
6087
|
this._setOffsetB(-offX, -offY);
|
|
6029
|
-
this.target =
|
|
6088
|
+
this.target = grabPoint;
|
|
6030
6089
|
}
|
|
6031
6090
|
|
|
6032
6091
|
this.sprite = sprite;
|
|
@@ -7797,7 +7856,7 @@ async function q5playPreSetup(q) {
|
|
|
7797
7856
|
s._vel._magCached = false;
|
|
7798
7857
|
|
|
7799
7858
|
if (s._hasImagery || s._userDefinedDraw) {
|
|
7800
|
-
s._rotation = Math.atan2(data[2], data[3]) *
|
|
7859
|
+
s._rotation = Math.atan2(data[2], data[3]) * RADTODEG;
|
|
7801
7860
|
}
|
|
7802
7861
|
|
|
7803
7862
|
if (s.debug || (!s._hasImagery && !s._userDefinedDraw)) {
|
|
@@ -7812,7 +7871,7 @@ async function q5playPreSetup(q) {
|
|
|
7812
7871
|
debugYellow = $.color(colorMax, colorMax, 0, colorMax * 0.9),
|
|
7813
7872
|
debugYellowFill = $.color(colorMax, colorMax, 0, colorMax * 0.1);
|
|
7814
7873
|
|
|
7815
|
-
if ($.
|
|
7874
|
+
if ($.canvas.c2d) {
|
|
7816
7875
|
// polyfill for q5 WebGPU high efficiency functions
|
|
7817
7876
|
$._getFillIdx = () => $._fill;
|
|
7818
7877
|
$._setFillIdx = (v) => ($._fill = v);
|
|
@@ -8026,7 +8085,7 @@ function q5playPostSetup() {
|
|
|
8026
8085
|
}
|
|
8027
8086
|
|
|
8028
8087
|
// called before each draw function call
|
|
8029
|
-
function
|
|
8088
|
+
function q5playUpdate() {
|
|
8030
8089
|
const $ = this;
|
|
8031
8090
|
|
|
8032
8091
|
if (!$._q5) {
|
|
@@ -8382,6 +8441,6 @@ q5playClassLangs.Group += q5playClassLangs.Sprite;
|
|
|
8382
8441
|
|
|
8383
8442
|
Q5.addHook('presetup', q5playPreSetup);
|
|
8384
8443
|
Q5.addHook('postsetup', q5playPostSetup);
|
|
8385
|
-
Q5.addHook('predraw',
|
|
8444
|
+
Q5.addHook('predraw', q5playUpdate);
|
|
8386
8445
|
Q5.addHook('postdraw', q5playPostDraw);
|
|
8387
8446
|
Q5.addHook('remove', q5playRemove);
|