q5play 4.0.8 → 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 +130 -98
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();
|
|
@@ -1005,7 +1041,6 @@ async function q5playPreSetup(q) {
|
|
|
1005
1041
|
if (!group.visualOnly) {
|
|
1006
1042
|
const def = new b2DefaultBodyDef();
|
|
1007
1043
|
def.type = bodyTypes[this._phys];
|
|
1008
|
-
def.allowFastRotation = true;
|
|
1009
1044
|
this.bdID = b2CreateBody(wID, def);
|
|
1010
1045
|
this._physicsEnabled = true;
|
|
1011
1046
|
|
|
@@ -1325,7 +1360,7 @@ async function q5playPreSetup(q) {
|
|
|
1325
1360
|
if (typeof a3 == 'string') {
|
|
1326
1361
|
rr = a4 || 0;
|
|
1327
1362
|
path = getRegularPolygon(a2 - rr, a3);
|
|
1328
|
-
} else if (
|
|
1363
|
+
} else if (typeof a2 == 'object') {
|
|
1329
1364
|
path = a2;
|
|
1330
1365
|
rr = a3;
|
|
1331
1366
|
} else {
|
|
@@ -1336,6 +1371,12 @@ async function q5playPreSetup(q) {
|
|
|
1336
1371
|
rr ??= 0;
|
|
1337
1372
|
|
|
1338
1373
|
if (path) {
|
|
1374
|
+
if (!Array.isArray(path)) {
|
|
1375
|
+
let tmp = path.absoluteAngles;
|
|
1376
|
+
path = path.array;
|
|
1377
|
+
path.absoluteAngles = tmp;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1339
1380
|
let start,
|
|
1340
1381
|
vecs = [{ x: 0, y: 0 }],
|
|
1341
1382
|
isLoop = (vecs.isLoop = false);
|
|
@@ -4743,6 +4784,27 @@ async function q5playPreSetup(q) {
|
|
|
4743
4784
|
$.Visuals.prototype.addAni = $.Group.prototype.addAni = $.Sprite.prototype.addAni;
|
|
4744
4785
|
$.Visuals.prototype.addAnis = $.Group.prototype.addAnis = $.Sprite.prototype.addAnis;
|
|
4745
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
|
+
|
|
4746
4808
|
$.World = class {
|
|
4747
4809
|
constructor() {
|
|
4748
4810
|
this.mod = {};
|
|
@@ -5099,57 +5161,56 @@ async function q5playPreSetup(q) {
|
|
|
5099
5161
|
}
|
|
5100
5162
|
|
|
5101
5163
|
rayCastAll(startPos, direction, maxDistance, limiter) {
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
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);
|
|
5109
5172
|
} else {
|
|
5110
|
-
|
|
5111
|
-
limiter
|
|
5112
|
-
|
|
5173
|
+
const endPos = direction;
|
|
5174
|
+
limiter = maxDistance;
|
|
5175
|
+
endX = endPos.x ?? endPos[0];
|
|
5176
|
+
endY = endPos.y ?? endPos[1];
|
|
5113
5177
|
}
|
|
5114
5178
|
|
|
5115
|
-
|
|
5116
|
-
|
|
5179
|
+
const origin = scaleTo(startX, startY);
|
|
5180
|
+
const translation = scaleTo(endX - startX, endY - startY);
|
|
5117
5181
|
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
let shouldLimit = limiter && limiter(sprite);
|
|
5122
|
-
|
|
5123
|
-
// TODO provide advanced info: point and angle of intersection
|
|
5124
|
-
results.push({
|
|
5125
|
-
sprite,
|
|
5126
|
-
// point,
|
|
5127
|
-
// normal,
|
|
5128
|
-
fraction
|
|
5129
|
-
});
|
|
5182
|
+
const filter = new b2QueryFilter();
|
|
5183
|
+
filter.categoryBits = 0xffffffff;
|
|
5184
|
+
filter.maskBits = 0xffffffff;
|
|
5130
5185
|
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
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);
|
|
5137
5202
|
}
|
|
5138
|
-
return 1; //
|
|
5203
|
+
return 1; // continue to collect all hits
|
|
5139
5204
|
});
|
|
5140
5205
|
|
|
5141
|
-
|
|
5142
|
-
results.sort((a, b) => a.fraction - b.fraction);
|
|
5206
|
+
filter.delete();
|
|
5143
5207
|
|
|
5144
|
-
|
|
5208
|
+
// sort results by distance from start
|
|
5209
|
+
results.sort((a, b) => a.ray.distance - b.ray.distance);
|
|
5145
5210
|
|
|
5146
|
-
|
|
5147
|
-
if (res.fraction <= maxFraction) {
|
|
5148
|
-
sprites.push(res.sprite);
|
|
5149
|
-
}
|
|
5150
|
-
}
|
|
5211
|
+
if (!limiter) return results;
|
|
5151
5212
|
|
|
5152
|
-
return
|
|
5213
|
+
return results.filter(limiter);
|
|
5153
5214
|
}
|
|
5154
5215
|
};
|
|
5155
5216
|
|
|
@@ -5334,7 +5395,7 @@ async function q5playPreSetup(q) {
|
|
|
5334
5395
|
this.isActive = cameraOn = false;
|
|
5335
5396
|
}
|
|
5336
5397
|
}
|
|
5337
|
-
}; //end camera class
|
|
5398
|
+
}; // end camera class
|
|
5338
5399
|
|
|
5339
5400
|
$.Joint = class {
|
|
5340
5401
|
constructor(spriteA, spriteB, type) {
|
|
@@ -5359,8 +5420,6 @@ async function q5playPreSetup(q) {
|
|
|
5359
5420
|
|
|
5360
5421
|
let _this = this;
|
|
5361
5422
|
|
|
5362
|
-
// if (type != 'slider' && type != 'rope') {
|
|
5363
|
-
|
|
5364
5423
|
if (type != 'wheel') {
|
|
5365
5424
|
this._offsetA = {};
|
|
5366
5425
|
|
|
@@ -5775,15 +5834,24 @@ async function q5playPreSetup(q) {
|
|
|
5775
5834
|
}
|
|
5776
5835
|
|
|
5777
5836
|
get lowerLimit() {
|
|
5778
|
-
return Box2D.b2WheelJoint_GetLowerLimit(this.jID);
|
|
5837
|
+
return Box2D.b2WheelJoint_GetLowerLimit(this.jID) * meterSize;
|
|
5779
5838
|
}
|
|
5780
5839
|
|
|
5781
5840
|
get upperLimit() {
|
|
5782
|
-
return Box2D.b2WheelJoint_GetUpperLimit(this.jID);
|
|
5841
|
+
return Box2D.b2WheelJoint_GetUpperLimit(this.jID) * meterSize;
|
|
5783
5842
|
}
|
|
5784
5843
|
|
|
5785
|
-
set
|
|
5786
|
-
|
|
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);
|
|
5787
5855
|
}
|
|
5788
5856
|
|
|
5789
5857
|
get motorEnabled() {
|
|
@@ -6408,23 +6476,23 @@ async function q5playPreSetup(q) {
|
|
|
6408
6476
|
if (!ani.looping) return;
|
|
6409
6477
|
}
|
|
6410
6478
|
|
|
6411
|
-
//going to target frame up
|
|
6479
|
+
// going to target frame up
|
|
6412
6480
|
if (ani.targetFrame > ani._frame && ani.targetFrame !== -1) {
|
|
6413
6481
|
ani._frame++;
|
|
6414
6482
|
}
|
|
6415
|
-
//going to target frame down
|
|
6483
|
+
// going to target frame down
|
|
6416
6484
|
else if (ani.targetFrame < ani._frame && ani.targetFrame !== -1) {
|
|
6417
6485
|
ani._frame--;
|
|
6418
6486
|
} else if (ani.targetFrame === ani._frame && ani.targetFrame !== -1) {
|
|
6419
6487
|
ani.playing = false;
|
|
6420
6488
|
} else if (ani.looping) {
|
|
6421
|
-
//advance frame
|
|
6422
|
-
//if next frame is too high
|
|
6489
|
+
// advance frame
|
|
6490
|
+
// if next frame is too high
|
|
6423
6491
|
if (ani._frame >= ani.lastFrame) {
|
|
6424
6492
|
ani._frame = 0;
|
|
6425
6493
|
} else ani._frame++;
|
|
6426
6494
|
} else {
|
|
6427
|
-
//if next frame is too high
|
|
6495
|
+
// if next frame is too high
|
|
6428
6496
|
if (ani._frame < ani.lastFrame) ani._frame++;
|
|
6429
6497
|
}
|
|
6430
6498
|
} else {
|
|
@@ -6440,42 +6508,6 @@ async function q5playPreSetup(q) {
|
|
|
6440
6508
|
});
|
|
6441
6509
|
};
|
|
6442
6510
|
|
|
6443
|
-
async function playIntro() {
|
|
6444
|
-
if (document.getElementById('made-with-q5play')) return;
|
|
6445
|
-
if (!using_p5v2) $._incrementPreload();
|
|
6446
|
-
let d = document.createElement('div');
|
|
6447
|
-
d.id = 'made-with-q5play';
|
|
6448
|
-
d.style = 'position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: 1000; background-color: black;';
|
|
6449
|
-
let logo = document.createElement('img');
|
|
6450
|
-
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;`;
|
|
6451
|
-
logo.onerror = () => {
|
|
6452
|
-
logo.style.imageRendering = 'pixelated';
|
|
6453
|
-
logo.src = `data:image/png;base64,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`;
|
|
6454
|
-
};
|
|
6455
|
-
let src = window._q5play_intro_image;
|
|
6456
|
-
if (src == '' || src?.includes('made_with_q5play')) {
|
|
6457
|
-
if (src.includes('bit.') || src.includes('pixel')) {
|
|
6458
|
-
logo.style.imageRendering = 'pixelated';
|
|
6459
|
-
}
|
|
6460
|
-
logo.src = src;
|
|
6461
|
-
} else {
|
|
6462
|
-
logo.src = 'https://q5play.org/assets/made_with_q5play.webp';
|
|
6463
|
-
}
|
|
6464
|
-
await new Promise((r) => (logo.onload = r));
|
|
6465
|
-
d.append(logo);
|
|
6466
|
-
document.body.append(d);
|
|
6467
|
-
await $.delay();
|
|
6468
|
-
logo.offsetHeight; // trigger css reflow
|
|
6469
|
-
logo.style.scale = 1.2;
|
|
6470
|
-
await $.delay(1100);
|
|
6471
|
-
logo.style.opacity = 0;
|
|
6472
|
-
await $.delay(400);
|
|
6473
|
-
d.style.display = 'none';
|
|
6474
|
-
d.remove();
|
|
6475
|
-
document.getElementById('made-with-q5play')?.remove();
|
|
6476
|
-
if (!using_p5v2) $._decrementPreload();
|
|
6477
|
-
}
|
|
6478
|
-
|
|
6479
6511
|
if (window.location) {
|
|
6480
6512
|
let lh = location.hostname;
|
|
6481
6513
|
switch (lh) {
|
|
@@ -6508,7 +6540,7 @@ async function q5playPreSetup(q) {
|
|
|
6508
6540
|
) {
|
|
6509
6541
|
break;
|
|
6510
6542
|
}
|
|
6511
|
-
|
|
6543
|
+
$.q5play.splashScreen();
|
|
6512
6544
|
}
|
|
6513
6545
|
}
|
|
6514
6546
|
|
|
@@ -7823,10 +7855,6 @@ async function q5playPreSetup(q) {
|
|
|
7823
7855
|
|
|
7824
7856
|
s = $.q5play.sprites[uid];
|
|
7825
7857
|
|
|
7826
|
-
if (s && !s.visible) {
|
|
7827
|
-
continue;
|
|
7828
|
-
}
|
|
7829
|
-
|
|
7830
7858
|
let type = Box2D.HEAPU8[offset];
|
|
7831
7859
|
|
|
7832
7860
|
if (type == 7) {
|
|
@@ -7855,6 +7883,10 @@ async function q5playPreSetup(q) {
|
|
|
7855
7883
|
s._velSynced = false;
|
|
7856
7884
|
s._vel._magCached = false;
|
|
7857
7885
|
|
|
7886
|
+
if (!s.visible) {
|
|
7887
|
+
continue;
|
|
7888
|
+
}
|
|
7889
|
+
|
|
7858
7890
|
if (s._hasImagery || s._userDefinedDraw) {
|
|
7859
7891
|
s._rotation = Math.atan2(data[2], data[3]) * RADTODEG;
|
|
7860
7892
|
}
|