q5play 4.0.7 → 4.1.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/README.md +1 -1
- package/package.json +3 -3
- package/q5play.d.ts +163 -66
- package/q5play.js +217 -129
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Visit [q5play.org][]! 🎮🧑💻
|
|
4
4
|
|
|
5
|
-
[q5play][] is a beginner friendly
|
|
5
|
+
[q5play][] is a beginner friendly and powerful game engine for the web.
|
|
6
6
|
|
|
7
7
|
It uses [q5.js WebGPU][] for graphics and [Box2D v3 WASM][] for physics.
|
|
8
8
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "q5play",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"author": "quinton-ashley",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
|
-
"description": "A web-based game engine that uses q5.js WebGPU for graphics and Box2D v3 WASM for physics.",
|
|
6
|
+
"description": "A beginner friendly, web-based game engine that uses q5.js WebGPU for graphics and Box2D v3 WASM for physics.",
|
|
7
7
|
"main": "q5play.js",
|
|
8
8
|
"types": "q5play.d.ts",
|
|
9
9
|
"homepage": "https://q5play.org",
|
|
@@ -25,6 +25,6 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"box2d3-wasm": "^5.2.0",
|
|
28
|
-
"q5": "^4.
|
|
28
|
+
"q5": "^4.6.3"
|
|
29
29
|
}
|
|
30
30
|
}
|
package/q5play.d.ts
CHANGED
|
@@ -33,10 +33,10 @@ declare global {
|
|
|
33
33
|
* Friendly rounding makes some Sprite getters return nice rounded numbers
|
|
34
34
|
* if a decimal value is within linear slop range (+/-0.005) or
|
|
35
35
|
* angular slop range (+/-0.000582 radians) of a whole number.
|
|
36
|
-
*
|
|
36
|
+
*
|
|
37
37
|
* This is because Box2D physics calculations can result in
|
|
38
38
|
* floating point drift, which beginners wouldn't expect.
|
|
39
|
-
*
|
|
39
|
+
*
|
|
40
40
|
* Setting to false can slightly improve performance.
|
|
41
41
|
* @default true
|
|
42
42
|
*/
|
|
@@ -70,6 +70,11 @@ declare global {
|
|
|
70
70
|
* @default false
|
|
71
71
|
*/
|
|
72
72
|
renderStats: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* "Made with q5play" [splash screen](https://en.wikipedia.org/wiki/Splash_screen) displayed during
|
|
75
|
+
* initial page load by default.
|
|
76
|
+
*/
|
|
77
|
+
splashScreen(): Promise<void>;
|
|
73
78
|
/**
|
|
74
79
|
* Runs automatically before each draw function call.
|
|
75
80
|
*/
|
|
@@ -81,6 +86,16 @@ declare global {
|
|
|
81
86
|
}
|
|
82
87
|
const q5play: Q5Play;
|
|
83
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Box2D v3 ported to WASM is the physics engine that
|
|
91
|
+
* q5play uses for its physics simulation.
|
|
92
|
+
*
|
|
93
|
+
* This variable enables direct access to the Box2D API for
|
|
94
|
+
* advanced users who want to do things that aren't wrapped
|
|
95
|
+
* by q5play.
|
|
96
|
+
*/
|
|
97
|
+
const Box2D: any;
|
|
98
|
+
|
|
84
99
|
/**
|
|
85
100
|
* Don't create Shapes directly; use `sprite.addCollider()`
|
|
86
101
|
* or `sprite.addSensor()` instead.
|
|
@@ -107,7 +122,7 @@ declare global {
|
|
|
107
122
|
}
|
|
108
123
|
|
|
109
124
|
/**
|
|
110
|
-
* Sensor are added to a sprite's physics body to detect overlaps
|
|
125
|
+
* Sensor are added to a sprite's physics body to detect overlaps
|
|
111
126
|
* without causing physical collisions.
|
|
112
127
|
*
|
|
113
128
|
* Don't create Sensors directly; use Sprite.addSensor() instead.
|
|
@@ -191,7 +206,7 @@ declare global {
|
|
|
191
206
|
* - "!" plays it backwards
|
|
192
207
|
* - ">" or "<" horizontally flips it
|
|
193
208
|
* - "^" vertically flips it
|
|
194
|
-
*
|
|
209
|
+
*
|
|
195
210
|
* @param name the name of the animation to play
|
|
196
211
|
* @returns A promise that fulfills when the animation completes
|
|
197
212
|
*/
|
|
@@ -1209,7 +1224,7 @@ declare global {
|
|
|
1209
1224
|
}
|
|
1210
1225
|
/**
|
|
1211
1226
|
* Stores animations.
|
|
1212
|
-
*
|
|
1227
|
+
*
|
|
1213
1228
|
* Used internally to create `sprite.anis` and `group.anis`.
|
|
1214
1229
|
*
|
|
1215
1230
|
* In instances of this class, the keys are animation names,
|
|
@@ -1224,7 +1239,7 @@ declare global {
|
|
|
1224
1239
|
/**
|
|
1225
1240
|
* Cuts sprite sheet frames into separate images, instead of rendering
|
|
1226
1241
|
* sections of the sprite sheet.
|
|
1227
|
-
*
|
|
1242
|
+
*
|
|
1228
1243
|
* Avoids edge bleeding artifacts caused by rotation and scaling,
|
|
1229
1244
|
* but uses more memory and may cause longer load times.
|
|
1230
1245
|
*/
|
|
@@ -2081,7 +2096,7 @@ declare global {
|
|
|
2081
2096
|
get reactionTorque(): any;
|
|
2082
2097
|
/**
|
|
2083
2098
|
* The amount of force that must be applied to the joint before it breaks.
|
|
2084
|
-
*
|
|
2099
|
+
*
|
|
2085
2100
|
* Setting the threshold too high leads to instability. Use
|
|
2086
2101
|
* `sprite.addCollider` to simulate unbreakable bonds between shapes.
|
|
2087
2102
|
* @default 500
|
|
@@ -2100,7 +2115,7 @@ declare global {
|
|
|
2100
2115
|
/**
|
|
2101
2116
|
* This function is run when the joint's reaction force exceeds the
|
|
2102
2117
|
* force threshold or its reaction torque exceeds the torque threshold.
|
|
2103
|
-
*
|
|
2118
|
+
*
|
|
2104
2119
|
* By default, the sprites' speed and rotation speed are set to 0
|
|
2105
2120
|
* and the joint is deleted, simulating a break.
|
|
2106
2121
|
*/
|
|
@@ -2142,7 +2157,7 @@ declare global {
|
|
|
2142
2157
|
get currentLength(): number;
|
|
2143
2158
|
/**
|
|
2144
2159
|
* The target length of the joint between the two joint anchors.
|
|
2145
|
-
*
|
|
2160
|
+
*
|
|
2146
2161
|
* It's set to the current distance between the two sprites
|
|
2147
2162
|
* when the joint is created.
|
|
2148
2163
|
*/
|
|
@@ -2164,9 +2179,10 @@ declare global {
|
|
|
2164
2179
|
*/
|
|
2165
2180
|
get maxLength(): number;
|
|
2166
2181
|
/**
|
|
2167
|
-
* Accepts
|
|
2182
|
+
* Accepts a number to set a symmetric range
|
|
2183
|
+
* or an array with the minimum and maximum length limits.
|
|
2168
2184
|
*/
|
|
2169
|
-
set range(val: [number, number]);
|
|
2185
|
+
set range(val: [number, number] | number);
|
|
2170
2186
|
/**
|
|
2171
2187
|
* Whether spring behavior is enabled for the joint.
|
|
2172
2188
|
* @default true
|
|
@@ -2184,7 +2200,7 @@ declare global {
|
|
|
2184
2200
|
/**
|
|
2185
2201
|
* Damping is a 0-1 ratio describing how quickly the joint loses
|
|
2186
2202
|
* vibrational energy.
|
|
2187
|
-
*
|
|
2203
|
+
*
|
|
2188
2204
|
* 0.0 means no damping, 1.0 means critical damping, which will stop
|
|
2189
2205
|
* the joint from vibrating at all.
|
|
2190
2206
|
*
|
|
@@ -2238,39 +2254,37 @@ declare global {
|
|
|
2238
2254
|
get angle(): number;
|
|
2239
2255
|
set angle(val: number);
|
|
2240
2256
|
/**
|
|
2241
|
-
*
|
|
2242
|
-
*
|
|
2243
|
-
*/
|
|
2244
|
-
get currentLength(): number;
|
|
2245
|
-
/**
|
|
2246
|
-
* The target length of the joint between the two joint anchors.
|
|
2247
|
-
*
|
|
2248
|
-
* It's set to the current distance between the two sprites
|
|
2249
|
-
* when the joint is created.
|
|
2250
|
-
*/
|
|
2251
|
-
get length(): number;
|
|
2252
|
-
set length(val: number);
|
|
2253
|
-
/**
|
|
2254
|
-
* Whether the joint's length limits are enabled.
|
|
2255
|
-
* When enabled a min/max length range constrains the joint.
|
|
2257
|
+
* Whether the joint's suspension limits are enabled.
|
|
2258
|
+
* When enabled a min/max distance from resting constrains the joint.
|
|
2256
2259
|
* @default false
|
|
2257
2260
|
*/
|
|
2258
2261
|
get limitsEnabled(): boolean;
|
|
2259
2262
|
set limitsEnabled(val: boolean);
|
|
2260
2263
|
/**
|
|
2261
|
-
* The minimum
|
|
2264
|
+
* The minimum distance the wheel's suspension can contract
|
|
2265
|
+
* from 0, which represents the resting position,
|
|
2266
|
+
* when limits are enabled.
|
|
2267
|
+
* @readonly
|
|
2262
2268
|
*/
|
|
2263
|
-
get
|
|
2269
|
+
get lowerLimit(): number;
|
|
2264
2270
|
/**
|
|
2265
|
-
* The maximum
|
|
2271
|
+
* The maximum distance the wheel's suspension can extend
|
|
2272
|
+
* from 0, which represents the resting position,
|
|
2273
|
+
* when limits are enabled.
|
|
2274
|
+
* @readonly
|
|
2266
2275
|
*/
|
|
2267
|
-
get
|
|
2276
|
+
get upperLimit(): number;
|
|
2268
2277
|
/**
|
|
2269
|
-
*
|
|
2278
|
+
* The distance the wheel's suspension can contract or extend
|
|
2279
|
+
* from 0, which represents the resting position.
|
|
2280
|
+
*
|
|
2281
|
+
* Accepts a number to set a symmetric range
|
|
2282
|
+
* or an array with the minimum and maximum length limits.
|
|
2270
2283
|
*/
|
|
2271
|
-
set range(val: [number, number]);
|
|
2284
|
+
set range(val: [number, number] | number);
|
|
2272
2285
|
/**
|
|
2273
|
-
* Whether
|
|
2286
|
+
* Whether the wheel joint has suspension,
|
|
2287
|
+
* which can make it ride smoother over bumps.
|
|
2274
2288
|
* @default true
|
|
2275
2289
|
*/
|
|
2276
2290
|
get springEnabled(): boolean;
|
|
@@ -2325,7 +2339,7 @@ declare global {
|
|
|
2325
2339
|
* Hinge joints attach two sprites together at a pivot point,
|
|
2326
2340
|
* constraining them to rotate around this point, like a hinge.
|
|
2327
2341
|
*
|
|
2328
|
-
*
|
|
2342
|
+
* Also known as a revolute joint.
|
|
2329
2343
|
*
|
|
2330
2344
|
* @param spriteA
|
|
2331
2345
|
* @param spriteB
|
|
@@ -2349,13 +2363,57 @@ declare global {
|
|
|
2349
2363
|
*/
|
|
2350
2364
|
get maxAngle(): number;
|
|
2351
2365
|
/**
|
|
2352
|
-
* Accepts
|
|
2366
|
+
* Accepts a number to set a symmetric range
|
|
2367
|
+
* or an array with the lower and upper limits of rotation.
|
|
2353
2368
|
*/
|
|
2354
|
-
set range(val: [number, number]);
|
|
2369
|
+
set range(val: [number, number] | number);
|
|
2355
2370
|
/**
|
|
2356
|
-
*
|
|
2371
|
+
* The joint's current angle of rotation.
|
|
2372
|
+
* @readonly
|
|
2357
2373
|
*/
|
|
2358
2374
|
get angle(): number;
|
|
2375
|
+
/**
|
|
2376
|
+
* Whether spring behavior is enabled.
|
|
2377
|
+
* @default false
|
|
2378
|
+
*/
|
|
2379
|
+
get springEnabled(): boolean;
|
|
2380
|
+
set springEnabled(val: boolean);
|
|
2381
|
+
/**
|
|
2382
|
+
* The springiness of the joint, a 0-1 ratio.
|
|
2383
|
+
*
|
|
2384
|
+
* 0 is rigid, 0.5 is bouncy, 1 is loose.
|
|
2385
|
+
* @default 0
|
|
2386
|
+
*/
|
|
2387
|
+
get springiness(): number;
|
|
2388
|
+
set springiness(val: number);
|
|
2389
|
+
/**
|
|
2390
|
+
* Damping ratio, 0-1. Higher values reduce oscillation faster.
|
|
2391
|
+
* @default 0
|
|
2392
|
+
*/
|
|
2393
|
+
get damping(): number;
|
|
2394
|
+
set damping(val: number);
|
|
2395
|
+
/**
|
|
2396
|
+
* Whether the joint's motor is enabled.
|
|
2397
|
+
* @default false
|
|
2398
|
+
*/
|
|
2399
|
+
get motorEnabled(): boolean;
|
|
2400
|
+
set motorEnabled(val: boolean);
|
|
2401
|
+
/**
|
|
2402
|
+
* Motor speed.
|
|
2403
|
+
* @default 0
|
|
2404
|
+
*/
|
|
2405
|
+
get speed(): number;
|
|
2406
|
+
set speed(val: number);
|
|
2407
|
+
/**
|
|
2408
|
+
* Maximum torque the motor can apply.
|
|
2409
|
+
*/
|
|
2410
|
+
get maxPower(): number;
|
|
2411
|
+
set maxPower(val: number);
|
|
2412
|
+
/**
|
|
2413
|
+
* The current torque being applied by the motor.
|
|
2414
|
+
* @readonly
|
|
2415
|
+
*/
|
|
2416
|
+
get power(): number;
|
|
2359
2417
|
}
|
|
2360
2418
|
|
|
2361
2419
|
class SliderJoint extends Joint {
|
|
@@ -2370,44 +2428,83 @@ declare global {
|
|
|
2370
2428
|
*/
|
|
2371
2429
|
constructor(spriteA: Sprite, spriteB: Sprite);
|
|
2372
2430
|
/**
|
|
2373
|
-
* The
|
|
2374
|
-
*
|
|
2375
|
-
* @default undefined
|
|
2431
|
+
* The current displacement of spriteB along the slide axis.
|
|
2432
|
+
* @readonly
|
|
2376
2433
|
*/
|
|
2377
|
-
get
|
|
2378
|
-
set range(val: number);
|
|
2434
|
+
get translation(): number;
|
|
2379
2435
|
/**
|
|
2380
|
-
*
|
|
2381
|
-
*
|
|
2382
|
-
* @default undefined
|
|
2436
|
+
* Whether the joint's translation limits are enabled.
|
|
2437
|
+
* @default false
|
|
2383
2438
|
*/
|
|
2384
|
-
get
|
|
2385
|
-
set
|
|
2439
|
+
get limitsEnabled(): boolean;
|
|
2440
|
+
set limitsEnabled(val: boolean);
|
|
2386
2441
|
/**
|
|
2387
|
-
* The mathematical lower
|
|
2388
|
-
*
|
|
2389
|
-
* @default undefined
|
|
2442
|
+
* The mathematical lower limit of translation.
|
|
2443
|
+
* @readonly
|
|
2390
2444
|
*/
|
|
2391
2445
|
get lowerLimit(): number;
|
|
2392
|
-
set lowerLimit(val: number);
|
|
2393
|
-
}
|
|
2394
|
-
|
|
2395
|
-
class RopeJoint extends Joint {
|
|
2396
2446
|
/**
|
|
2397
|
-
*
|
|
2398
|
-
*
|
|
2399
|
-
|
|
2400
|
-
|
|
2447
|
+
* The mathematical upper limit of translation.
|
|
2448
|
+
* @readonly
|
|
2449
|
+
*/
|
|
2450
|
+
get upperLimit(): number;
|
|
2451
|
+
/**
|
|
2452
|
+
* Accepts a number to set a symmetric range
|
|
2453
|
+
* or an array with the lower and upper translation limits.
|
|
2454
|
+
*/
|
|
2455
|
+
set range(val: [number, number] | number);
|
|
2456
|
+
/**
|
|
2457
|
+
* Alias for range.
|
|
2458
|
+
*/
|
|
2459
|
+
set limits(val: [number, number] | number);
|
|
2460
|
+
/**
|
|
2461
|
+
* Whether spring behavior is enabled.
|
|
2462
|
+
* @default false
|
|
2463
|
+
*/
|
|
2464
|
+
get springEnabled(): boolean;
|
|
2465
|
+
set springEnabled(val: boolean);
|
|
2466
|
+
/**
|
|
2467
|
+
* The springiness of the joint, a 0-1 ratio.
|
|
2401
2468
|
*
|
|
2402
|
-
*
|
|
2403
|
-
* @
|
|
2469
|
+
* 0 is rigid, 0.5 is bouncy, 1 is loose.
|
|
2470
|
+
* @default 0
|
|
2404
2471
|
*/
|
|
2405
|
-
|
|
2472
|
+
get springiness(): number;
|
|
2473
|
+
set springiness(val: number);
|
|
2406
2474
|
/**
|
|
2407
|
-
*
|
|
2475
|
+
* Damping ratio, 0-1. Higher values reduce oscillation faster.
|
|
2476
|
+
* @default 0
|
|
2408
2477
|
*/
|
|
2409
|
-
get
|
|
2410
|
-
set
|
|
2478
|
+
get damping(): number;
|
|
2479
|
+
set damping(val: number);
|
|
2480
|
+
/**
|
|
2481
|
+
* Whether the joint's motor is enabled.
|
|
2482
|
+
* @default true
|
|
2483
|
+
*/
|
|
2484
|
+
get motorEnabled(): boolean;
|
|
2485
|
+
set motorEnabled(val: boolean);
|
|
2486
|
+
/**
|
|
2487
|
+
* Motor speed.
|
|
2488
|
+
* @default 0
|
|
2489
|
+
*/
|
|
2490
|
+
get speed(): number;
|
|
2491
|
+
set speed(val: number);
|
|
2492
|
+
/**
|
|
2493
|
+
* Maximum force the motor can apply.
|
|
2494
|
+
* @default 10
|
|
2495
|
+
*/
|
|
2496
|
+
get maxPower(): number;
|
|
2497
|
+
set maxPower(val: number);
|
|
2498
|
+
/**
|
|
2499
|
+
* The current motor force being applied.
|
|
2500
|
+
* @readonly
|
|
2501
|
+
*/
|
|
2502
|
+
get power(): number;
|
|
2503
|
+
/**
|
|
2504
|
+
* The current sliding speed of the joint.
|
|
2505
|
+
* @readonly
|
|
2506
|
+
*/
|
|
2507
|
+
get energy(): number;
|
|
2411
2508
|
}
|
|
2412
2509
|
|
|
2413
2510
|
class GrabberJoint extends Joint {
|
|
@@ -2431,7 +2528,7 @@ declare global {
|
|
|
2431
2528
|
set target(pos: any);
|
|
2432
2529
|
/**
|
|
2433
2530
|
* The maximum spring force that the joint can exert on the sprite.
|
|
2434
|
-
*
|
|
2531
|
+
*
|
|
2435
2532
|
* By default it's 500 * the sprite's mass.
|
|
2436
2533
|
*/
|
|
2437
2534
|
get maxForce(): number;
|
package/q5play.js
CHANGED
|
@@ -12,13 +12,12 @@
|
|
|
12
12
|
* |__/ |__/ \______/
|
|
13
13
|
*
|
|
14
14
|
* @package q5play
|
|
15
|
-
* @version 4.
|
|
15
|
+
* @version 4.1
|
|
16
16
|
* @author quinton-ashley
|
|
17
17
|
* @website https://q5play.org
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
let q5play_version = '4.0';
|
|
20
|
+
let q5play_version = '4.1';
|
|
22
21
|
|
|
23
22
|
if (typeof globalThis.Q5 == 'undefined') {
|
|
24
23
|
console.error('q5play requires q5.js to be loaded first. Visit https://q5js.org to learn more.');
|
|
@@ -324,6 +323,43 @@ async function q5playPreSetup(q) {
|
|
|
324
323
|
set friendlyRounding(val) {
|
|
325
324
|
friendlyRounding = val;
|
|
326
325
|
}
|
|
326
|
+
|
|
327
|
+
async splashScreen() {
|
|
328
|
+
if (document.getElementById('made-with-q5play')) return;
|
|
329
|
+
if (!using_p5v2) $._incrementPreload();
|
|
330
|
+
let d = document.createElement('div');
|
|
331
|
+
d.id = 'made-with-q5play';
|
|
332
|
+
d.style =
|
|
333
|
+
'position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: 1000; background-color: black;';
|
|
334
|
+
let logo = document.createElement('img');
|
|
335
|
+
logo.style = `position: absolute; top: 50%; left: 50%; width: 80vmin; height: 40vmin; margin-left: -40vmin; margin-top: -20vmin; z-index: 1001; opacity: 1; scale: 1; transition: scale 1.5s, opacity 0.4s ease-in-out;`;
|
|
336
|
+
logo.onerror = () => {
|
|
337
|
+
logo.style.imageRendering = 'pixelated';
|
|
338
|
+
logo.src = `data:image/png;base64,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`;
|
|
339
|
+
};
|
|
340
|
+
let src = window._q5play_intro_image;
|
|
341
|
+
if (src == '' || src?.includes('made_with_q5play')) {
|
|
342
|
+
if (src.includes('bit.') || src.includes('pixel')) {
|
|
343
|
+
logo.style.imageRendering = 'pixelated';
|
|
344
|
+
}
|
|
345
|
+
logo.src = src;
|
|
346
|
+
} else {
|
|
347
|
+
logo.src = 'https://q5play.org/assets/made_with_q5play.webp';
|
|
348
|
+
}
|
|
349
|
+
await new Promise((r) => (logo.onload = r));
|
|
350
|
+
d.append(logo);
|
|
351
|
+
document.body.append(d);
|
|
352
|
+
await $.delay();
|
|
353
|
+
logo.offsetHeight; // trigger css reflow
|
|
354
|
+
logo.style.scale = 1.2;
|
|
355
|
+
await $.delay(1100);
|
|
356
|
+
logo.style.opacity = 0;
|
|
357
|
+
await $.delay(400);
|
|
358
|
+
d.style.display = 'none';
|
|
359
|
+
d.remove();
|
|
360
|
+
document.getElementById('made-with-q5play')?.remove();
|
|
361
|
+
if (!using_p5v2) $._decrementPreload();
|
|
362
|
+
}
|
|
327
363
|
};
|
|
328
364
|
|
|
329
365
|
$.q5play = new $.Q5Play();
|
|
@@ -334,7 +370,8 @@ async function q5playPreSetup(q) {
|
|
|
334
370
|
|
|
335
371
|
// in q5play the default angle mode is degrees
|
|
336
372
|
const DEGREES = $.DEGREES,
|
|
337
|
-
DEGTORAD = Math.PI / 180
|
|
373
|
+
DEGTORAD = Math.PI / 180,
|
|
374
|
+
RADTODEG = 180 / Math.PI;
|
|
338
375
|
$.angleMode(DEGREES);
|
|
339
376
|
|
|
340
377
|
// in q5play the default color mode is float RGB
|
|
@@ -1323,7 +1360,7 @@ async function q5playPreSetup(q) {
|
|
|
1323
1360
|
if (typeof a3 == 'string') {
|
|
1324
1361
|
rr = a4 || 0;
|
|
1325
1362
|
path = getRegularPolygon(a2 - rr, a3);
|
|
1326
|
-
} else if (
|
|
1363
|
+
} else if (typeof a2 == 'object') {
|
|
1327
1364
|
path = a2;
|
|
1328
1365
|
rr = a3;
|
|
1329
1366
|
} else {
|
|
@@ -1334,6 +1371,12 @@ async function q5playPreSetup(q) {
|
|
|
1334
1371
|
rr ??= 0;
|
|
1335
1372
|
|
|
1336
1373
|
if (path) {
|
|
1374
|
+
if (!Array.isArray(path)) {
|
|
1375
|
+
let tmp = path.absoluteAngles;
|
|
1376
|
+
path = path.array;
|
|
1377
|
+
path.absoluteAngles = tmp;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1337
1380
|
let start,
|
|
1338
1381
|
vecs = [{ x: 0, y: 0 }],
|
|
1339
1382
|
isLoop = (vecs.isLoop = false);
|
|
@@ -4741,6 +4784,27 @@ async function q5playPreSetup(q) {
|
|
|
4741
4784
|
$.Visuals.prototype.addAni = $.Group.prototype.addAni = $.Sprite.prototype.addAni;
|
|
4742
4785
|
$.Visuals.prototype.addAnis = $.Group.prototype.addAnis = $.Sprite.prototype.addAnis;
|
|
4743
4786
|
|
|
4787
|
+
class RayInfo {
|
|
4788
|
+
constructor(sprite, px, py, nx, ny, fraction, maxDistance) {
|
|
4789
|
+
this.sprite = sprite;
|
|
4790
|
+
this._px = px;
|
|
4791
|
+
this._py = py;
|
|
4792
|
+
this._nx = nx;
|
|
4793
|
+
this._ny = ny;
|
|
4794
|
+
this.distance = fraction * maxDistance;
|
|
4795
|
+
}
|
|
4796
|
+
|
|
4797
|
+
get intersect() {
|
|
4798
|
+
if (!this._intersect) this._intersect = scaleFrom(this._px, this._py);
|
|
4799
|
+
return this._intersect;
|
|
4800
|
+
}
|
|
4801
|
+
|
|
4802
|
+
get incidence() {
|
|
4803
|
+
if (this._incidence === undefined) this._incidence = $.atan2(this._ny, this._nx);
|
|
4804
|
+
return this._incidence;
|
|
4805
|
+
}
|
|
4806
|
+
}
|
|
4807
|
+
|
|
4744
4808
|
$.World = class {
|
|
4745
4809
|
constructor() {
|
|
4746
4810
|
this.mod = {};
|
|
@@ -5097,57 +5161,56 @@ async function q5playPreSetup(q) {
|
|
|
5097
5161
|
}
|
|
5098
5162
|
|
|
5099
5163
|
rayCastAll(startPos, direction, maxDistance, limiter) {
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5164
|
+
const startX = startPos.x ?? startPos[0];
|
|
5165
|
+
const startY = startPos.y ?? startPos[1];
|
|
5166
|
+
|
|
5167
|
+
let endX, endY;
|
|
5168
|
+
if (typeof direction == 'number') {
|
|
5169
|
+
maxDistance ??= 10000;
|
|
5170
|
+
endX = startX + maxDistance * $.cos(direction);
|
|
5171
|
+
endY = startY + maxDistance * $.sin(direction);
|
|
5107
5172
|
} else {
|
|
5108
|
-
|
|
5109
|
-
limiter
|
|
5110
|
-
|
|
5173
|
+
const endPos = direction;
|
|
5174
|
+
limiter = maxDistance;
|
|
5175
|
+
endX = endPos.x ?? endPos[0];
|
|
5176
|
+
endY = endPos.y ?? endPos[1];
|
|
5111
5177
|
}
|
|
5112
5178
|
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
super.rayCast(start, end, function (fixture, point, normal, fraction) {
|
|
5117
|
-
let sprite = fixture.getBody().sprite;
|
|
5179
|
+
const origin = scaleTo(startX, startY);
|
|
5180
|
+
const translation = scaleTo(endX - startX, endY - startY);
|
|
5118
5181
|
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
results.push({
|
|
5123
|
-
sprite,
|
|
5124
|
-
// point,
|
|
5125
|
-
// normal,
|
|
5126
|
-
fraction
|
|
5127
|
-
});
|
|
5182
|
+
const filter = new b2QueryFilter();
|
|
5183
|
+
filter.categoryBits = 0xffffffff;
|
|
5184
|
+
filter.maskBits = 0xffffffff;
|
|
5128
5185
|
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5186
|
+
const results = [];
|
|
5187
|
+
|
|
5188
|
+
b2World_CastRay(wID, origin, translation, filter, (castResult) => {
|
|
5189
|
+
const shape = shapeDict[castResult.shapeId.index1];
|
|
5190
|
+
if (shape?.sprite) {
|
|
5191
|
+
const s = shape.sprite;
|
|
5192
|
+
s.ray = new RayInfo(
|
|
5193
|
+
s,
|
|
5194
|
+
castResult.point.x,
|
|
5195
|
+
castResult.point.y,
|
|
5196
|
+
castResult.normal.x,
|
|
5197
|
+
castResult.normal.y,
|
|
5198
|
+
castResult.fraction,
|
|
5199
|
+
maxDistance
|
|
5200
|
+
);
|
|
5201
|
+
results.push(s);
|
|
5135
5202
|
}
|
|
5136
|
-
return 1; //
|
|
5203
|
+
return 1; // continue to collect all hits
|
|
5137
5204
|
});
|
|
5138
5205
|
|
|
5139
|
-
|
|
5140
|
-
results.sort((a, b) => a.fraction - b.fraction);
|
|
5206
|
+
filter.delete();
|
|
5141
5207
|
|
|
5142
|
-
|
|
5208
|
+
// sort results by distance from start
|
|
5209
|
+
results.sort((a, b) => a.ray.distance - b.ray.distance);
|
|
5143
5210
|
|
|
5144
|
-
|
|
5145
|
-
if (res.fraction <= maxFraction) {
|
|
5146
|
-
sprites.push(res.sprite);
|
|
5147
|
-
}
|
|
5148
|
-
}
|
|
5211
|
+
if (!limiter) return results;
|
|
5149
5212
|
|
|
5150
|
-
return
|
|
5213
|
+
return results.filter(limiter);
|
|
5151
5214
|
}
|
|
5152
5215
|
};
|
|
5153
5216
|
|
|
@@ -5332,7 +5395,7 @@ async function q5playPreSetup(q) {
|
|
|
5332
5395
|
this.isActive = cameraOn = false;
|
|
5333
5396
|
}
|
|
5334
5397
|
}
|
|
5335
|
-
}; //end camera class
|
|
5398
|
+
}; // end camera class
|
|
5336
5399
|
|
|
5337
5400
|
$.Joint = class {
|
|
5338
5401
|
constructor(spriteA, spriteB, type) {
|
|
@@ -5348,6 +5411,7 @@ async function q5playPreSetup(q) {
|
|
|
5348
5411
|
this.type = type ??= 'glue';
|
|
5349
5412
|
this.visible = true;
|
|
5350
5413
|
this.deleted = false;
|
|
5414
|
+
this._springiness = 0;
|
|
5351
5415
|
|
|
5352
5416
|
if (!a._shapes.length) a.addDefaultSensors();
|
|
5353
5417
|
if (!b._shapes.length) b.addDefaultSensors();
|
|
@@ -5356,8 +5420,6 @@ async function q5playPreSetup(q) {
|
|
|
5356
5420
|
|
|
5357
5421
|
let _this = this;
|
|
5358
5422
|
|
|
5359
|
-
// if (type != 'slider' && type != 'rope') {
|
|
5360
|
-
|
|
5361
5423
|
if (type != 'wheel') {
|
|
5362
5424
|
this._offsetA = {};
|
|
5363
5425
|
|
|
@@ -5536,6 +5598,7 @@ async function q5playPreSetup(q) {
|
|
|
5536
5598
|
|
|
5537
5599
|
_springMap(val) {
|
|
5538
5600
|
if (val > 0) {
|
|
5601
|
+
this._springiness = val;
|
|
5539
5602
|
if (val < 0.1) {
|
|
5540
5603
|
val = $.map(val, 0, 0.1, 30, 4);
|
|
5541
5604
|
} else if (val < 0.5) {
|
|
@@ -5572,7 +5635,7 @@ async function q5playPreSetup(q) {
|
|
|
5572
5635
|
}
|
|
5573
5636
|
|
|
5574
5637
|
get springiness() {
|
|
5575
|
-
return
|
|
5638
|
+
return this._springiness;
|
|
5576
5639
|
}
|
|
5577
5640
|
set springiness(val) {
|
|
5578
5641
|
val = this._springMap(val);
|
|
@@ -5648,7 +5711,7 @@ async function q5playPreSetup(q) {
|
|
|
5648
5711
|
}
|
|
5649
5712
|
|
|
5650
5713
|
get springiness() {
|
|
5651
|
-
return
|
|
5714
|
+
return this._springiness;
|
|
5652
5715
|
}
|
|
5653
5716
|
set springiness(val) {
|
|
5654
5717
|
val = this._springMap(val);
|
|
@@ -5692,15 +5755,20 @@ async function q5playPreSetup(q) {
|
|
|
5692
5755
|
constructor(spriteA, spriteB) {
|
|
5693
5756
|
super(spriteA, spriteB, 'wheel');
|
|
5694
5757
|
|
|
5758
|
+
this._angle = $._angleMode == DEGREES ? 90 : Math.PI / 2;
|
|
5759
|
+
this._motorEnabled = false;
|
|
5760
|
+
|
|
5695
5761
|
let j = this._init(b2DefaultWheelJointDef(wID));
|
|
5696
5762
|
j.enableSpring = true;
|
|
5697
5763
|
j.hertz = 4;
|
|
5698
5764
|
j.dampingRatio = 0.7;
|
|
5699
|
-
j.enableMotor =
|
|
5765
|
+
j.enableMotor = false; // neutral by default
|
|
5700
5766
|
j.maxMotorTorque = 1000;
|
|
5701
5767
|
|
|
5702
5768
|
this.jID = b2CreateWheelJoint(wID, j);
|
|
5703
5769
|
jointDict[this.jID.index1] = this;
|
|
5770
|
+
|
|
5771
|
+
this._springiness = 0.1;
|
|
5704
5772
|
}
|
|
5705
5773
|
|
|
5706
5774
|
_init(j) {
|
|
@@ -5710,11 +5778,12 @@ async function q5playPreSetup(q) {
|
|
|
5710
5778
|
j.base.bodyIdA = a.bdID;
|
|
5711
5779
|
j.base.bodyIdB = b.bdID;
|
|
5712
5780
|
|
|
5713
|
-
|
|
5781
|
+
let rad = this._angle;
|
|
5782
|
+
if ($._angleMode == DEGREES) rad *= DEGTORAD;
|
|
5783
|
+
j.base.localFrameA.q.SetAngle(rad);
|
|
5714
5784
|
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
// j.base.localFrameA.q = b2InvMulRot(qA, qB);
|
|
5785
|
+
let pivot = scaleTo(b.x, b.y);
|
|
5786
|
+
j.base.localFrameA.p = b2Body_GetLocalPoint(a.bdID, pivot);
|
|
5718
5787
|
|
|
5719
5788
|
return j;
|
|
5720
5789
|
}
|
|
@@ -5727,9 +5796,12 @@ async function q5playPreSetup(q) {
|
|
|
5727
5796
|
set angle(val) {
|
|
5728
5797
|
if (val == this._angle) return;
|
|
5729
5798
|
this._angle = val;
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5799
|
+
let rad = $._angleMode == DEGREES ? val * DEGTORAD : val;
|
|
5800
|
+
|
|
5801
|
+
let t = b2Joint_GetLocalFrameA(this.jID);
|
|
5802
|
+
t.q.SetAngle(rad);
|
|
5803
|
+
b2Joint_SetLocalFrameA(this.jID, t);
|
|
5804
|
+
b2Joint_WakeBodies(this.jID);
|
|
5733
5805
|
}
|
|
5734
5806
|
|
|
5735
5807
|
get springEnabled() {
|
|
@@ -5740,7 +5812,7 @@ async function q5playPreSetup(q) {
|
|
|
5740
5812
|
}
|
|
5741
5813
|
|
|
5742
5814
|
get springiness() {
|
|
5743
|
-
return
|
|
5815
|
+
return this._springiness;
|
|
5744
5816
|
}
|
|
5745
5817
|
set springiness(val) {
|
|
5746
5818
|
val = this._springMap(val);
|
|
@@ -5762,15 +5834,24 @@ async function q5playPreSetup(q) {
|
|
|
5762
5834
|
}
|
|
5763
5835
|
|
|
5764
5836
|
get lowerLimit() {
|
|
5765
|
-
return Box2D.b2WheelJoint_GetLowerLimit(this.jID);
|
|
5837
|
+
return Box2D.b2WheelJoint_GetLowerLimit(this.jID) * meterSize;
|
|
5766
5838
|
}
|
|
5767
5839
|
|
|
5768
5840
|
get upperLimit() {
|
|
5769
|
-
return Box2D.b2WheelJoint_GetUpperLimit(this.jID);
|
|
5841
|
+
return Box2D.b2WheelJoint_GetUpperLimit(this.jID) * meterSize;
|
|
5770
5842
|
}
|
|
5771
5843
|
|
|
5772
|
-
set
|
|
5773
|
-
|
|
5844
|
+
set range(val) {
|
|
5845
|
+
let min, max;
|
|
5846
|
+
if (typeof val == 'number') {
|
|
5847
|
+
val /= 2;
|
|
5848
|
+
min = -val;
|
|
5849
|
+
max = val;
|
|
5850
|
+
} else {
|
|
5851
|
+
min = val[0];
|
|
5852
|
+
max = val[1];
|
|
5853
|
+
}
|
|
5854
|
+
Box2D.b2WheelJoint_SetLimits(this.jID, min / meterSize, max / meterSize);
|
|
5774
5855
|
}
|
|
5775
5856
|
|
|
5776
5857
|
get motorEnabled() {
|
|
@@ -5778,13 +5859,16 @@ async function q5playPreSetup(q) {
|
|
|
5778
5859
|
}
|
|
5779
5860
|
set motorEnabled(val) {
|
|
5780
5861
|
Box2D.b2WheelJoint_EnableMotor(this.jID, val);
|
|
5862
|
+
this._motorEnabled = val;
|
|
5781
5863
|
}
|
|
5782
5864
|
|
|
5783
5865
|
get maxPower() {
|
|
5784
5866
|
return Box2D.b2WheelJoint_GetMaxMotorTorque(this.jID);
|
|
5785
5867
|
}
|
|
5786
5868
|
set maxPower(val) {
|
|
5869
|
+
if (val > 0 && !this._motorEnabled) this.motorEnabled = true;
|
|
5787
5870
|
Box2D.b2WheelJoint_SetMaxMotorTorque(this.jID, val);
|
|
5871
|
+
b2Joint_WakeBodies(this.jID);
|
|
5788
5872
|
}
|
|
5789
5873
|
|
|
5790
5874
|
get power() {
|
|
@@ -5792,10 +5876,14 @@ async function q5playPreSetup(q) {
|
|
|
5792
5876
|
}
|
|
5793
5877
|
|
|
5794
5878
|
get speed() {
|
|
5879
|
+
// if in neutral, return the wheel's angular velocity
|
|
5880
|
+
if (!this._motorEnabled) return this.spriteB.rotationSpeed;
|
|
5795
5881
|
return Box2D.b2WheelJoint_GetMotorSpeed(this.jID);
|
|
5796
5882
|
}
|
|
5797
5883
|
set speed(val) {
|
|
5884
|
+
if (!this._motorEnabled) this.motorEnabled = true;
|
|
5798
5885
|
Box2D.b2WheelJoint_SetMotorSpeed(this.jID, val);
|
|
5886
|
+
b2Joint_WakeBodies(this.jID);
|
|
5799
5887
|
}
|
|
5800
5888
|
};
|
|
5801
5889
|
|
|
@@ -5823,7 +5911,7 @@ async function q5playPreSetup(q) {
|
|
|
5823
5911
|
}
|
|
5824
5912
|
|
|
5825
5913
|
get springiness() {
|
|
5826
|
-
return
|
|
5914
|
+
return this._springiness;
|
|
5827
5915
|
}
|
|
5828
5916
|
set springiness(val) {
|
|
5829
5917
|
val = this._springMap(val);
|
|
@@ -5863,8 +5951,8 @@ async function q5playPreSetup(q) {
|
|
|
5863
5951
|
max = val[1];
|
|
5864
5952
|
}
|
|
5865
5953
|
if ($._angleMode == DEGREES) {
|
|
5866
|
-
min *=
|
|
5867
|
-
max *=
|
|
5954
|
+
min *= DEGTORAD;
|
|
5955
|
+
max *= DEGTORAD;
|
|
5868
5956
|
}
|
|
5869
5957
|
Box2D.b2RevoluteJoint_SetLimits(this.jID, min, max);
|
|
5870
5958
|
}
|
|
@@ -5893,8 +5981,6 @@ async function q5playPreSetup(q) {
|
|
|
5893
5981
|
set maxPower(val) {
|
|
5894
5982
|
Box2D.b2RevoluteJoint_SetMaxMotorTorque(this.jID, val);
|
|
5895
5983
|
}
|
|
5896
|
-
|
|
5897
|
-
_display() {}
|
|
5898
5984
|
};
|
|
5899
5985
|
|
|
5900
5986
|
$.SliderJoint = class extends $.Joint {
|
|
@@ -5902,17 +5988,39 @@ async function q5playPreSetup(q) {
|
|
|
5902
5988
|
super(spriteA, spriteB, 'slider');
|
|
5903
5989
|
|
|
5904
5990
|
let j = this._init(b2DefaultPrismaticJointDef());
|
|
5905
|
-
j.enableLimit =
|
|
5906
|
-
j.lowerTranslation = -1;
|
|
5907
|
-
j.upperTranslation = 1;
|
|
5991
|
+
j.enableLimit = false;
|
|
5908
5992
|
j.enableMotor = true;
|
|
5909
|
-
j.maxMotorForce =
|
|
5993
|
+
j.maxMotorForce = 10;
|
|
5910
5994
|
j.motorSpeed = 0;
|
|
5911
5995
|
|
|
5912
5996
|
this.jID = b2CreatePrismaticJoint(wID, j);
|
|
5913
5997
|
jointDict[this.jID.index1] = this;
|
|
5914
5998
|
}
|
|
5915
5999
|
|
|
6000
|
+
_init(j) {
|
|
6001
|
+
let a = this.spriteA,
|
|
6002
|
+
b = this.spriteB;
|
|
6003
|
+
|
|
6004
|
+
j.base.bodyIdA = a.bdID;
|
|
6005
|
+
j.base.bodyIdB = b.bdID;
|
|
6006
|
+
|
|
6007
|
+
// set the anchor at sprite A's position in B's local frame
|
|
6008
|
+
j.base.localFrameB.p = b2Body_GetLocalPoint(b.bdID, scaleTo(a.x, a.y));
|
|
6009
|
+
|
|
6010
|
+
// align the slide axis with the vector from A to B
|
|
6011
|
+
let dx = b.x - a.x;
|
|
6012
|
+
let dy = b.y - a.y;
|
|
6013
|
+
let len = Math.sqrt(dx * dx + dy * dy);
|
|
6014
|
+
let angle = len > 0 ? Math.atan2(dy, dx) : 0;
|
|
6015
|
+
|
|
6016
|
+
let qA = b2Body_GetRotation(a.bdID);
|
|
6017
|
+
let qB = b2Body_GetRotation(b.bdID);
|
|
6018
|
+
j.base.localFrameA.q.SetAngle(angle - qA.GetAngle());
|
|
6019
|
+
j.base.localFrameB.q.SetAngle(angle - qB.GetAngle());
|
|
6020
|
+
|
|
6021
|
+
return j;
|
|
6022
|
+
}
|
|
6023
|
+
|
|
5916
6024
|
get translation() {
|
|
5917
6025
|
return Box2D.b2PrismaticJoint_GetTranslation(this.jID) * meterSize;
|
|
5918
6026
|
}
|
|
@@ -5943,6 +6051,21 @@ async function q5playPreSetup(q) {
|
|
|
5943
6051
|
max = val[1];
|
|
5944
6052
|
}
|
|
5945
6053
|
Box2D.b2PrismaticJoint_SetLimits(this.jID, min / meterSize, max / meterSize);
|
|
6054
|
+
Box2D.b2PrismaticJoint_EnableLimit(this.jID, true);
|
|
6055
|
+
}
|
|
6056
|
+
|
|
6057
|
+
set limits(val) {
|
|
6058
|
+
let min, max;
|
|
6059
|
+
if (typeof val == 'number') {
|
|
6060
|
+
val /= 2;
|
|
6061
|
+
min = -val;
|
|
6062
|
+
max = val;
|
|
6063
|
+
} else {
|
|
6064
|
+
min = val[0];
|
|
6065
|
+
max = val[1];
|
|
6066
|
+
}
|
|
6067
|
+
Box2D.b2PrismaticJoint_SetLimits(this.jID, min / meterSize, max / meterSize);
|
|
6068
|
+
Box2D.b2PrismaticJoint_EnableLimit(this.jID, true);
|
|
5946
6069
|
}
|
|
5947
6070
|
|
|
5948
6071
|
get springEnabled() {
|
|
@@ -5953,10 +6076,10 @@ async function q5playPreSetup(q) {
|
|
|
5953
6076
|
}
|
|
5954
6077
|
|
|
5955
6078
|
get springiness() {
|
|
5956
|
-
return
|
|
6079
|
+
return this._springiness;
|
|
5957
6080
|
}
|
|
5958
6081
|
set springiness(val) {
|
|
5959
|
-
val = this._springMap
|
|
6082
|
+
val = this._springMap(val);
|
|
5960
6083
|
Box2D.b2PrismaticJoint_SetSpringHertz(this.jID, val);
|
|
5961
6084
|
}
|
|
5962
6085
|
|
|
@@ -5979,6 +6102,7 @@ async function q5playPreSetup(q) {
|
|
|
5979
6102
|
}
|
|
5980
6103
|
set speed(val) {
|
|
5981
6104
|
Box2D.b2PrismaticJoint_SetMotorSpeed(this.jID, val);
|
|
6105
|
+
b2Joint_WakeBodies(this.jID);
|
|
5982
6106
|
}
|
|
5983
6107
|
|
|
5984
6108
|
get maxPower() {
|
|
@@ -5992,14 +6116,14 @@ async function q5playPreSetup(q) {
|
|
|
5992
6116
|
return Box2D.b2PrismaticJoint_GetMotorForce(this.jID);
|
|
5993
6117
|
}
|
|
5994
6118
|
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
6119
|
+
get energy() {
|
|
6120
|
+
return Box2D.b2PrismaticJoint_GetSpeed(this.jID);
|
|
6121
|
+
}
|
|
5998
6122
|
};
|
|
5999
6123
|
|
|
6000
6124
|
$.GrabberJoint = class extends $.Joint {
|
|
6001
|
-
constructor(
|
|
6002
|
-
sprite ??=
|
|
6125
|
+
constructor(grabPoint, sprite) {
|
|
6126
|
+
sprite ??= grabPoint;
|
|
6003
6127
|
super(sprite, sprite, 'grabber');
|
|
6004
6128
|
|
|
6005
6129
|
let bd = b2DefaultBodyDef();
|
|
@@ -6025,11 +6149,11 @@ async function q5playPreSetup(q) {
|
|
|
6025
6149
|
|
|
6026
6150
|
this.jID = b2CreateMotorJoint(wID, j);
|
|
6027
6151
|
|
|
6028
|
-
let offX = sprite.x - (
|
|
6029
|
-
offY = sprite.y - (
|
|
6152
|
+
let offX = sprite.x - (grabPoint[0] || grabPoint.x),
|
|
6153
|
+
offY = sprite.y - (grabPoint[1] || grabPoint.y);
|
|
6030
6154
|
if (!isSlop(offX) || !isSlop(offY)) {
|
|
6031
6155
|
this._setOffsetB(-offX, -offY);
|
|
6032
|
-
this.target =
|
|
6156
|
+
this.target = grabPoint;
|
|
6033
6157
|
}
|
|
6034
6158
|
|
|
6035
6159
|
this.sprite = sprite;
|
|
@@ -6352,23 +6476,23 @@ async function q5playPreSetup(q) {
|
|
|
6352
6476
|
if (!ani.looping) return;
|
|
6353
6477
|
}
|
|
6354
6478
|
|
|
6355
|
-
//going to target frame up
|
|
6479
|
+
// going to target frame up
|
|
6356
6480
|
if (ani.targetFrame > ani._frame && ani.targetFrame !== -1) {
|
|
6357
6481
|
ani._frame++;
|
|
6358
6482
|
}
|
|
6359
|
-
//going to target frame down
|
|
6483
|
+
// going to target frame down
|
|
6360
6484
|
else if (ani.targetFrame < ani._frame && ani.targetFrame !== -1) {
|
|
6361
6485
|
ani._frame--;
|
|
6362
6486
|
} else if (ani.targetFrame === ani._frame && ani.targetFrame !== -1) {
|
|
6363
6487
|
ani.playing = false;
|
|
6364
6488
|
} else if (ani.looping) {
|
|
6365
|
-
//advance frame
|
|
6366
|
-
//if next frame is too high
|
|
6489
|
+
// advance frame
|
|
6490
|
+
// if next frame is too high
|
|
6367
6491
|
if (ani._frame >= ani.lastFrame) {
|
|
6368
6492
|
ani._frame = 0;
|
|
6369
6493
|
} else ani._frame++;
|
|
6370
6494
|
} else {
|
|
6371
|
-
//if next frame is too high
|
|
6495
|
+
// if next frame is too high
|
|
6372
6496
|
if (ani._frame < ani.lastFrame) ani._frame++;
|
|
6373
6497
|
}
|
|
6374
6498
|
} else {
|
|
@@ -6384,42 +6508,6 @@ async function q5playPreSetup(q) {
|
|
|
6384
6508
|
});
|
|
6385
6509
|
};
|
|
6386
6510
|
|
|
6387
|
-
async function playIntro() {
|
|
6388
|
-
if (document.getElementById('made-with-q5play')) return;
|
|
6389
|
-
if (!using_p5v2) $._incrementPreload();
|
|
6390
|
-
let d = document.createElement('div');
|
|
6391
|
-
d.id = 'made-with-q5play';
|
|
6392
|
-
d.style = 'position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: 1000; background-color: black;';
|
|
6393
|
-
let logo = document.createElement('img');
|
|
6394
|
-
logo.style = `position: absolute; top: 50%; left: 50%; width: 80vmin; height: 40vmin; margin-left: -40vmin; margin-top: -20vmin; z-index: 1001; opacity: 1; scale: 1; transition: scale 1.5s, opacity 0.4s ease-in-out;`;
|
|
6395
|
-
logo.onerror = () => {
|
|
6396
|
-
logo.style.imageRendering = 'pixelated';
|
|
6397
|
-
logo.src = `data:image/png;base64,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`;
|
|
6398
|
-
};
|
|
6399
|
-
let src = window._q5play_intro_image;
|
|
6400
|
-
if (src == '' || src?.includes('made_with_q5play')) {
|
|
6401
|
-
if (src.includes('bit.') || src.includes('pixel')) {
|
|
6402
|
-
logo.style.imageRendering = 'pixelated';
|
|
6403
|
-
}
|
|
6404
|
-
logo.src = src;
|
|
6405
|
-
} else {
|
|
6406
|
-
logo.src = 'https://q5play.org/assets/made_with_q5play.webp';
|
|
6407
|
-
}
|
|
6408
|
-
await new Promise((r) => (logo.onload = r));
|
|
6409
|
-
d.append(logo);
|
|
6410
|
-
document.body.append(d);
|
|
6411
|
-
await $.delay();
|
|
6412
|
-
logo.offsetHeight; // trigger css reflow
|
|
6413
|
-
logo.style.scale = 1.2;
|
|
6414
|
-
await $.delay(1100);
|
|
6415
|
-
logo.style.opacity = 0;
|
|
6416
|
-
await $.delay(400);
|
|
6417
|
-
d.style.display = 'none';
|
|
6418
|
-
d.remove();
|
|
6419
|
-
document.getElementById('made-with-q5play')?.remove();
|
|
6420
|
-
if (!using_p5v2) $._decrementPreload();
|
|
6421
|
-
}
|
|
6422
|
-
|
|
6423
6511
|
if (window.location) {
|
|
6424
6512
|
let lh = location.hostname;
|
|
6425
6513
|
switch (lh) {
|
|
@@ -6452,7 +6540,7 @@ async function q5playPreSetup(q) {
|
|
|
6452
6540
|
) {
|
|
6453
6541
|
break;
|
|
6454
6542
|
}
|
|
6455
|
-
|
|
6543
|
+
$.q5play.splashScreen();
|
|
6456
6544
|
}
|
|
6457
6545
|
}
|
|
6458
6546
|
|
|
@@ -7767,10 +7855,6 @@ async function q5playPreSetup(q) {
|
|
|
7767
7855
|
|
|
7768
7856
|
s = $.q5play.sprites[uid];
|
|
7769
7857
|
|
|
7770
|
-
if (s && !s.visible) {
|
|
7771
|
-
continue;
|
|
7772
|
-
}
|
|
7773
|
-
|
|
7774
7858
|
let type = Box2D.HEAPU8[offset];
|
|
7775
7859
|
|
|
7776
7860
|
if (type == 7) {
|
|
@@ -7799,8 +7883,12 @@ async function q5playPreSetup(q) {
|
|
|
7799
7883
|
s._velSynced = false;
|
|
7800
7884
|
s._vel._magCached = false;
|
|
7801
7885
|
|
|
7886
|
+
if (!s.visible) {
|
|
7887
|
+
continue;
|
|
7888
|
+
}
|
|
7889
|
+
|
|
7802
7890
|
if (s._hasImagery || s._userDefinedDraw) {
|
|
7803
|
-
s._rotation = Math.atan2(data[2], data[3]) *
|
|
7891
|
+
s._rotation = Math.atan2(data[2], data[3]) * RADTODEG;
|
|
7804
7892
|
}
|
|
7805
7893
|
|
|
7806
7894
|
if (s.debug || (!s._hasImagery && !s._userDefinedDraw)) {
|