pxt-common-packages 10.3.4 → 10.3.6

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 (45) hide show
  1. package/built/common-sim.d.ts +12 -0
  2. package/built/common-sim.js +24 -0
  3. package/libs/azureiot/built/debug/binary.js +461 -461
  4. package/libs/color/built/debug/binary.js +8 -8
  5. package/libs/color-sensor/built/debug/binary.js +8 -8
  6. package/libs/controller/built/debug/binary.js +7239 -7205
  7. package/libs/controller---none/built/debug/binary.js +4062 -4028
  8. package/libs/datalogger/built/debug/binary.js +63 -63
  9. package/libs/edge-connector/built/debug/binary.js +8 -8
  10. package/libs/esp32/built/debug/binary.js +462 -462
  11. package/libs/game/animation.ts +403 -323
  12. package/libs/game/built/debug/binary.js +7158 -7124
  13. package/libs/game/controller.ts +6 -0
  14. package/libs/game/info.ts +9 -0
  15. package/libs/game/multiplayer.cpp +3 -0
  16. package/libs/game/multiplayer.ts +45 -0
  17. package/libs/game/physics.ts +2 -2
  18. package/libs/game/sim/multiplayer.ts +32 -0
  19. package/libs/lcd/built/debug/binary.js +8 -8
  20. package/libs/light-spectrum-sensor/built/debug/binary.js +8 -8
  21. package/libs/lora/built/debug/binary.js +8 -8
  22. package/libs/matrix-keypad/built/debug/binary.js +8 -8
  23. package/libs/mixer/instrument.ts +22 -3
  24. package/libs/mixer/sequencer.ts +2 -2
  25. package/libs/mqtt/built/debug/binary.js +176 -176
  26. package/libs/multiplayer/fieldEditors.ts +0 -8
  27. package/libs/multiplayer/images.ts +1 -1
  28. package/libs/multiplayer/player.ts +706 -0
  29. package/libs/multiplayer/pxt.json +1 -1
  30. package/libs/multiplayer/stateKind.ts +1 -1
  31. package/libs/net/built/debug/binary.js +176 -176
  32. package/libs/net-game/built/debug/binary.js +8745 -8711
  33. package/libs/palette/built/debug/binary.js +7157 -7123
  34. package/libs/pixel/built/debug/binary.js +8 -8
  35. package/libs/power/built/debug/binary.js +8 -8
  36. package/libs/proximity/built/debug/binary.js +8 -8
  37. package/libs/radio/built/debug/binary.js +8 -8
  38. package/libs/radio-broadcast/built/debug/binary.js +8 -8
  39. package/libs/rotary-encoder/built/debug/binary.js +8 -8
  40. package/libs/screen/built/debug/binary.js +50 -50
  41. package/libs/servo/built/debug/binary.js +8 -8
  42. package/libs/sprite-scaling/built/debug/binary.js +7157 -7123
  43. package/libs/storyboard/built/debug/binary.js +7157 -7123
  44. package/package.json +1 -1
  45. package/libs/multiplayer/mp.ts +0 -625
