pxt-common-packages 10.3.2 → 10.3.4

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.
Files changed (41) hide show
  1. package/built/common-sim.d.ts +2 -2
  2. package/libs/azureiot/built/debug/binary.js +461 -461
  3. package/libs/color/built/debug/binary.js +8 -8
  4. package/libs/color-sensor/built/debug/binary.js +8 -8
  5. package/libs/controller/built/debug/binary.js +7736 -7608
  6. package/libs/controller---none/built/debug/binary.js +7715 -7587
  7. package/libs/datalogger/built/debug/binary.js +63 -63
  8. package/libs/edge-connector/built/debug/binary.js +9 -9
  9. package/libs/esp32/built/debug/binary.js +462 -462
  10. package/libs/game/built/debug/binary.js +7628 -7500
  11. package/libs/game/camera.ts +18 -13
  12. package/libs/game/physics.ts +2 -1
  13. package/libs/game/scenes.ts +3 -0
  14. package/libs/lcd/built/debug/binary.js +8 -8
  15. package/libs/light-spectrum-sensor/built/debug/binary.js +8 -8
  16. package/libs/lora/built/debug/binary.js +8 -8
  17. package/libs/matrix-keypad/built/debug/binary.js +8 -8
  18. package/libs/mqtt/built/debug/binary.js +176 -176
  19. package/libs/multiplayer/README.md +4 -0
  20. package/libs/multiplayer/docs/.gitkeep +0 -0
  21. package/libs/multiplayer/fieldEditors.ts +23 -0
  22. package/libs/multiplayer/images.ts +303 -0
  23. package/libs/multiplayer/mp.ts +625 -0
  24. package/libs/multiplayer/pxt.json +19 -0
  25. package/libs/multiplayer/stateKind.ts +14 -0
  26. package/libs/multiplayer/targetoverrides.ts +1 -0
  27. package/libs/multiplayer/test.ts +0 -0
  28. package/libs/net/built/debug/binary.js +176 -176
  29. package/libs/net-game/built/debug/binary.js +9540 -9412
  30. package/libs/palette/built/debug/binary.js +7627 -7499
  31. package/libs/pixel/built/debug/binary.js +8 -8
  32. package/libs/power/built/debug/binary.js +8 -8
  33. package/libs/proximity/built/debug/binary.js +8 -8
  34. package/libs/radio/built/debug/binary.js +8 -8
  35. package/libs/radio-broadcast/built/debug/binary.js +8 -8
  36. package/libs/rotary-encoder/built/debug/binary.js +8 -8
  37. package/libs/screen/built/debug/binary.js +50 -50
  38. package/libs/servo/built/debug/binary.js +8 -8
  39. package/libs/sprite-scaling/built/debug/binary.js +7627 -7499
  40. package/libs/storyboard/built/debug/binary.js +7627 -7499
  41. package/package.json +1 -1
