q5play 4.1.1 → 4.2.0
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 +2 -2
- package/py.typed +0 -0
- package/q5play.d.ts +1387 -163
- package/q5play.js +543 -146
- package/q5play.pyi +5007 -0
package/q5play.js
CHANGED
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
* |__/ |__/ \______/
|
|
13
13
|
*
|
|
14
14
|
* @package q5play
|
|
15
|
-
* @version 4.
|
|
15
|
+
* @version 4.2
|
|
16
16
|
* @author quinton-ashley
|
|
17
17
|
* @website https://q5play.org
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
let q5play_version = '4.
|
|
20
|
+
let q5play_version = '4.2';
|
|
21
21
|
|
|
22
22
|
if (typeof globalThis.Q5 == 'undefined') {
|
|
23
23
|
console.error('q5play requires q5.js to be loaded first. Visit https://q5js.org to learn more.');
|
|
@@ -85,6 +85,7 @@ async function q5playPreSetup(q) {
|
|
|
85
85
|
b2World_OverlapShape,
|
|
86
86
|
b2World_CastRay,
|
|
87
87
|
b2World_CastRayClosest,
|
|
88
|
+
b2World_CastShape,
|
|
88
89
|
b2World_SetCustomFilterCallback,
|
|
89
90
|
b2World_SetPreSolveCallback,
|
|
90
91
|
b2World_GetGravity,
|
|
@@ -395,7 +396,9 @@ async function q5playPreSetup(q) {
|
|
|
395
396
|
const scaleFrom = (x, y) => ({ x: x * meterSize, y: y * meterSize });
|
|
396
397
|
|
|
397
398
|
const linearSlop = 0.005,
|
|
398
|
-
angularSlop = 0.
|
|
399
|
+
angularSlop = 0.0333;
|
|
400
|
+
|
|
401
|
+
let visualSlop = 0.5;
|
|
399
402
|
|
|
400
403
|
const isSlop = (val) => Math.abs(val) <= linearSlop;
|
|
401
404
|
const fixRound = (val) => {
|
|
@@ -538,6 +541,12 @@ async function q5playPreSetup(q) {
|
|
|
538
541
|
this._density = val;
|
|
539
542
|
b2Shape_SetDensity(this.id, val);
|
|
540
543
|
}
|
|
544
|
+
|
|
545
|
+
applyWind(strength, angle, drag = 0, lift = 0) {
|
|
546
|
+
const wind = new b2Vec2(strength * $.cos(angle), strength * $.sin(angle));
|
|
547
|
+
b2Shape_ApplyWind(this.id, wind, drag, lift, true);
|
|
548
|
+
wind.delete();
|
|
549
|
+
}
|
|
541
550
|
};
|
|
542
551
|
|
|
543
552
|
const Sensor = class extends Shape {
|
|
@@ -1192,10 +1201,10 @@ async function q5playPreSetup(q) {
|
|
|
1192
1201
|
else this.addCollider(...args);
|
|
1193
1202
|
}
|
|
1194
1203
|
|
|
1195
|
-
this.
|
|
1204
|
+
this.prevX = x;
|
|
1205
|
+
this.prevY = y;
|
|
1196
1206
|
this.prevRotation = 0;
|
|
1197
|
-
|
|
1198
|
-
this._destIdx = 0;
|
|
1207
|
+
|
|
1199
1208
|
this._debug = false;
|
|
1200
1209
|
|
|
1201
1210
|
if (!group._isAllSpritesGroup) $.allSprites.push(this);
|
|
@@ -1884,7 +1893,7 @@ async function q5playPreSetup(q) {
|
|
|
1884
1893
|
}
|
|
1885
1894
|
const speed = this._vel.mag();
|
|
1886
1895
|
if (speed) {
|
|
1887
|
-
this.
|
|
1896
|
+
this.__setVel($.cos(val) * speed, $.sin(val) * speed);
|
|
1888
1897
|
this._vel._magCached = false;
|
|
1889
1898
|
}
|
|
1890
1899
|
this._vel._direction = val;
|
|
@@ -1992,19 +2001,17 @@ async function q5playPreSetup(q) {
|
|
|
1992
2001
|
this._opacity = val;
|
|
1993
2002
|
}
|
|
1994
2003
|
|
|
1995
|
-
get
|
|
1996
|
-
return this.
|
|
2004
|
+
get previousX() {
|
|
2005
|
+
return this.prevX;
|
|
1997
2006
|
}
|
|
1998
|
-
|
|
1999
|
-
|
|
2007
|
+
|
|
2008
|
+
get previousY() {
|
|
2009
|
+
return this.prevY;
|
|
2000
2010
|
}
|
|
2001
2011
|
|
|
2002
2012
|
get previousRotation() {
|
|
2003
2013
|
return this.prevRotation;
|
|
2004
2014
|
}
|
|
2005
|
-
set previousRotation(val) {
|
|
2006
|
-
this.prevRotation = val;
|
|
2007
|
-
}
|
|
2008
2015
|
|
|
2009
2016
|
get pixelPerfect() {
|
|
2010
2017
|
return this._pixelPerfect;
|
|
@@ -2028,8 +2035,9 @@ async function q5playPreSetup(q) {
|
|
|
2028
2035
|
get rotation() {
|
|
2029
2036
|
if (!this._physicsEnabled || !usePhysics) return this._rotation || 0;
|
|
2030
2037
|
let val = b2Body_GetRotation(this.bdID).GetAngle();
|
|
2038
|
+
if ($._angleMode == DEGREES) val = $.degrees(val);
|
|
2031
2039
|
if (friendlyRounding) val = fixRoundAngular(val);
|
|
2032
|
-
return (this._rotation =
|
|
2040
|
+
return (this._rotation = val);
|
|
2033
2041
|
}
|
|
2034
2042
|
set rotation(val) {
|
|
2035
2043
|
this._rotation = val;
|
|
@@ -2053,17 +2061,15 @@ async function q5playPreSetup(q) {
|
|
|
2053
2061
|
}
|
|
2054
2062
|
set rotationLock(val) {
|
|
2055
2063
|
if (this.watch) this.mod[25] = true;
|
|
2064
|
+
this._rotationLock = val;
|
|
2065
|
+
if (!this._physicsEnabled) return;
|
|
2056
2066
|
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
// TODO: not working, shape is ignored by physics sim after this
|
|
2060
|
-
let locks = new b2MotionLocks();
|
|
2067
|
+
const locks = new b2MotionLocks();
|
|
2061
2068
|
locks.linearX = false;
|
|
2062
2069
|
locks.linearY = false;
|
|
2063
2070
|
locks.angularZ = val;
|
|
2064
2071
|
b2Body_SetMotionLocks(this.bdID, locks);
|
|
2065
|
-
|
|
2066
|
-
// this.mass = mass;
|
|
2072
|
+
locks.delete();
|
|
2067
2073
|
}
|
|
2068
2074
|
|
|
2069
2075
|
get rotationSpeed() {
|
|
@@ -2148,14 +2154,14 @@ async function q5playPreSetup(q) {
|
|
|
2148
2154
|
return this._vel.mag();
|
|
2149
2155
|
}
|
|
2150
2156
|
set speed(val) {
|
|
2151
|
-
if (!val) this.
|
|
2157
|
+
if (!val) this.__setVel(0, 0);
|
|
2152
2158
|
else {
|
|
2153
2159
|
const mag = this._vel.mag();
|
|
2154
2160
|
if (mag > 0) {
|
|
2155
|
-
this.
|
|
2161
|
+
this.__setVel((this._vel.x / mag) * val, (this._vel.y / mag) * val);
|
|
2156
2162
|
} else {
|
|
2157
2163
|
const dir = this._vel.direction();
|
|
2158
|
-
this.
|
|
2164
|
+
this.__setVel($.cos(dir) * val, $.sin(dir) * val);
|
|
2159
2165
|
}
|
|
2160
2166
|
}
|
|
2161
2167
|
this._vel._mag = val;
|
|
@@ -2163,7 +2169,7 @@ async function q5playPreSetup(q) {
|
|
|
2163
2169
|
}
|
|
2164
2170
|
|
|
2165
2171
|
setSpeedAndDirection(speed, direction) {
|
|
2166
|
-
this.
|
|
2172
|
+
this.__setVel($.cos(direction) * speed, $.sin(direction) * speed);
|
|
2167
2173
|
this._vel._mag = speed;
|
|
2168
2174
|
this._vel._direction = direction;
|
|
2169
2175
|
this._vel._magCached = this._vel._directionCached = true;
|
|
@@ -2225,7 +2231,7 @@ async function q5playPreSetup(q) {
|
|
|
2225
2231
|
}
|
|
2226
2232
|
|
|
2227
2233
|
get pos() {
|
|
2228
|
-
return this.
|
|
2234
|
+
return { x: this._posX, y: this._posY };
|
|
2229
2235
|
}
|
|
2230
2236
|
set pos(val) {
|
|
2231
2237
|
if (val == $.mouse && !$.mouse.isActive) return;
|
|
@@ -2404,7 +2410,6 @@ async function q5playPreSetup(q) {
|
|
|
2404
2410
|
}
|
|
2405
2411
|
set vel(val) {
|
|
2406
2412
|
this._setVel(val[0] ?? val.x, val[1] ?? val.y);
|
|
2407
|
-
this._vel._magCached = this._vel._directionCached = false;
|
|
2408
2413
|
}
|
|
2409
2414
|
|
|
2410
2415
|
_setVel(x, y) {
|
|
@@ -2414,6 +2419,16 @@ async function q5playPreSetup(q) {
|
|
|
2414
2419
|
this._velX = x;
|
|
2415
2420
|
this._velY = y;
|
|
2416
2421
|
this._velSynced = true;
|
|
2422
|
+
this._vel._magCached = this._vel._directionCached = false;
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
__setVel(x, y) {
|
|
2426
|
+
if (this._physicsEnabled) {
|
|
2427
|
+
b2Body_SetLinearVelocity(this.bdID, new b2Vec2(x, y));
|
|
2428
|
+
}
|
|
2429
|
+
this._velX = x;
|
|
2430
|
+
this._velY = y;
|
|
2431
|
+
this._velSynced = true;
|
|
2417
2432
|
}
|
|
2418
2433
|
|
|
2419
2434
|
get velocity() {
|
|
@@ -2442,6 +2457,9 @@ async function q5playPreSetup(q) {
|
|
|
2442
2457
|
|
|
2443
2458
|
_update() {
|
|
2444
2459
|
if (this._customUpdate) this._customUpdate();
|
|
2460
|
+
this.prevX = this._posX;
|
|
2461
|
+
this.prevY = this._posY;
|
|
2462
|
+
this.prevRotation = this.rotation;
|
|
2445
2463
|
if (this.autoUpdate) this.autoUpdate = null;
|
|
2446
2464
|
}
|
|
2447
2465
|
|
|
@@ -2463,6 +2481,70 @@ async function q5playPreSetup(q) {
|
|
|
2463
2481
|
}
|
|
2464
2482
|
}
|
|
2465
2483
|
|
|
2484
|
+
if (this._destArrivalTime !== undefined && $.world.physicsTime >= this._destArrivalTime) {
|
|
2485
|
+
const x = this._posX,
|
|
2486
|
+
y = this._posY,
|
|
2487
|
+
prevX = this.prevX,
|
|
2488
|
+
prevY = this.prevY,
|
|
2489
|
+
destX = this._destX,
|
|
2490
|
+
destY = this._destY;
|
|
2491
|
+
|
|
2492
|
+
const destReachedX =
|
|
2493
|
+
destX === undefined || (destX >= Math.min(prevX, x) - visualSlop && destX <= Math.max(prevX, x) + visualSlop);
|
|
2494
|
+
const destReachedY =
|
|
2495
|
+
destY === undefined || (destY >= Math.min(prevY, y) - visualSlop && destY <= Math.max(prevY, y) + visualSlop);
|
|
2496
|
+
const destReached = destReachedX && destReachedY;
|
|
2497
|
+
|
|
2498
|
+
if (destReached) {
|
|
2499
|
+
this._setVel(0, 0);
|
|
2500
|
+
this.rotationSpeed = 0;
|
|
2501
|
+
this.pos = [this._destX ?? this._posX, this._destY ?? this._posY];
|
|
2502
|
+
if (this._destRot !== undefined) {
|
|
2503
|
+
this.rotation = this._destRot;
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
if (this._destResolve) {
|
|
2508
|
+
this._destResolve(destReached);
|
|
2509
|
+
this._destResolve = undefined;
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
this._destX = this._destY = this._destRot = this._destArrivalTime = undefined;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
if (this._destRotArrivalTime !== undefined && $.world.physicsTime >= this._destRotArrivalTime) {
|
|
2516
|
+
const isDeg = $._angleMode == DEGREES,
|
|
2517
|
+
full = isDeg ? 360 : $.TWO_PI,
|
|
2518
|
+
half = isDeg ? 180 : Math.PI,
|
|
2519
|
+
prevRot = this.prevRotation,
|
|
2520
|
+
currRot = this.rotation,
|
|
2521
|
+
destRot = this._destRot;
|
|
2522
|
+
|
|
2523
|
+
// normalize destRot to [-half, half) to match this.rotation's range
|
|
2524
|
+
let nd = ((destRot % full) + full) % full;
|
|
2525
|
+
if (nd >= half) nd -= full;
|
|
2526
|
+
|
|
2527
|
+
// when the sprite crosses the ±half boundary, prevRot and currRot jump
|
|
2528
|
+
// by ~full°; invert the range check so nd is tested against the arc that
|
|
2529
|
+
// was actually traversed rather than the gap between them
|
|
2530
|
+
const crossed180 = Math.abs(prevRot - currRot) > half;
|
|
2531
|
+
const rotReached = crossed180
|
|
2532
|
+
? nd >= Math.max(prevRot, currRot) - visualSlop || nd <= Math.min(prevRot, currRot) + visualSlop
|
|
2533
|
+
: nd >= Math.min(prevRot, currRot) - visualSlop && nd <= Math.max(prevRot, currRot) + visualSlop;
|
|
2534
|
+
|
|
2535
|
+
if (rotReached) {
|
|
2536
|
+
this.rotationSpeed = 0;
|
|
2537
|
+
this.rotation = nd;
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
if (this._destRotationResolve) {
|
|
2541
|
+
this._destRotationResolve(rotReached);
|
|
2542
|
+
this._destRotationResolve = undefined;
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
this._destRot = this._destRotArrivalTime = undefined;
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2466
2548
|
if (!this._physicsEnabled && !this._deleted) return;
|
|
2467
2549
|
|
|
2468
2550
|
this.__step();
|
|
@@ -2763,30 +2845,12 @@ async function q5playPreSetup(q) {
|
|
|
2763
2845
|
b2Body_ApplyTorque(this.bdID, val, true);
|
|
2764
2846
|
}
|
|
2765
2847
|
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
}
|
|
2771
|
-
return $.atan2(y - this.y, x - this.x);
|
|
2772
|
-
}
|
|
2773
|
-
|
|
2774
|
-
rotationToFace(x, y, facing) {
|
|
2775
|
-
if (typeof x == 'object') {
|
|
2776
|
-
facing = y;
|
|
2777
|
-
y = x.y;
|
|
2778
|
-
x = x.x;
|
|
2779
|
-
}
|
|
2780
|
-
// if the sprite is too close to the position, don't rotate
|
|
2781
|
-
if (Math.abs(x - this.x) < 0.01 && Math.abs(y - this.y) < 0.01) {
|
|
2782
|
-
return 0;
|
|
2848
|
+
applyWind(strength, angle, drag = 0, lift = 0) {
|
|
2849
|
+
const wind = new b2Vec2(strength * $.cos(angle), strength * $.sin(angle));
|
|
2850
|
+
for (let shape of this._shapes) {
|
|
2851
|
+
b2Shape_ApplyWind(shape.id, wind, drag, lift, true);
|
|
2783
2852
|
}
|
|
2784
|
-
|
|
2785
|
-
}
|
|
2786
|
-
|
|
2787
|
-
angleToFace(x, y, facing) {
|
|
2788
|
-
let ang = this.rotationToFace(x, y, facing);
|
|
2789
|
-
return minAngleDist(ang, this.rotation);
|
|
2853
|
+
wind.delete();
|
|
2790
2854
|
}
|
|
2791
2855
|
|
|
2792
2856
|
moveTowards(x, y, tracking) {
|
|
@@ -2803,13 +2867,13 @@ async function q5playPreSetup(q) {
|
|
|
2803
2867
|
|
|
2804
2868
|
let velX, velY;
|
|
2805
2869
|
|
|
2806
|
-
if (x !== null) {
|
|
2870
|
+
if (x !== null && x !== undefined) {
|
|
2807
2871
|
let diffX = x - this.x;
|
|
2808
2872
|
if (!isSlop(diffX)) {
|
|
2809
2873
|
velX = diffX * tracking;
|
|
2810
2874
|
} else velX = 0;
|
|
2811
2875
|
} else velX = this._velX;
|
|
2812
|
-
if (y !== null) {
|
|
2876
|
+
if (y !== null && y !== undefined) {
|
|
2813
2877
|
let diffY = y - this.y;
|
|
2814
2878
|
if (!isSlop(diffY)) {
|
|
2815
2879
|
velY = diffY * tracking;
|
|
@@ -2817,7 +2881,155 @@ async function q5playPreSetup(q) {
|
|
|
2817
2881
|
} else velY = this._velY;
|
|
2818
2882
|
|
|
2819
2883
|
this._setVel(velX, velY);
|
|
2820
|
-
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
moveTo(x, y, speed) {
|
|
2887
|
+
if (x === undefined && (y === undefined || y === null)) return;
|
|
2888
|
+
|
|
2889
|
+
if (x !== null && x !== undefined && typeof x != 'number') {
|
|
2890
|
+
let pos = x;
|
|
2891
|
+
if (pos == $.mouse && !$.mouse.isActive) return;
|
|
2892
|
+
speed = y;
|
|
2893
|
+
y = pos.y;
|
|
2894
|
+
x = pos.x;
|
|
2895
|
+
}
|
|
2896
|
+
|
|
2897
|
+
const moveX = x !== null && x !== undefined;
|
|
2898
|
+
const moveY = y !== null && y !== undefined;
|
|
2899
|
+
|
|
2900
|
+
speed ||= this.speed || 1;
|
|
2901
|
+
|
|
2902
|
+
const dist =
|
|
2903
|
+
moveX && moveY
|
|
2904
|
+
? Math.hypot(x - this._posX, y - this._posY)
|
|
2905
|
+
: moveX
|
|
2906
|
+
? Math.abs(x - this._posX)
|
|
2907
|
+
: Math.abs(y - this._posY);
|
|
2908
|
+
|
|
2909
|
+
if (this._destResolve) {
|
|
2910
|
+
this._destResolve(false);
|
|
2911
|
+
this._destResolve = undefined;
|
|
2912
|
+
}
|
|
2913
|
+
|
|
2914
|
+
this._destX = moveX ? x : undefined;
|
|
2915
|
+
this._destY = moveY ? y : undefined;
|
|
2916
|
+
this._destArrivalTime = $.world.physicsTime + dist / (speed * $.world._updateRate);
|
|
2917
|
+
|
|
2918
|
+
if (dist > 0) {
|
|
2919
|
+
if (moveX && moveY) {
|
|
2920
|
+
this.setSpeedAndDirection(speed, $.atan2(y - this.y, x - this.x));
|
|
2921
|
+
} else if (moveX) {
|
|
2922
|
+
this._setVel(x > this._posX ? speed : -speed, this._velY);
|
|
2923
|
+
} else {
|
|
2924
|
+
this._setVel(this._velX, y > this._posY ? speed : -speed);
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
|
|
2928
|
+
return {
|
|
2929
|
+
then: (onFulfilled) => {
|
|
2930
|
+
this._destResolve = onFulfilled;
|
|
2931
|
+
}
|
|
2932
|
+
};
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
angleTo(x, y, facing = 0) {
|
|
2936
|
+
if (typeof x == 'object') {
|
|
2937
|
+
facing = y || 0;
|
|
2938
|
+
y = x.y;
|
|
2939
|
+
x = x.x;
|
|
2940
|
+
}
|
|
2941
|
+
// if the sprite is too close to the position, don't rotate
|
|
2942
|
+
if (Math.abs(x - this.x) < 0.01 && Math.abs(y - this.y) < 0.01) {
|
|
2943
|
+
return this.rotation;
|
|
2944
|
+
}
|
|
2945
|
+
return $.atan2(y - this.y, x - this.x) + facing;
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
angleDistTo(x, y, facing = 0) {
|
|
2949
|
+
if (typeof x == 'object') {
|
|
2950
|
+
facing = y || 0;
|
|
2951
|
+
y = x.y;
|
|
2952
|
+
x = x.x;
|
|
2953
|
+
}
|
|
2954
|
+
// if the sprite is too close to the position, don't rotate
|
|
2955
|
+
if (Math.abs(x - this.x) < 0.01 && Math.abs(y - this.y) < 0.01) {
|
|
2956
|
+
return 0;
|
|
2957
|
+
}
|
|
2958
|
+
return minAngleDist($.atan2(y - this.y, x - this.x) + facing, this.rotation);
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
rotateTo(angle, speed) {
|
|
2962
|
+
let args = arguments;
|
|
2963
|
+
let x, y, facing;
|
|
2964
|
+
if (typeof args[0] != 'number') {
|
|
2965
|
+
x = args[0].x;
|
|
2966
|
+
y = args[0].y;
|
|
2967
|
+
speed = args[1];
|
|
2968
|
+
facing = args[2];
|
|
2969
|
+
} else if (arguments.length > 2) {
|
|
2970
|
+
x = args[0];
|
|
2971
|
+
y = args[1];
|
|
2972
|
+
speed = args[2];
|
|
2973
|
+
facing = args[3];
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
if (x !== undefined) angle = this.angleTo(x, y, facing);
|
|
2977
|
+
|
|
2978
|
+
const full = $._angleMode == DEGREES ? 360 : $.TWO_PI;
|
|
2979
|
+
let angleDist = (angle - this.rotation) % full;
|
|
2980
|
+
if (angleDist < 0 && speed > 0) angleDist += full;
|
|
2981
|
+
if (angleDist > 0 && speed < 0) angleDist -= full;
|
|
2982
|
+
|
|
2983
|
+
return this.rotate(angleDist, speed);
|
|
2984
|
+
}
|
|
2985
|
+
|
|
2986
|
+
rotateMinTo(angle, speed, facing) {
|
|
2987
|
+
let args = arguments;
|
|
2988
|
+
let x, y;
|
|
2989
|
+
if (typeof args[0] != 'number') {
|
|
2990
|
+
x = args[0].x;
|
|
2991
|
+
y = args[0].y;
|
|
2992
|
+
speed = args[1];
|
|
2993
|
+
facing = args[2];
|
|
2994
|
+
} else if (args.length > 2) {
|
|
2995
|
+
x = args[0];
|
|
2996
|
+
y = args[1];
|
|
2997
|
+
speed = args[2];
|
|
2998
|
+
facing = args[3];
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
if (x !== undefined) angle = this.angleTo(x, y, facing);
|
|
3002
|
+
|
|
3003
|
+
return this.rotate(minAngleDist(angle, this.rotation), speed);
|
|
3004
|
+
}
|
|
3005
|
+
|
|
3006
|
+
rotate(angleDist, speed) {
|
|
3007
|
+
if (Math.abs(angleDist) <= angularSlop) return;
|
|
3008
|
+
|
|
3009
|
+
speed ||= this.rotationSpeed || 1;
|
|
3010
|
+
speed = Math.abs(speed) * Math.sign(angleDist);
|
|
3011
|
+
|
|
3012
|
+
// cap speed so the sprite doesn't overshoot the destination in one physics step
|
|
3013
|
+
if (Math.abs(speed) > Math.abs(angleDist)) speed = angleDist;
|
|
3014
|
+
|
|
3015
|
+
this._destRotArrivalTime = $.world.physicsTime + Math.abs(angleDist) / (Math.abs(speed) * $.world._updateRate);
|
|
3016
|
+
|
|
3017
|
+
this._destRot = this.rotation + angleDist;
|
|
3018
|
+
|
|
3019
|
+
if (this._destRotationResolve) {
|
|
3020
|
+
this._destRotationResolve(false);
|
|
3021
|
+
this._destRotationResolve = undefined;
|
|
3022
|
+
}
|
|
3023
|
+
|
|
3024
|
+
this.rotationSpeed = speed;
|
|
3025
|
+
|
|
3026
|
+
log(this.rotation, this._destRot, angleDist, speed, this._destRotArrivalTime);
|
|
3027
|
+
|
|
3028
|
+
return {
|
|
3029
|
+
then: (onFulfilled) => {
|
|
3030
|
+
this._destRotationResolve = onFulfilled;
|
|
3031
|
+
}
|
|
3032
|
+
};
|
|
2821
3033
|
}
|
|
2822
3034
|
|
|
2823
3035
|
rotateTowards(angle, tracking) {
|
|
@@ -2835,18 +3047,31 @@ async function q5playPreSetup(q) {
|
|
|
2835
3047
|
facing = args[3];
|
|
2836
3048
|
}
|
|
2837
3049
|
|
|
2838
|
-
if (x !== undefined) angle = this.
|
|
3050
|
+
if (x !== undefined) angle = this.angleDistTo(x, y, facing);
|
|
2839
3051
|
else angle -= this.rotation;
|
|
2840
3052
|
|
|
2841
3053
|
tracking ??= 0.1;
|
|
2842
3054
|
this.rotationSpeed = angle * tracking;
|
|
2843
3055
|
}
|
|
2844
3056
|
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
3057
|
+
transformTowards(x, y, rotation, tracking = 0.1) {
|
|
3058
|
+
if (x === undefined) return;
|
|
3059
|
+
|
|
3060
|
+
if (typeof x != 'number') {
|
|
3061
|
+
let pos = x;
|
|
3062
|
+
if (pos == $.mouse && !$.mouse.isActive) return;
|
|
3063
|
+
tracking = rotation ?? tracking;
|
|
3064
|
+
rotation = y;
|
|
3065
|
+
y = pos.y;
|
|
3066
|
+
x = pos.x;
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
const t = new b2Transform();
|
|
3070
|
+
t.p = scaleTo(x ?? this._posX, y ?? this._posY);
|
|
3071
|
+
rotation ??= this._rotation;
|
|
3072
|
+
if ($._angleMode == DEGREES) rotation = (rotation % 360) * DEGTORAD;
|
|
2848
3073
|
t.q = b2MakeRot(rotation);
|
|
2849
|
-
b2Body_SetTargetTransform(this.bdID, t, $.world._timeStep);
|
|
3074
|
+
b2Body_SetTargetTransform(this.bdID, t, $.world._timeStep / tracking);
|
|
2850
3075
|
}
|
|
2851
3076
|
|
|
2852
3077
|
delete() {
|
|
@@ -4467,6 +4692,16 @@ async function q5playPreSetup(q) {
|
|
|
4467
4692
|
}
|
|
4468
4693
|
}
|
|
4469
4694
|
|
|
4695
|
+
applyWind(strength, angle, drag = 0, lift = 0) {
|
|
4696
|
+
const wind = new b2Vec2(strength * $.cos(angle), strength * $.sin(angle));
|
|
4697
|
+
for (let s of this) {
|
|
4698
|
+
for (let shape of s._shapes) {
|
|
4699
|
+
b2Shape_ApplyWind(shape.id, wind, drag, lift, true);
|
|
4700
|
+
}
|
|
4701
|
+
}
|
|
4702
|
+
wind.delete();
|
|
4703
|
+
}
|
|
4704
|
+
|
|
4470
4705
|
_resetCentroid() {
|
|
4471
4706
|
let x = 0;
|
|
4472
4707
|
let y = 0;
|
|
@@ -4509,6 +4744,134 @@ async function q5playPreSetup(q) {
|
|
|
4509
4744
|
}
|
|
4510
4745
|
}
|
|
4511
4746
|
|
|
4747
|
+
rotateTowards() {
|
|
4748
|
+
for (let s of this) {
|
|
4749
|
+
s.rotateTowards(...arguments);
|
|
4750
|
+
}
|
|
4751
|
+
}
|
|
4752
|
+
|
|
4753
|
+
rotateTo(angle, speed) {
|
|
4754
|
+
const thenables = [];
|
|
4755
|
+
for (let s of this) {
|
|
4756
|
+
thenables.push(s.rotateTo(...arguments));
|
|
4757
|
+
}
|
|
4758
|
+
return {
|
|
4759
|
+
then: (onFulfilled) => {
|
|
4760
|
+
let pending = thenables.length;
|
|
4761
|
+
if (!pending) return onFulfilled(true);
|
|
4762
|
+
let allReached = true;
|
|
4763
|
+
for (let t of thenables) {
|
|
4764
|
+
t.then((reached) => {
|
|
4765
|
+
if (!reached) allReached = false;
|
|
4766
|
+
if (--pending === 0) onFulfilled(allReached);
|
|
4767
|
+
});
|
|
4768
|
+
}
|
|
4769
|
+
}
|
|
4770
|
+
};
|
|
4771
|
+
}
|
|
4772
|
+
|
|
4773
|
+
rotate(angle, speed) {
|
|
4774
|
+
const thenables = [];
|
|
4775
|
+
for (let s of this) {
|
|
4776
|
+
thenables.push(s.rotate(...arguments));
|
|
4777
|
+
}
|
|
4778
|
+
return {
|
|
4779
|
+
then: (onFulfilled) => {
|
|
4780
|
+
let pending = thenables.length;
|
|
4781
|
+
if (!pending) return onFulfilled(true);
|
|
4782
|
+
let allReached = true;
|
|
4783
|
+
for (let t of thenables) {
|
|
4784
|
+
t.then((reached) => {
|
|
4785
|
+
if (!reached) allReached = false;
|
|
4786
|
+
if (--pending === 0) onFulfilled(allReached);
|
|
4787
|
+
});
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
};
|
|
4791
|
+
}
|
|
4792
|
+
|
|
4793
|
+
rotateMinTo(angle, speed) {
|
|
4794
|
+
const thenables = [];
|
|
4795
|
+
for (let s of this) {
|
|
4796
|
+
thenables.push(s.rotateMinTo(...arguments));
|
|
4797
|
+
}
|
|
4798
|
+
return {
|
|
4799
|
+
then: (onFulfilled) => {
|
|
4800
|
+
let pending = thenables.length;
|
|
4801
|
+
if (!pending) return onFulfilled(true);
|
|
4802
|
+
let allReached = true;
|
|
4803
|
+
for (let t of thenables) {
|
|
4804
|
+
t.then((reached) => {
|
|
4805
|
+
if (!reached) allReached = false;
|
|
4806
|
+
if (--pending === 0) onFulfilled(allReached);
|
|
4807
|
+
});
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
};
|
|
4811
|
+
}
|
|
4812
|
+
|
|
4813
|
+
transformTowards(x, y, rotation, tracking = 0.1) {
|
|
4814
|
+
if (x === undefined) return;
|
|
4815
|
+
|
|
4816
|
+
if (typeof x != 'number') {
|
|
4817
|
+
let pos = x;
|
|
4818
|
+
if (pos == $.mouse && !$.mouse.isActive) return;
|
|
4819
|
+
tracking = rotation ?? tracking;
|
|
4820
|
+
rotation = y;
|
|
4821
|
+
y = pos.y;
|
|
4822
|
+
x = pos.x;
|
|
4823
|
+
}
|
|
4824
|
+
|
|
4825
|
+
this._resetCentroid();
|
|
4826
|
+
|
|
4827
|
+
for (let s of this) {
|
|
4828
|
+
if (s.distCentroid === undefined) {
|
|
4829
|
+
this._resetDistancesFromCentroid();
|
|
4830
|
+
}
|
|
4831
|
+
s.transformTowards(s.distCentroid.x + x, s.distCentroid.y + y, rotation, tracking);
|
|
4832
|
+
}
|
|
4833
|
+
}
|
|
4834
|
+
|
|
4835
|
+
moveTo(x, y, speed) {
|
|
4836
|
+
if (x === undefined && (y === undefined || y === null)) return;
|
|
4837
|
+
|
|
4838
|
+
let nullX = x === null || x === undefined;
|
|
4839
|
+
let nullY = y === null || y === undefined;
|
|
4840
|
+
|
|
4841
|
+
if (!nullX && typeof x != 'number') {
|
|
4842
|
+
let pos = x;
|
|
4843
|
+
if (pos == $.mouse && !$.mouse.isActive) return;
|
|
4844
|
+
speed = y;
|
|
4845
|
+
y = pos.y;
|
|
4846
|
+
x = pos.x;
|
|
4847
|
+
nullX = nullY = false;
|
|
4848
|
+
}
|
|
4849
|
+
|
|
4850
|
+
this._resetCentroid();
|
|
4851
|
+
this._resetDistancesFromCentroid();
|
|
4852
|
+
|
|
4853
|
+
const thenables = [];
|
|
4854
|
+
for (let s of this) {
|
|
4855
|
+
const tx = nullX ? null : s.distCentroid.x + x;
|
|
4856
|
+
const ty = nullY ? null : s.distCentroid.y + y;
|
|
4857
|
+
thenables.push(s.moveTo(tx, ty, speed));
|
|
4858
|
+
}
|
|
4859
|
+
|
|
4860
|
+
return {
|
|
4861
|
+
then: (onFulfilled) => {
|
|
4862
|
+
let pending = thenables.length;
|
|
4863
|
+
if (!pending) return onFulfilled(true);
|
|
4864
|
+
let allReached = true;
|
|
4865
|
+
for (let t of thenables) {
|
|
4866
|
+
t.then((reached) => {
|
|
4867
|
+
if (!reached) allReached = false;
|
|
4868
|
+
if (--pending === 0) onFulfilled(allReached);
|
|
4869
|
+
});
|
|
4870
|
+
}
|
|
4871
|
+
}
|
|
4872
|
+
};
|
|
4873
|
+
}
|
|
4874
|
+
|
|
4512
4875
|
toString() {
|
|
4513
4876
|
return 'g' + this.idNum;
|
|
4514
4877
|
}
|
|
@@ -4787,7 +5150,7 @@ async function q5playPreSetup(q) {
|
|
|
4787
5150
|
$.Visuals.prototype.addAni = $.Group.prototype.addAni = $.Sprite.prototype.addAni;
|
|
4788
5151
|
$.Visuals.prototype.addAnis = $.Group.prototype.addAnis = $.Sprite.prototype.addAnis;
|
|
4789
5152
|
|
|
4790
|
-
class
|
|
5153
|
+
class CastInfo {
|
|
4791
5154
|
constructor(sprite, px, py, nx, ny, fraction, maxDistance) {
|
|
4792
5155
|
this.sprite = sprite;
|
|
4793
5156
|
this._px = px;
|
|
@@ -5017,6 +5380,7 @@ async function q5playPreSetup(q) {
|
|
|
5017
5380
|
}
|
|
5018
5381
|
set meterSize(val) {
|
|
5019
5382
|
meterSize = val;
|
|
5383
|
+
visualSlop = meterSize / 120;
|
|
5020
5384
|
}
|
|
5021
5385
|
|
|
5022
5386
|
get profile() {
|
|
@@ -5132,6 +5496,8 @@ async function q5playPreSetup(q) {
|
|
|
5132
5496
|
|
|
5133
5497
|
this.physicsTime += timeStep;
|
|
5134
5498
|
|
|
5499
|
+
this._sync();
|
|
5500
|
+
|
|
5135
5501
|
let sprites = Object.values($.q5play.sprites);
|
|
5136
5502
|
let groups = Object.values($.q5play.groups);
|
|
5137
5503
|
|
|
@@ -5148,6 +5514,71 @@ async function q5playPreSetup(q) {
|
|
|
5148
5514
|
if (this.autoStep) this.autoStep = null;
|
|
5149
5515
|
}
|
|
5150
5516
|
|
|
5517
|
+
_sync() {
|
|
5518
|
+
jointStack = [];
|
|
5519
|
+
shapeStack = [];
|
|
5520
|
+
|
|
5521
|
+
b2World_Draw(wID, drawCmds.GetDebugDraw());
|
|
5522
|
+
|
|
5523
|
+
let cmdPtr = drawCmds.GetCommandsData(),
|
|
5524
|
+
cmdSize = drawCmds.GetCommandsSize(),
|
|
5525
|
+
cmdStride = drawCmds.GetCommandStride(),
|
|
5526
|
+
offset = cmdPtr,
|
|
5527
|
+
renderJointForces = $.q5play.renderJointForces,
|
|
5528
|
+
s;
|
|
5529
|
+
|
|
5530
|
+
for (let i = 0; i < cmdSize; i++, offset += cmdStride) {
|
|
5531
|
+
// workaround that unpacks data from
|
|
5532
|
+
// the shape material's customColor
|
|
5533
|
+
const customColor = Box2D.HEAPU32[(offset + 4) >> 2],
|
|
5534
|
+
uid = customColor & 0xffffff,
|
|
5535
|
+
isSensor = (customColor >>> 25) & 0x1,
|
|
5536
|
+
isFirstShape = (customColor >>> 26) & 0x1;
|
|
5537
|
+
|
|
5538
|
+
s = $.q5play.sprites[uid];
|
|
5539
|
+
|
|
5540
|
+
let type = Box2D.HEAPU8[offset];
|
|
5541
|
+
|
|
5542
|
+
if (type == 7) {
|
|
5543
|
+
continue;
|
|
5544
|
+
}
|
|
5545
|
+
|
|
5546
|
+
let vertexCount = Box2D.HEAPU16[(offset + 8) >> 1];
|
|
5547
|
+
|
|
5548
|
+
let dataLen = 4;
|
|
5549
|
+
if (type == 1) dataLen = 5 + vertexCount * 2;
|
|
5550
|
+
else if (type == 3 || type == 4) dataLen = 5;
|
|
5551
|
+
let data = new Float32Array(Box2D.HEAPU8.buffer, offset + 12, dataLen);
|
|
5552
|
+
|
|
5553
|
+
if (!s) {
|
|
5554
|
+
if (type == 0 && renderJointForces) jointStack.push(data);
|
|
5555
|
+
continue;
|
|
5556
|
+
}
|
|
5557
|
+
|
|
5558
|
+
// always keep position in sync since it has a low performance cost
|
|
5559
|
+
// unless the shape is a chain
|
|
5560
|
+
if (type < 4 || (type == 4 && !s._hasCapsuleChain)) {
|
|
5561
|
+
s._posX = data[0] * meterSize;
|
|
5562
|
+
s._posY = data[1] * meterSize;
|
|
5563
|
+
}
|
|
5564
|
+
|
|
5565
|
+
s._velSynced = false;
|
|
5566
|
+
s._vel._magCached = false;
|
|
5567
|
+
|
|
5568
|
+
if (!s.visible) {
|
|
5569
|
+
continue;
|
|
5570
|
+
}
|
|
5571
|
+
|
|
5572
|
+
if (s._hasImagery || s._userDefinedDraw) {
|
|
5573
|
+
s._rotation = Math.atan2(data[2], data[3]) * RADTODEG;
|
|
5574
|
+
}
|
|
5575
|
+
|
|
5576
|
+
if (s.debug || (!s._hasImagery && !s._userDefinedDraw)) {
|
|
5577
|
+
shapeStack.push({ type, sprite: s, isSensor, isFirstShape, data, vertexCount });
|
|
5578
|
+
}
|
|
5579
|
+
}
|
|
5580
|
+
}
|
|
5581
|
+
|
|
5151
5582
|
get realTime() {
|
|
5152
5583
|
return $.millis() / 1000;
|
|
5153
5584
|
}
|
|
@@ -5183,7 +5614,7 @@ async function q5playPreSetup(q) {
|
|
|
5183
5614
|
if (shape?.sprite) {
|
|
5184
5615
|
const s = shape.sprite;
|
|
5185
5616
|
|
|
5186
|
-
s.
|
|
5617
|
+
s.cast = new CastInfo(
|
|
5187
5618
|
s,
|
|
5188
5619
|
castResult.point.x,
|
|
5189
5620
|
castResult.point.y,
|
|
@@ -5200,7 +5631,54 @@ async function q5playPreSetup(q) {
|
|
|
5200
5631
|
});
|
|
5201
5632
|
|
|
5202
5633
|
// sort results by distance from start
|
|
5203
|
-
results.sort((a, b) => a.
|
|
5634
|
+
results.sort((a, b) => a.cast.distance - b.cast.distance);
|
|
5635
|
+
return results;
|
|
5636
|
+
}
|
|
5637
|
+
|
|
5638
|
+
circleCast(startPos, endPos, radius) {
|
|
5639
|
+
let sprites = this.circleCastAll(startPos, endPos, radius, () => true);
|
|
5640
|
+
return sprites[0];
|
|
5641
|
+
}
|
|
5642
|
+
|
|
5643
|
+
circleCastAll(startPos, endPos, radius, limiter) {
|
|
5644
|
+
const startX = startPos.x ?? startPos[0];
|
|
5645
|
+
const startY = startPos.y ?? startPos[1];
|
|
5646
|
+
const endX = endPos.x ?? endPos[0];
|
|
5647
|
+
const endY = endPos.y ?? endPos[1];
|
|
5648
|
+
|
|
5649
|
+
const maxDistance = Math.sqrt((endX - startX) ** 2 + (endY - startY) ** 2);
|
|
5650
|
+
|
|
5651
|
+
const center = scaleTo(startX, startY);
|
|
5652
|
+
const proxy = b2MakeProxy(center, 1, radius / meterSize);
|
|
5653
|
+
const translation = scaleTo(endX - startX, endY - startY);
|
|
5654
|
+
|
|
5655
|
+
const results = [];
|
|
5656
|
+
|
|
5657
|
+
b2World_CastShape(wID, proxy, translation, NULL_FILTER, (castResult) => {
|
|
5658
|
+
const shape = shapeDict[castResult.shapeId.index1];
|
|
5659
|
+
if (shape?.sprite) {
|
|
5660
|
+
const s = shape.sprite;
|
|
5661
|
+
|
|
5662
|
+
s.cast = new CastInfo(
|
|
5663
|
+
s,
|
|
5664
|
+
castResult.point.x,
|
|
5665
|
+
castResult.point.y,
|
|
5666
|
+
castResult.normal.x,
|
|
5667
|
+
castResult.normal.y,
|
|
5668
|
+
castResult.fraction,
|
|
5669
|
+
maxDistance
|
|
5670
|
+
);
|
|
5671
|
+
results.push(s);
|
|
5672
|
+
|
|
5673
|
+
if (limiter && limiter(s)) return 0; // stop cast
|
|
5674
|
+
}
|
|
5675
|
+
return 1; // continue to collect all hits
|
|
5676
|
+
});
|
|
5677
|
+
|
|
5678
|
+
proxy.delete();
|
|
5679
|
+
|
|
5680
|
+
// sort results by distance from start
|
|
5681
|
+
results.sort((a, b) => a.cast.distance - b.cast.distance);
|
|
5204
5682
|
return results;
|
|
5205
5683
|
}
|
|
5206
5684
|
};
|
|
@@ -5228,7 +5706,7 @@ async function q5playPreSetup(q) {
|
|
|
5228
5706
|
}
|
|
5229
5707
|
|
|
5230
5708
|
get pos() {
|
|
5231
|
-
return this._pos;
|
|
5709
|
+
return { x: this._pos.x, y: this._pos.y };
|
|
5232
5710
|
}
|
|
5233
5711
|
set pos(val) {
|
|
5234
5712
|
this.x = val[0] ?? val.x;
|
|
@@ -5497,7 +5975,7 @@ async function q5playPreSetup(q) {
|
|
|
5497
5975
|
}
|
|
5498
5976
|
|
|
5499
5977
|
_draw(xA, yA, xB, yB) {
|
|
5500
|
-
if (xB) $.line(xA, yA, xB, yB);
|
|
5978
|
+
if (xB || yB) $.line(xA, yA, xB, yB);
|
|
5501
5979
|
else $.point(xA, yA);
|
|
5502
5980
|
}
|
|
5503
5981
|
|
|
@@ -6045,20 +6523,6 @@ async function q5playPreSetup(q) {
|
|
|
6045
6523
|
Box2D.b2PrismaticJoint_EnableLimit(this.jID, true);
|
|
6046
6524
|
}
|
|
6047
6525
|
|
|
6048
|
-
set limits(val) {
|
|
6049
|
-
let min, max;
|
|
6050
|
-
if (typeof val == 'number') {
|
|
6051
|
-
val /= 2;
|
|
6052
|
-
min = -val;
|
|
6053
|
-
max = val;
|
|
6054
|
-
} else {
|
|
6055
|
-
min = val[0];
|
|
6056
|
-
max = val[1];
|
|
6057
|
-
}
|
|
6058
|
-
Box2D.b2PrismaticJoint_SetLimits(this.jID, min / meterSize, max / meterSize);
|
|
6059
|
-
Box2D.b2PrismaticJoint_EnableLimit(this.jID, true);
|
|
6060
|
-
}
|
|
6061
|
-
|
|
6062
6526
|
get springEnabled() {
|
|
6063
6527
|
return Box2D.b2PrismaticJoint_IsSpringEnabled(this.jID);
|
|
6064
6528
|
}
|
|
@@ -6910,7 +7374,7 @@ async function q5playPreSetup(q) {
|
|
|
6910
7374
|
}
|
|
6911
7375
|
|
|
6912
7376
|
get pos() {
|
|
6913
|
-
return this.
|
|
7377
|
+
return { x: this.x, y: this.y };
|
|
6914
7378
|
}
|
|
6915
7379
|
get position() {
|
|
6916
7380
|
return this._pos;
|
|
@@ -7823,71 +8287,6 @@ async function q5playPreSetup(q) {
|
|
|
7823
8287
|
jointStack = [],
|
|
7824
8288
|
shapeStack = [];
|
|
7825
8289
|
|
|
7826
|
-
$._syncWorld = () => {
|
|
7827
|
-
jointStack = [];
|
|
7828
|
-
shapeStack = [];
|
|
7829
|
-
|
|
7830
|
-
b2World_Draw(wID, drawCmds.GetDebugDraw());
|
|
7831
|
-
|
|
7832
|
-
let cmdPtr = drawCmds.GetCommandsData(),
|
|
7833
|
-
cmdSize = drawCmds.GetCommandsSize(),
|
|
7834
|
-
cmdStride = drawCmds.GetCommandStride(),
|
|
7835
|
-
offset = cmdPtr,
|
|
7836
|
-
renderJointForces = $.q5play.renderJointForces,
|
|
7837
|
-
s;
|
|
7838
|
-
|
|
7839
|
-
for (let i = 0; i < cmdSize; i++, offset += cmdStride) {
|
|
7840
|
-
// workaround that unpacks data from
|
|
7841
|
-
// the shape material's customColor
|
|
7842
|
-
const customColor = Box2D.HEAPU32[(offset + 4) >> 2],
|
|
7843
|
-
uid = customColor & 0xffffff,
|
|
7844
|
-
isSensor = (customColor >>> 25) & 0x1,
|
|
7845
|
-
isFirstShape = (customColor >>> 26) & 0x1;
|
|
7846
|
-
|
|
7847
|
-
s = $.q5play.sprites[uid];
|
|
7848
|
-
|
|
7849
|
-
let type = Box2D.HEAPU8[offset];
|
|
7850
|
-
|
|
7851
|
-
if (type == 7) {
|
|
7852
|
-
continue;
|
|
7853
|
-
}
|
|
7854
|
-
|
|
7855
|
-
let vertexCount = Box2D.HEAPU16[(offset + 8) >> 1];
|
|
7856
|
-
|
|
7857
|
-
let dataLen = 4;
|
|
7858
|
-
if (type == 1) dataLen = 5 + vertexCount * 2;
|
|
7859
|
-
else if (type == 3 || type == 4) dataLen = 5;
|
|
7860
|
-
let data = new Float32Array(Box2D.HEAPU8.buffer, offset + 12, dataLen);
|
|
7861
|
-
|
|
7862
|
-
if (!s) {
|
|
7863
|
-
if (type == 0 && renderJointForces) jointStack.push(data);
|
|
7864
|
-
continue;
|
|
7865
|
-
}
|
|
7866
|
-
|
|
7867
|
-
// always keep position in sync since it has a low performance cost
|
|
7868
|
-
// unless the shape is a chain
|
|
7869
|
-
if (type < 4 || (type == 4 && !s._hasCapsuleChain)) {
|
|
7870
|
-
s._posX = data[0] * meterSize;
|
|
7871
|
-
s._posY = data[1] * meterSize;
|
|
7872
|
-
}
|
|
7873
|
-
|
|
7874
|
-
s._velSynced = false;
|
|
7875
|
-
s._vel._magCached = false;
|
|
7876
|
-
|
|
7877
|
-
if (!s.visible) {
|
|
7878
|
-
continue;
|
|
7879
|
-
}
|
|
7880
|
-
|
|
7881
|
-
if (s._hasImagery || s._userDefinedDraw) {
|
|
7882
|
-
s._rotation = Math.atan2(data[2], data[3]) * RADTODEG;
|
|
7883
|
-
}
|
|
7884
|
-
|
|
7885
|
-
if (s.debug || (!s._hasImagery && !s._userDefinedDraw)) {
|
|
7886
|
-
shapeStack.push({ type, sprite: s, isSensor, isFirstShape, data, vertexCount });
|
|
7887
|
-
}
|
|
7888
|
-
}
|
|
7889
|
-
};
|
|
7890
|
-
|
|
7891
8290
|
const colorMax = $._colorFormat,
|
|
7892
8291
|
debugGreen = $.color(0, colorMax, 0, colorMax * 0.9),
|
|
7893
8292
|
debugGreenFill = $.color(0, colorMax, 0, colorMax * 0.1),
|
|
@@ -8186,7 +8585,6 @@ function q5playUpdate() {
|
|
|
8186
8585
|
|
|
8187
8586
|
if ($.world.autoStep && $.world.timeScale > 0) {
|
|
8188
8587
|
$.world.physicsUpdate();
|
|
8189
|
-
$._syncWorld();
|
|
8190
8588
|
}
|
|
8191
8589
|
$.world.autoStep ??= true;
|
|
8192
8590
|
|
|
@@ -8357,8 +8755,7 @@ attractTo -> es:atraerA
|
|
|
8357
8755
|
repelFrom -> es:repelerDe
|
|
8358
8756
|
applyTorque -> es:aplicarTorque
|
|
8359
8757
|
angleTo -> es:ánguloHacia
|
|
8360
|
-
|
|
8361
|
-
angleToFace -> es:ánguloParaMirar
|
|
8758
|
+
angleDistTo -> es:distÁnguloHacia
|
|
8362
8759
|
setSpeedAndDirection -> es:establecerVelocidadYDirección
|
|
8363
8760
|
scaleBy -> es:escalarPor
|
|
8364
8761
|
resetMass -> es:reiniciarMasa
|