@@ -0,0 +1,706 @@
1
+ //% color="#207a77"
2
+ //% icon="\uf0c0"
3
+ //% block="Multiplayer"
4
+ namespace mp {
5
+ const MAX_PLAYERS = 4;
6
+
7
+ export enum PlayerNumber {
8
+ //% block="1"
9
+ One = 1,
10
+ //% block="2"
11
+ Two = 2,
12
+ //% block="3"
13
+ Three = 3,
14
+ //% block="4"
15
+ Four = 4
16
+ }
17
+
18
+ export enum PlayerProperty {
19
+ //% block="index"
20
+ Index = 1,
21
+ //% block="number"
22
+ Number = 2
23
+ }
24
+
25
+ export enum MultiplayerButton {
26
+ //% block="A"
27
+ A,
28
+ //% block="B"
29
+ B,
30
+ //% block="up"
31
+ Up,
32
+ //% block="right"
33
+ Right,
34
+ //% block="down"
35
+ Down,
36
+ //% block="left"
37
+ Left
38
+ }
39
+
40
+ class ButtonHandler {
41
+ constructor(public button: MultiplayerButton, public event: ControllerButtonEvent, public handler: (player: Player) => void) {
42
+ }
43
+ }
44
+
45
+ class ControllerEventHandler {
46
+ constructor(public event: ControllerEvent, public handler: (player: Player) => void) {
47
+ }
48
+ }
49
+
50
+ class ScoreHandler {
51
+ constructor(public target: number, public handler: (player: Player) => void) {
52
+ }
53
+ }
54
+
55
+ /**
56
+ * A player in the game
57
+ */
58
+ export class Player {
59
+ _sprite: Sprite;
60
+ _state: number[];
61
+ _index: number;
62
+ _data: any;
63
+
64
+ constructor(index: number) {
65
+ this._index = index;
66
+ }
67
+
68
+ get index(): number {
69
+ return this._index;
70
+ }
71
+
72
+ get number(): number {
73
+ return this._index + 1;
74
+ }
75
+
76
+ get data(): any {
77
+ if (!this._data) this._data = {};
78
+ return this._data;
79
+ }
80
+
81
+ set data(value: any) {
82
+ this._data = value;
83
+ }
84
+
85
+ getProperty(prop: PlayerProperty): number {
86
+ switch (prop) {
87
+ case PlayerProperty.Index: return this.index;
88
+ case PlayerProperty.Number: return this.number;
89
+ default: return 0;
90
+ }
91
+ }
92
+
93
+ getSprite(): Sprite {
94
+ return this._sprite;
95
+ }
96
+
97
+ setSprite(sprite: Sprite) {
98
+ if (sprite && sprite.image) {
99
+ // Passing 'implicit' flag so we don't override icons that
100
+ // user has explicitly defined.
101
+ multiplayer.postPresenceIcon(
102
+ this.number,
103
+ sprite.image,
104
+ /** implicit **/ true
105
+ );
106
+ } else {
107
+ // Passing 'implicit' flag so we don't override icons that
108
+ // user has explicitly defined.
109
+ multiplayer.postPresenceIcon(
110
+ this.number,
111
+ undefined,
112
+ /** implicit **/ true
113
+ );
114
+
115
+ }
116
+ this._sprite = sprite;
117
+ }
118
+
119
+ moveWithButtons(vx?: number, vy?: number) {
120
+ this._getController().moveSprite(this.getSprite(), vx, vy);
121
+ }
122
+
123
+ getState(key: number): number {
124
+ if (key === MultiplayerState.Score) {
125
+ return this._getInfo().score();
126
+ }
127
+ if (key === MultiplayerState.Life) {
128
+ return this._getInfo().life();
129
+ }
130
+ return this._getState(key);
131
+ }
132
+
133
+ setState(key: number, val: number) {
134
+ if (key === MultiplayerState.Score) {
135
+ this._getInfo().setScore(val);
136
+ }
137
+ if (key === MultiplayerState.Life) {
138
+ this._getInfo().setLife(val);
139
+ }
140
+ this._setState(key, val);
141
+ }
142
+
143
+ _setState(key: number, val: number) {
144
+ this._ensureState(key);
145
+ if (this._state.length > key)
146
+ this._state[key] = val;
147
+ }
148
+
149
+ _getState(key: number): number {
150
+ this._ensureState(key);
151
+ return (this._state.length > key) ? this._state[key] : 0;
152
+ }
153
+
154
+ _ensureState(key: number) {
155
+ if (!this._state) this._state = [];
156
+ if (key < 0 || key > 255) return;
157
+ while (this._state.length < key) this._state.push(0);
158
+ }
159
+
160
+ _getInfo(): info.PlayerInfo {
161
+ switch (this._index) {
162
+ case 0: return info.player1;
163
+ case 1: return info.player2;
164
+ case 2: return info.player3;
165
+ case 3: return info.player4;
166
+ default: return undefined;
167
+ }
168
+ }
169
+
170
+ _getController(): controller.Controller {
171
+ switch (this._index) {
172
+ case 0: return controller.player1 as any;
173
+ case 1: return controller.player2;
174
+ case 2: return controller.player3;
175
+ case 3: return controller.player4;
176
+ }
177
+ return undefined;
178
+ }
179
+ }
180
+
181
+ class MPState {
182
+ players: Player[];
183
+ buttonHandlers: ButtonHandler[];
184
+ controllerEventHandlers: ControllerEventHandler[];
185
+ scoreHandlers: ScoreHandler[];
186
+ lifeZeroHandler: (player: Player) => void;
187
+ indicatorsVisible: boolean;
188
+ indicatorRenderable: scene.Renderable;
189
+
190
+ constructor() {
191
+ this.players = [];
192
+ for (let i = 0; i < MAX_PLAYERS; ++i)
193
+ this.players.push(new Player(i));
194
+ this.buttonHandlers = [];
195
+ this.controllerEventHandlers = [];
196
+ this.scoreHandlers = [];
197
+ this.indicatorsVisible = false;
198
+ }
199
+
200
+ onButtonEvent(button: MultiplayerButton, event: ControllerButtonEvent, handler: (player: Player) => void) {
201
+ const existing = this.getButtonHandler(button, event);
202
+
203
+ if (existing) {
204
+ existing.handler = handler;
205
+ return;
206
+ }
207
+
208
+ this.buttonHandlers.push(new ButtonHandler(button, event, handler));
209
+
210
+ for (const player of this.players) {
211
+ getButton(player._getController(), button).onEvent(event, () => {
212
+ this.getButtonHandler(button, event).handler(player);
213
+ })
214
+ }
215
+ }
216
+
217
+ onControllerEvent(event: ControllerEvent, handler: (player: Player) => void) {
218
+ const existing = this.getControllerEventHandler(event);
219
+
220
+ if (existing) {
221
+ existing.handler = handler;
222
+ return;
223
+ }
224
+
225
+ this.controllerEventHandlers.push(new ControllerEventHandler(event, handler));
226
+
227
+ for (const player of this.players) {
228
+ player._getController().onEvent(event, () => {
229
+ this.getControllerEventHandler(event).handler(player);
230
+ })
231
+ }
232
+ }
233
+
234
+ onReachedScore(score: number, handler: (player: Player) => void) {
235
+ const existing = this.getScoreHandler(score);
236
+
237
+ if (existing) {
238
+ existing.handler = handler;
239
+ return;
240
+ }
241
+
242
+ this.scoreHandlers.push(new ScoreHandler(score, handler));
243
+
244
+ for (const player of this.players) {
245
+ player._getInfo().onScore(score, () => {
246
+ this.getScoreHandler(score).handler(player);
247
+ })
248
+ }
249
+ }
250
+
251
+ onLifeZero(handler: (player: Player) => void) {
252
+ if (!this.lifeZeroHandler) {
253
+ for (const player of this.players) {
254
+ player._getInfo().onLifeZero(() => {
255
+ this.lifeZeroHandler(player);
256
+ })
257
+ }
258
+ }
259
+ this.lifeZeroHandler = handler;
260
+ }
261
+
262
+ setPlayerIndicatorsVisible(visible: boolean) {
263
+ this.indicatorsVisible = visible;
264
+
265
+ if (visible && !this.indicatorRenderable) {
266
+ this.indicatorRenderable = scene.createRenderable(99, (target, camera) => {
267
+ if (this.indicatorsVisible) this.drawIndicators(target, camera);
268
+ })
269
+ }
270
+ }
271
+
272
+ getButtonHandler(button: MultiplayerButton, event: ControllerButtonEvent) {
273
+ for (const handler of this.buttonHandlers) {
274
+ if (handler.button === button && handler.event === event) return handler;
275
+ }
276
+ return undefined;
277
+ }
278
+
279
+ getControllerEventHandler(event: ControllerEvent) {
280
+ for (const handler of this.controllerEventHandlers) {
281
+ if (handler.event === event) return handler;
282
+ }
283
+ return undefined;
284
+ }
285
+
286
+
287
+ getScoreHandler(score: number) {
288
+ for (const handler of this.scoreHandlers) {
289
+ if (handler.target === score) return handler;
290
+ }
291
+ return undefined;
292
+ }
293
+
294
+ drawIndicators(target: Image, camera: scene.Camera) {
295
+ for (const player of this.players) {
296
+ const sprite = player.getSprite();
297
+
298
+ if (!sprite || sprite.flags & (sprites.Flag.Destroyed | sprites.Flag.Invisible)) {
299
+ continue;
300
+ }
301
+
302
+ let top = Fx.toInt(sprite._hitbox.top)
303
+ let bottom = Fx.toInt(sprite._hitbox.bottom)
304
+ let left = Fx.toInt(sprite._hitbox.left)
305
+ let right = Fx.toInt(sprite._hitbox.right)
306
+
307
+ if (!(sprite.flags & sprites.Flag.RelativeToCamera)) {
308
+ top -= camera.drawOffsetY;
309
+ bottom -= camera.drawOffsetY;
310
+ left -= camera.drawOffsetX;
311
+ right -= camera.drawOffsetX;
312
+ }
313
+
314
+ if (left < 0) {
315
+ const indicator = _indicatorForPlayer(player.number, CollisionDirection.Right);
316
+ target.drawTransparentImage(
317
+ indicator,
318
+ Math.max(right + 2, 0),
319
+ Math.min(
320
+ Math.max(
321
+ (top + ((bottom - top) >> 1) - (indicator.height >> 1)),
322
+ 0
323
+ ),
324
+ screen.height - indicator.height
325
+ )
326
+ )
327
+ }
328
+ else if (right > 160) {
329
+ const indicator = _indicatorForPlayer(player.number, CollisionDirection.Left);
330
+ target.drawTransparentImage(
331
+ indicator,
332
+ Math.min(left - indicator.width - 2, screen.width - indicator.width),
333
+ Math.min(
334
+ Math.max(
335
+ (top + ((bottom - top) >> 1) - (indicator.height >> 1)),
336
+ 0
337
+ ),
338
+ screen.height - indicator.height
339
+ )
340
+ )
341
+ }
342
+ else if (top < 18) {
343
+ const indicator = _indicatorForPlayer(player.number, CollisionDirection.Bottom);
344
+ target.drawTransparentImage(
345
+ indicator,
346
+ (left + ((right - left) >> 1) - (indicator.width >> 1)),
347
+ Math.max(bottom + 2, 0)
348
+ )
349
+ }
350
+ else {
351
+ const indicator = _indicatorForPlayer(player.number, CollisionDirection.Top);
352
+ target.drawTransparentImage(
353
+ indicator,
354
+ (left + ((right - left) >> 1) - (indicator.width >> 1)),
355
+ Math.min(top - indicator.height - 2, screen.height - indicator.height)
356
+ )
357
+ }
358
+ }
359
+ }
360
+ }
361
+
362
+ let stateStack: MPState[];
363
+
364
+ function init() {
365
+ if (stateStack) return;
366
+ stateStack = [new MPState()];
367
+ game.addScenePushHandler(() => {
368
+ stateStack.push(new MPState());
369
+ });
370
+ game.addScenePopHandler(() => {
371
+ stateStack.pop();
372
+ if (stateStack.length === 0) stateStack.push(new MPState());
373
+ });
374
+ }
375
+
376
+ export function _mpstate() {
377
+ init();
378
+ return stateStack[stateStack.length - 1];
379
+ }
380
+
381
+ function getButton(ctrl: controller.Controller, button: MultiplayerButton) {
382
+ switch (button) {
383
+ case MultiplayerButton.A: return ctrl.A;
384
+ case MultiplayerButton.B: return ctrl.B;
385
+ case MultiplayerButton.Up: return ctrl.up;
386
+ case MultiplayerButton.Right: return ctrl.right;
387
+ case MultiplayerButton.Down: return ctrl.down;
388
+ case MultiplayerButton.Left: return ctrl.left;
389
+ }
390
+ }
391
+
392
+ /**
393
+ * Gets the sprite of the player
394
+ * @param player The player to get the sprite of
395
+ * @returns The sprite of the player, or undefined if the player has no assigned sprite
396
+ */
397
+ //% blockId=mp_getPlayerSprite
398
+ //% block="$player sprite"
399
+ //% player.shadow=mp_playerSelector
400
+ //% group=Sprites
401
+ //% weight=100
402
+ //% blockGap=8
403
+ //% help=multiplayer/get-player-sprite
404
+ //% parts="multiplayer"
405
+ export function getPlayerSprite(player: Player): Sprite {
406
+ return player.getSprite();
407
+ }
408
+
409
+ /**
410
+ * Sets the sprite of the player
411
+ * @param player The player to set the sprite for
412
+ * @param sprite The sprite to set
413
+ */
414
+ //% blockId=mp_setPlayerSprite
415
+ //% block="set $player sprite to $sprite"
416
+ //% player.shadow=mp_playerSelector
417
+ //% sprite.shadow=spritescreate
418
+ //% group=Sprites
419
+ //% weight=100
420
+ //% blockGap=8
421
+ //% help=multiplayer/set-player-sprite
422
+ //% parts="multiplayer"
423
+ export function setPlayerSprite(player: Player, sprite: Sprite) {
424
+ player.setSprite(sprite);
425
+ }
426
+
427
+ /**
428
+ * Control a player's sprite with directional buttons
429
+ * @param player The player to control
430
+ * @param vx The horizontal velocity of the sprite (optional)
431
+ * @param vy The vertical velocity of the sprite (optional)
432
+ */
433
+ //% blockId=mp_moveWithButtons
434
+ //% block="move $player with buttons||vx $vx vy $vy"
435
+ //% player.shadow=mp_playerSelector
436
+ //% vx.defl=100
437
+ //% vy.defl=100
438
+ //% vx.shadow="spriteSpeedPicker"
439
+ //% vy.shadow="spriteSpeedPicker"
440
+ //% expandableArgumentMode="toggle"
441
+ //% inlineInputMode=inline
442
+ //% group=Controller
443
+ //% weight=100
444
+ //% blockGap=8
445
+ //% help=controller/move-sprite
446
+ //% parts="multiplayer"
447
+ export function moveWithButtons(player: Player, vx?: number, vy?: number) {
448
+ player.moveWithButtons(vx, vy);
449
+ }
450
+
451
+ /**
452
+ * Runs code when a button on any controller is pressed, released, or held
453
+ * @param button The button to listen for
454
+ * @param event The event to listen for (pressed, released, or held)
455
+ * @param handler The code to run when the button is pressed, released, or held
456
+ */
457
+ //% blockId=mp_onButtonEvent
458
+ //% block="on $button button $event for $player"
459
+ //% draggableParameters=reporter
460
+ //% group=Controller
461
+ //% weight=90
462
+ //% blockGap=8
463
+ //% help=controller/on-button-event
464
+ //% parts="multiplayer"
465
+ export function onButtonEvent(button: MultiplayerButton, event: ControllerButtonEvent, handler: (player: Player) => void) {
466
+ _mpstate().onButtonEvent(button, event, handler);
467
+ }
468
+
469
+ /**
470
+ * Queries the state of a button on a controller
471
+ * @param player The player to query
472
+ * @param button The button to query
473
+ * @returns true if the button is pressed
474
+ */
475
+ //% blockId=mp_isButtonPressed
476
+ //% block="is $player $button button pressed"
477
+ //% player.shadow=mp_playerSelector
478
+ //% group=Controller
479
+ //% weight=80
480
+ //% blockGap=8
481
+ //% help=controller/button/is-pressed
482
+ //% parts="multiplayer"
483
+ export function isButtonPressed(player: Player, button: MultiplayerButton): boolean {
484
+ return getButton(player._getController(), button).isPressed();
485
+ }
486
+
487
+ /**
488
+ * Runs code when a controller is connected or disconnected
489
+ * @param event The event to listen for (controller connected or disconnected)
490
+ * @param handler Code to run when the event is raised
491
+ */
492
+ //% blockId=mp_onControllerEvent
493
+ //% block="on $player $event"
494
+ //% draggableParameters=reporter
495
+ //% group=Controller
496
+ //% weight=70
497
+ //% blockGap=8
498
+ //% help=controller/on-event
499
+ //% parts="multiplayer"
500
+ export function onControllerEvent(event: ControllerEvent, handler: (player: Player) => void) {
501
+ _mpstate().onControllerEvent(event, handler);
502
+ }
503
+
504
+ /**
505
+ * Gets the value of the specified player state
506
+ * @param player The player to get the state for
507
+ * @param state The state to get
508
+ * @returns The value of the state
509
+ */
510
+ //% blockId=mp_getPlayerState
511
+ //% block="$player $state"
512
+ //% player.shadow=mp_playerSelector
513
+ //% state.shadow=mp_multiplayerstate
514
+ //% group=Info
515
+ //% weight=100
516
+ //% blockGap=8
517
+ //% help=multiplayer/get-player-state
518
+ //% parts="multiplayer"
519
+ export function getPlayerState(player: Player, state: number): number {
520
+ return player.getState(state);
521
+ }
522
+
523
+ /**
524
+ * Sets the value of the specified player state
525
+ * @param player The player to set the state for
526
+ * @param state The state to set
527
+ * @param value The value to set the state to
528
+ */
529
+ //% blockId=mp_setPlayerState
530
+ //% block="set $player $state to $value"
531
+ //% player.shadow=mp_playerSelector
532
+ //% state.shadow=mp_multiplayerstate
533
+ //% group=Info
534
+ //% weight=90
535
+ //% blockGap=8
536
+ //% help=multiplayer/set-player-state
537
+ //% parts="multiplayer"
538
+ export function setPlayerState(player: Player, state: number, value: number) {
539
+ player.setState(state, value);
540
+ }
541
+
542
+ /**
543
+ * Changes the value of the specified player state
544
+ * @param player The player to change the state for
545
+ * @param state The state to change
546
+ * @param delta The amount to change the state by
547
+ */
548
+ //% blockId=mp_changePlayerStateBy
549
+ //% block="change $player $state by $delta"
550
+ //% player.shadow=mp_playerSelector
551
+ //% state.shadow=mp_multiplayerstate
552
+ //% delta.defl=1
553
+ //% group=Info
554
+ //% weight=80
555
+ //% blockGap=8
556
+ //% help=multiplayer/change-player-state-by
557
+ //% parts="multiplayer"
558
+ export function changePlayerStateBy(player: Player, state: number, delta: number) {
559
+ player.setState(state, player.getState(state) + delta);
560
+ }
561
+
562
+ /**
563
+ * Gets a property of the player
564
+ * @param player The player to get the property of
565
+ * @param prop The property to get
566
+ * @returns The value of the property
567
+ */
568
+ //% blockId=mp_getPlayerProperty
569
+ //% block="$player $prop"
570
+ //% player.shadow=mp_playerSelector
571
+ //% group=Info
572
+ //% weight=100
573
+ //% blockGap=8
574
+ //% help=multiplayer/get-player-property
575
+ //% parts="multiplayer"
576
+ export function getPlayerProperty(player: Player, prop: PlayerProperty): number {
577
+ return player.getProperty(prop);
578
+ }
579
+
580
+ /**
581
+ * Runs code once each time a player's score reaches a given value.
582
+ * @param score The score to check for, eg: 100
583
+ * @param handler The code to run when the score is reached
584
+ */
585
+ //% blockId=mp_onScore
586
+ //% block="on score $score for $player"
587
+ //% score.defl=100
588
+ //% draggableParameters=reporter
589
+ //% group=Info
590
+ //% weight=70
591
+ //% blockGap=8
592
+ //% help=info/on-score
593
+ //% parts="multiplayer"
594
+ export function onScore(score: number, handler: (player: Player) => void) {
595
+ _mpstate().onReachedScore(score, handler);
596
+ }
597
+
598
+ /**
599
+ * Runs code when a player's number of lives reaches zero
600
+ * @param handler The code to run when the lives reach zero
601
+ */
602
+ //% blockId=mp_onLifeZero
603
+ //% block="on life zero for $player"
604
+ //% draggableParameters=reporter
605
+ //% group=Info
606
+ //% weight=60
607
+ //% blockGap=8
608
+ //% help=info/on-life-zero
609
+ //% parts="multiplayer"
610
+ export function onLifeZero(handler: (player: Player) => void) {
611
+ _mpstate().onLifeZero(handler);
612
+ }
613
+
614
+ /**
615
+ * Gets the player by number
616
+ * @param number The one-based number of the player
617
+ * @returns Player, or undefined if not found
618
+ */
619
+ //% blockId=mp_getPlayerByNumber
620
+ //% block="player $number"
621
+ //% number.shadow=variables_get
622
+ //% number.defl=number
623
+ //% group=Utility
624
+ //% weight=80
625
+ //% blockGap=8
626
+ //% help=multiplayer/get-player-by-number
627
+ //% parts="multiplayer"
628
+ export function getPlayerByNumber(number: number): Player {
629
+ const index = number - 1;
630
+ return getPlayerByIndex(index);
631
+ }
632
+
633
+ /**
634
+ * Gets the player by index
635
+ * @param index The zero-based index of the player
636
+ * @returns Player, or undefined if not found
637
+ */
638
+ //% blockId=mp_getPlayerByIndex
639
+ //% block="player at $index"
640
+ //% index.shadow=variables_get
641
+ //% index.defl=index
642
+ //% group=Utility
643
+ //% weight=80
644
+ //% blockGap=8
645
+ //% help=multiplayer/get-player-by-index
646
+ //% parts="multiplayer"
647
+ export function getPlayerByIndex(index: number): Player {
648
+ if (index < 0 || index >= MAX_PLAYERS) return undefined;
649
+ return _mpstate().players[index];
650
+ }
651
+
652
+ /**
653
+ * Selects one of the players by number
654
+ * @param number The player number
655
+ * @returns The player
656
+ */
657
+ //% blockId=mp_playerSelector
658
+ //% block="player $number"
659
+ //% group=Utility
660
+ //% weight=80
661
+ //% blockGap=8
662
+ //% help=multiplayer/player-selector
663
+ //% parts="multiplayer"
664
+ export function playerSelector(number: PlayerNumber): Player {
665
+ const index = number - 1;
666
+ return getPlayerByIndex(index);
667
+ }
668
+
669
+ /**
670
+ * Gets the player the sprite is assigned to
671
+ * @param sprite the sprite
672
+ * @returns Player, or undefined if not found
673
+ */
674
+ //% blockId=mp_getPlayerBySprite
675
+ //% block="$sprite player"
676
+ //% sprite.shadow=variables_get
677
+ //% sprite.defl=mySprite
678
+ //% group=Sprites
679
+ //% weight=90
680
+ //% blockGap=8
681
+ //% help=multiplayer/get-player-by-sprite
682
+ //% parts="multiplayer"
683
+ export function getPlayerBySprite(sprite: Sprite): Player {
684
+ for (const player of _mpstate().players) {
685
+ if (player.getSprite() === sprite) return player;
686
+ }
687
+ return undefined;
688
+ }
689
+
690
+ /**
691
+ * Turns player indicators on or off
692
+ * @param visible indicator visibility
693
+ */
694
+ //% blockId=mp_setPlayerIndicatorsVisible
695
+ //% block="set player indicators $visible"
696
+ //% visible.shadow=toggleOnOff
697
+ //% visible.defl=true
698
+ //% group=Utility
699
+ //% weight=100
700
+ //% blockGap=8
701
+ //% help=multiplayer/set-player-indicators-visible
702
+ //% parts="multiplayer"
703
+ export function setPlayerIndicatorsVisible(visible: boolean) {
704
+ _mpstate().setPlayerIndicatorsVisible(visible);
705
+ }
706
+ }
@@ -5,7 +5,7 @@
5
5
  "README.md",
6
6
  "fieldEditors.ts",
7
7
  "images.ts",
8
- "mp.ts",
8
+ "player.ts",
9
9
  "stateKind.ts",
10
10
  "targetoverrides.ts"
11
11
  ],