@@ -0,0 +1,625 @@
1
+ namespace sprites.multiplayer {
2
+ //% blockId=mp_setPlayerSprite
3
+ //% block="set $player sprite to $sprite=variables_get(mySprite)"
4
+ //% player.shadow=mp_playernumber
5
+ //% weight=75
6
+ //% blockGap=8
7
+ //% group="Multiplayer"
8
+ //% parts="multiplayer"
9
+ export function setPlayerSprite(player: number, sprite: Sprite) {
10
+ mp._state().setPlayerSprite(player, sprite);
11
+ }
12
+
13
+ //% blockId=mp_getPlayerSprite
14
+ //% block="$player sprite"
15
+ //% player.shadow=mp_playernumber
16
+ //% weight=70
17
+ //% blockGap=8
18
+ //% group="Multiplayer"
19
+ //% parts="multiplayer"
20
+ export function getPlayerSprite(player: number): Sprite {
21
+ return mp._state().getPlayerSprite(player);
22
+ }
23
+
24
+ //% blockId=mp_isPlayerSprite
25
+ //% block="is $sprite $player sprite"
26
+ //% sprite.shadow=variables_get
27
+ //% sprite.defl=mySprite
28
+ //% player.shadow=mp_playernumber
29
+ //% weight=60
30
+ //% group="Multiplayer"
31
+ //% parts="multiplayer"
32
+ export function isPlayerSprite(sprite: Sprite, player: number): boolean {
33
+ return getPlayerSprite(player) === sprite;
34
+ }
35
+ }
36
+
37
+ namespace controller.multiplayer {
38
+ //% blockId=mp_moveWithButtons
39
+ //% block="$player move $sprite with buttons||vx $vx vy $vy"
40
+ //% player.shadow=mp_playernumber
41
+ //% sprite.shadow=variables_get
42
+ //% sprite.defl=mySprite
43
+ //% vx.defl=100
44
+ //% vy.defl=100
45
+ //% vx.shadow="spriteSpeedPicker"
46
+ //% vy.shadow="spriteSpeedPicker"
47
+ //% expandableArgumentMode="toggle"
48
+ //% inlineInputMode=inline
49
+ //% group="Multiplayer"
50
+ //% parts="multiplayer"
51
+ //% weight=100
52
+ export function moveWithButtons(
53
+ player: number,
54
+ sprite: Sprite,
55
+ vx?: number,
56
+ vy?: number
57
+ ) {
58
+ mp.getController(player).moveSprite(sprite, vx, vy);
59
+ }
60
+
61
+ //% blockId=mp_onButtonEvent
62
+ //% block="on $button button $event for $player"
63
+ //% draggableParameters=reporter
64
+ //% group="Multiplayer"
65
+ //% parts="multiplayer"
66
+ //% weight=90
67
+ export function onButtonEvent(
68
+ button: mp.MultiplayerButton,
69
+ event: ControllerButtonEvent,
70
+ handler: (player: number) => void
71
+ ) {
72
+ mp._state().onButtonEvent(button, event, handler);
73
+ }
74
+
75
+ //% blockId=mp_isButtonPressed
76
+ //% block="is $player $button button pressed"
77
+ //% player.shadow=mp_playernumber
78
+ //% group="Multiplayer"
79
+ //% parts="multiplayer"
80
+ //% weight=80
81
+ //% blockGap=8
82
+ export function isButtonPressed(
83
+ player: number,
84
+ button: mp.MultiplayerButton
85
+ ): boolean {
86
+ return mp.getButton(mp.getController(player), button).isPressed();
87
+ }
88
+ }
89
+
90
+ namespace info.multiplayer {
91
+ //% blockId=mp_getPlayerState
92
+ //% block="$player $state"
93
+ //% player.shadow=mp_playernumber
94
+ //% state.shadow=mp_multiplayerstate
95
+ //% group="Multiplayer"
96
+ //% parts="multiplayer"
97
+ //% weight=100
98
+ //% blockGap=8
99
+ export function getPlayerState(player: number, state: number): number {
100
+ if (state === MultiplayerState.Score) {
101
+ return mp.getInfo(player).score();
102
+ } else if (state === MultiplayerState.Lives) {
103
+ return mp.getInfo(player).life();
104
+ }
105
+
106
+ return mp._state().getPlayerState(player, state);
107
+ }
108
+
109
+ //% blockId=mp_setPlayerState
110
+ //% block="set $player $state to $value"
111
+ //% player.shadow=mp_playernumber
112
+ //% state.shadow=mp_multiplayerstate
113
+ //% group="Multiplayer"
114
+ //% parts="multiplayer"
115
+ //% weight=90
116
+ //% blockGap=8
117
+ export function setPlayerState(
118
+ player: number,
119
+ state: number,
120
+ value: number
121
+ ) {
122
+ if (state === MultiplayerState.Score) {
123
+ return mp.getInfo(player).setScore(value);
124
+ } else if (state === MultiplayerState.Lives) {
125
+ return mp.getInfo(player).setLife(value);
126
+ }
127
+
128
+ mp._state().setPlayerState(player, state, value);
129
+ }
130
+
131
+ //% blockId=mp_changePlayerStateBy
132
+ //% block="change $player $state by $deltaValue"
133
+ //% player.shadow=mp_playernumber
134
+ //% state.shadow=mp_multiplayerstate
135
+ //% deltaValue.defl=1
136
+ //% group="Multiplayer"
137
+ //% parts="multiplayer"
138
+ //% weight=80
139
+ export function changePlayerStateBy(
140
+ player: number,
141
+ state: number,
142
+ deltaValue: number
143
+ ) {
144
+ setPlayerState(
145
+ player,
146
+ state,
147
+ getPlayerState(player, state) + deltaValue
148
+ );
149
+ }
150
+
151
+ //% blockId=mp_onScore
152
+ //% block="on score $score for $player"
153
+ //% score.defl=100
154
+ //% draggableParameters=reporter
155
+ //% group="Multiplayer"
156
+ //% parts="multiplayer"
157
+ //% weight=70
158
+ //% blockGap=8
159
+ export function onScore(score: number, handler: (player: number) => void) {
160
+ mp._state().onReachedScore(score, handler);
161
+ }
162
+
163
+ //% blockId=mp_onLifeZero
164
+ //% block="on life zero for $player"
165
+ //% draggableParameters=reporter
166
+ //% group="Multiplayer"
167
+ //% parts="multiplayer"
168
+ //% weight=60
169
+ export function onLifeZero(handler: (player: number) => void) {
170
+ mp._state().onLifeZero(handler);
171
+ }
172
+ }
173
+
174
+ //% icon="\uf0c0"
175
+ //% block="Multiplayer"
176
+ //% color="#207a77"
177
+ namespace mp {
178
+ export enum PlayerNumber {
179
+ //% block="1"
180
+ One = 1,
181
+ //% block="2"
182
+ Two = 2,
183
+ //% block="3"
184
+ Three = 3,
185
+ //% block="4"
186
+ Four = 4,
187
+ }
188
+
189
+ export enum MultiplayerButton {
190
+ //% block="A"
191
+ A,
192
+ //% block="B"
193
+ B,
194
+ //% block="up"
195
+ Up,
196
+ //% block="right"
197
+ Right,
198
+ //% block="down"
199
+ Down,
200
+ //% block="left"
201
+ Left,
202
+ }
203
+
204
+ //% blockId=mp_setPlayerIndicatorsVisible
205
+ //% block="set player indicators $visible"
206
+ //% visible.shadow=toggleOnOff
207
+ //% visible.defl=true
208
+ //% group="Utility"
209
+ //% parts="multiplayer"
210
+ //% weight=100
211
+ export function setPlayerIndicatorsVisible(visible: boolean) {
212
+ mp._state().setPlayerIndicatorsVisible(visible);
213
+ }
214
+
215
+ //% blockId=mp_isPlayer
216
+ //% block="$toCheck is $player"
217
+ //% toCheck.shadow=variables_get
218
+ //% toCheck.defl=player
219
+ //% player.shadow=mp_playernumber
220
+ //% group="Utility"
221
+ //% parts="multiplayer"
222
+ //% weight=90
223
+ export function isPlayer(toCheck: number, player: number): boolean {
224
+ return toCheck === player;
225
+ }
226
+
227
+ //% blockId=mp_allPlayers
228
+ //% block="array of all players"
229
+ //% group="Utility"
230
+ //% parts="multiplayer"
231
+ //% weight=80
232
+ export function allPlayers(): number[] {
233
+ return [1, 2, 3, 4];
234
+ }
235
+
236
+ //% blockId=mp_indexToPlayer
237
+ //% block="$index to player number"
238
+ //% index.shadow=variables_get
239
+ //% index.defl=index
240
+ //% group="Utility"
241
+ //% parts="multiplayer"
242
+ //% weight=70
243
+ //% blockGap=8
244
+ export function indexToPlayer(index: number) {
245
+ if (index < 0 || index > 3) return -1;
246
+ return (index | 0) + 1;
247
+ }
248
+
249
+ //% blockId=mp_playerToIndex
250
+ //% block="$player to index"
251
+ //% player.shadow=mp_playernumber
252
+ //% group="Utility"
253
+ //% parts="multiplayer"
254
+ //% weight=60
255
+ export function playerToIndex(player: number) {
256
+ if (player < 1 || player > 4) return -1;
257
+ return (player | 0) - 1;
258
+ }
259
+
260
+ export function getController(player: number): controller.Controller {
261
+ switch (player) {
262
+ case 1:
263
+ return controller.player1 as any;
264
+ case 2:
265
+ return controller.player2;
266
+ case 3:
267
+ return controller.player3;
268
+ case 4:
269
+ return controller.player4;
270
+ }
271
+ return undefined;
272
+ }
273
+
274
+ export function getInfo(player: number) {
275
+ switch (player) {
276
+ case 1:
277
+ return info.player1;
278
+ case 2:
279
+ return info.player2;
280
+ case 3:
281
+ return info.player3;
282
+ case 4:
283
+ return info.player4;
284
+ }
285
+ return undefined;
286
+ }
287
+
288
+ export function getButton(
289
+ ctrl: controller.Controller,
290
+ button: MultiplayerButton
291
+ ) {
292
+ switch (button) {
293
+ case MultiplayerButton.A:
294
+ return ctrl.A;
295
+ case MultiplayerButton.B:
296
+ return ctrl.B;
297
+ case MultiplayerButton.Up:
298
+ return ctrl.up;
299
+ case MultiplayerButton.Right:
300
+ return ctrl.right;
301
+ case MultiplayerButton.Down:
302
+ return ctrl.down;
303
+ case MultiplayerButton.Left:
304
+ return ctrl.left;
305
+ }
306
+ }
307
+
308
+ let stateStack: MPState[];
309
+
310
+ class ButtonHandler {
311
+ constructor(
312
+ public button: mp.MultiplayerButton,
313
+ public event: ControllerButtonEvent,
314
+ public handler: (player: number) => void
315
+ ) {}
316
+ }
317
+
318
+ class ScoreHandler {
319
+ constructor(
320
+ public target: number,
321
+ public handler: (player: number) => void
322
+ ) {}
323
+ }
324
+
325
+ class PlayerStateEntry {
326
+ public player1: number;
327
+ public player2: number;
328
+ public player3: number;
329
+ public player4: number;
330
+
331
+ constructor() {
332
+ this.player1 = 0;
333
+ this.player2 = 0;
334
+ this.player3 = 0;
335
+ this.player4 = 0;
336
+ }
337
+
338
+ getForPlayer(player: number) {
339
+ switch (player) {
340
+ case 1:
341
+ return this.player1;
342
+ case 2:
343
+ return this.player2;
344
+ case 3:
345
+ return this.player3;
346
+ case 4:
347
+ return this.player4;
348
+ }
349
+ return undefined;
350
+ }
351
+
352
+ setForPlayer(player: number, value: number) {
353
+ switch (player) {
354
+ case 1:
355
+ this.player1 = value;
356
+ break;
357
+ case 2:
358
+ this.player2 = value;
359
+ break;
360
+ case 3:
361
+ this.player3 = value;
362
+ break;
363
+ case 4:
364
+ this.player4 = value;
365
+ break;
366
+ }
367
+ }
368
+ }
369
+
370
+ class MPState {
371
+ playerSprites: Sprite[];
372
+ buttonHandlers: ButtonHandler[];
373
+ scoreHandlers: ScoreHandler[];
374
+ playerState: PlayerStateEntry[];
375
+ lifeZeroHandler: (player: number) => void;
376
+ indicatorsVisible: boolean;
377
+ indicatorRenderable: scene.Renderable;
378
+
379
+ constructor() {
380
+ this.playerSprites = [];
381
+ this.buttonHandlers = [];
382
+ this.playerState = [];
383
+ this.scoreHandlers = [];
384
+ this.indicatorsVisible = false;
385
+ }
386
+
387
+ onButtonEvent(
388
+ button: mp.MultiplayerButton,
389
+ event: ControllerButtonEvent,
390
+ handler: (playerNumber: number) => void
391
+ ) {
392
+ const existing = this.getButtonHandler(button, event);
393
+
394
+ if (existing) {
395
+ existing.handler = handler;
396
+ return;
397
+ }
398
+
399
+ this.buttonHandlers.push(new ButtonHandler(button, event, handler));
400
+
401
+ const registerHandler = (p: number) => {
402
+ mp.getButton(mp.getController(p), button).onEvent(event, () => {
403
+ this.getButtonHandler(button, event).handler(p);
404
+ });
405
+ };
406
+
407
+ for (let player = 1; player < 5; player++) {
408
+ registerHandler(player);
409
+ }
410
+ }
411
+
412
+ onReachedScore(score: number, handler: (playerNumber: number) => void) {
413
+ const existing = this.getScoreHandler(score);
414
+
415
+ if (existing) {
416
+ existing.handler = handler;
417
+ return;
418
+ }
419
+
420
+ this.scoreHandlers.push(new ScoreHandler(score, handler));
421
+
422
+ const registerHandler = (p: number) => {
423
+ mp.getInfo(p).onScore(score, () => {
424
+ this.getScoreHandler(score).handler(p);
425
+ });
426
+ };
427
+
428
+ for (let player = 1; player < 5; player++) {
429
+ registerHandler(player);
430
+ }
431
+ }
432
+
433
+ onLifeZero(handler: (playerNumber: number) => void) {
434
+ if (!this.lifeZeroHandler) {
435
+ const registerHandler = (p: number) => {
436
+ mp.getInfo(p).onLifeZero(() => {
437
+ this.lifeZeroHandler(p);
438
+ });
439
+ };
440
+
441
+ for (let player = 1; player < 5; player++) {
442
+ registerHandler(player);
443
+ }
444
+ }
445
+
446
+ this.lifeZeroHandler = handler;
447
+ }
448
+
449
+ setPlayerSprite(player: number, sprite: Sprite) {
450
+ player |= 0;
451
+ if (player < 1 || player > 4) return;
452
+
453
+ while (this.playerSprites.length < player + 1) {
454
+ this.playerSprites.push(undefined);
455
+ }
456
+
457
+ this.playerSprites[player] = sprite;
458
+ }
459
+
460
+ getPlayerSprite(player: number) {
461
+ return this.playerSprites[player];
462
+ }
463
+
464
+ setPlayerState(player: number, state: number, value: number) {
465
+ this.getOrCreatePlayerStateEntry(state).setForPlayer(player, value);
466
+ }
467
+
468
+ getPlayerState(player: number, state: number) {
469
+ return this.getOrCreatePlayerStateEntry(state).getForPlayer(player);
470
+ }
471
+
472
+ setPlayerIndicatorsVisible(visible: boolean) {
473
+ this.indicatorsVisible = visible;
474
+
475
+ if (visible && !this.indicatorRenderable) {
476
+ this.indicatorRenderable = scene.createRenderable(
477
+ 99,
478
+ (target, camera) => {
479
+ if (this.indicatorsVisible)
480
+ this.drawIndicators(target, camera);
481
+ }
482
+ );
483
+ }
484
+ }
485
+
486
+ protected getOrCreatePlayerStateEntry(state: number) {
487
+ if (!this.playerState[state]) {
488
+ while (this.playerState.length < state + 1) {
489
+ this.playerState.push(undefined);
490
+ }
491
+
492
+ this.playerState[state] = new PlayerStateEntry();
493
+ }
494
+
495
+ return this.playerState[state];
496
+ }
497
+
498
+ protected getButtonHandler(
499
+ button: mp.MultiplayerButton,
500
+ event: ControllerButtonEvent
501
+ ) {
502
+ for (const bHandler of this.buttonHandlers) {
503
+ if (bHandler.button === button && bHandler.event === event)
504
+ return bHandler;
505
+ }
506
+
507
+ return undefined;
508
+ }
509
+
510
+ protected getScoreHandler(score: number) {
511
+ for (const sHandler of this.scoreHandlers) {
512
+ if (sHandler.target === score) return sHandler;
513
+ }
514
+ return undefined;
515
+ }
516
+
517
+ protected drawIndicators(target: Image, camera: scene.Camera) {
518
+ for (let player = 1; player < 5; player++) {
519
+ const sprite = this.getPlayerSprite(player);
520
+
521
+ if (
522
+ !sprite ||
523
+ sprite.flags &
524
+ (sprites.Flag.Destroyed | sprites.Flag.Invisible)
525
+ ) {
526
+ continue;
527
+ }
528
+
529
+ let top = Fx.toInt(sprite._hitbox.top);
530
+ let bottom = Fx.toInt(sprite._hitbox.bottom);
531
+ let left = Fx.toInt(sprite._hitbox.left);
532
+ let right = Fx.toInt(sprite._hitbox.right);
533
+
534
+ if (!(sprite.flags & sprites.Flag.RelativeToCamera)) {
535
+ top -= camera.drawOffsetY;
536
+ bottom -= camera.drawOffsetY;
537
+ left -= camera.drawOffsetX;
538
+ right -= camera.drawOffsetX;
539
+ }
540
+
541
+ if (left < 0) {
542
+ const indicator = multiplayer._indicatorForPlayer(
543
+ player,
544
+ CollisionDirection.Right
545
+ );
546
+ target.drawTransparentImage(
547
+ indicator,
548
+ Math.max(right + 2, 0),
549
+ Math.min(
550
+ Math.max(
551
+ top +
552
+ ((bottom - top) >> 1) -
553
+ (indicator.height >> 1),
554
+ 0
555
+ ),
556
+ screen.height - indicator.height
557
+ )
558
+ );
559
+ } else if (right > 160) {
560
+ const indicator = multiplayer._indicatorForPlayer(
561
+ player,
562
+ CollisionDirection.Left
563
+ );
564
+ target.drawTransparentImage(
565
+ indicator,
566
+ Math.min(
567
+ left - indicator.width - 2,
568
+ screen.width - indicator.width
569
+ ),
570
+ Math.min(
571
+ Math.max(
572
+ top +
573
+ ((bottom - top) >> 1) -
574
+ (indicator.height >> 1),
575
+ 0
576
+ ),
577
+ screen.height - indicator.height
578
+ )
579
+ );
580
+ } else if (top < 18) {
581
+ const indicator = multiplayer._indicatorForPlayer(
582
+ player,
583
+ CollisionDirection.Bottom
584
+ );
585
+ target.drawTransparentImage(
586
+ indicator,
587
+ left + ((right - left) >> 1) - (indicator.width >> 1),
588
+ Math.max(bottom + 2, 0)
589
+ );
590
+ } else {
591
+ const indicator = multiplayer._indicatorForPlayer(
592
+ player,
593
+ CollisionDirection.Top
594
+ );
595
+ target.drawTransparentImage(
596
+ indicator,
597
+ left + ((right - left) >> 1) - (indicator.width >> 1),
598
+ Math.min(
599
+ top - indicator.height - 2,
600
+ screen.height - indicator.height
601
+ )
602
+ );
603
+ }
604
+ }
605
+ }
606
+ }
607
+
608
+ function init() {
609
+ if (stateStack) return;
610
+ stateStack = [new MPState()];
611
+ game.addScenePushHandler(() => {
612
+ stateStack.push(new MPState());
613
+ });
614
+
615
+ game.addScenePopHandler(() => {
616
+ stateStack.pop();
617
+ if (stateStack.length === 0) stateStack.push(new MPState());
618
+ });
619
+ }
620
+
621
+ export function _state() {
622
+ init();
623
+ return stateStack[stateStack.length - 1];
624
+ }
625
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "multiplayer",
3
+ "description": "Additional blocks for building multiplayer games",
4
+ "files": [
5
+ "README.md",
6
+ "fieldEditors.ts",
7
+ "images.ts",
8
+ "mp.ts",
9
+ "stateKind.ts",
10
+ "targetoverrides.ts"
11
+ ],
12
+ "testFiles": [
13
+ "test.ts"
14
+ ],
15
+ "public": true,
16
+ "dependencies": {
17
+ "game": "file:../game"
18
+ }
19
+ }
@@ -0,0 +1,14 @@
1
+ namespace MultiplayerState {
2
+ let nextKind: number;
3
+
4
+ export function create() {
5
+ if (nextKind === undefined) nextKind = 0;
6
+ return nextKind++;
7
+ }
8
+
9
+ //% isKind
10
+ export const Score = create();
11
+
12
+ //% isKind
13
+ export const Lives = create();
14
+ }
@@ -0,0 +1 @@
1
+ // TODO any platform specific overrides
File without changes