pxt-common-packages 10.3.7 → 10.3.9

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 (51) hide show
  1. package/libs/azureiot/built/debug/binary.js +461 -461
  2. package/libs/color/built/debug/binary.js +8 -8
  3. package/libs/color-sensor/built/debug/binary.js +8 -8
  4. package/libs/controller/built/debug/binary.js +15483 -15338
  5. package/libs/controller---none/built/debug/binary.js +15467 -15322
  6. package/libs/datalogger/built/debug/binary.js +63 -63
  7. package/libs/edge-connector/built/debug/binary.js +8 -8
  8. package/libs/esp32/built/debug/binary.js +462 -462
  9. package/libs/game/_locales/game-jsdoc-strings.json +8 -3
  10. package/libs/game/_locales/game-strings.json +11 -0
  11. package/libs/game/ask.ts +0 -1
  12. package/libs/game/built/debug/binary.js +16092 -15947
  13. package/libs/game/controller.ts +0 -6
  14. package/libs/game/game.ts +194 -45
  15. package/libs/game/gameutil.ts +0 -2
  16. package/libs/game/info.ts +98 -45
  17. package/libs/game/multiplayer.ts +9 -8
  18. package/libs/game/ns.ts +5 -0
  19. package/libs/game/numberprompt.ts +0 -1
  20. package/libs/game/particleeffects.ts +30 -0
  21. package/libs/game/prompt.ts +0 -1
  22. package/libs/game/pxt.json +1 -0
  23. package/libs/game/textDialogs.ts +275 -40
  24. package/libs/lcd/built/debug/binary.js +8 -8
  25. package/libs/light-spectrum-sensor/built/debug/binary.js +8 -8
  26. package/libs/lora/built/debug/binary.js +8 -8
  27. package/libs/matrix-keypad/built/debug/binary.js +8 -8
  28. package/libs/mixer/instrument.ts +20 -1
  29. package/libs/mixer/melody.ts +13 -15
  30. package/libs/mixer/playable.ts +181 -0
  31. package/libs/mixer/pxt.json +1 -0
  32. package/libs/mixer/soundEffect.ts +19 -2
  33. package/libs/mqtt/built/debug/binary.js +176 -176
  34. package/libs/multiplayer/ns.ts +6 -0
  35. package/libs/multiplayer/player.ts +24 -6
  36. package/libs/multiplayer/pxt.json +1 -0
  37. package/libs/music/ns.ts +1 -1
  38. package/libs/net/built/debug/binary.js +176 -176
  39. package/libs/net-game/built/debug/binary.js +20403 -20258
  40. package/libs/palette/built/debug/binary.js +16083 -15938
  41. package/libs/pixel/built/debug/binary.js +8 -8
  42. package/libs/power/built/debug/binary.js +8 -8
  43. package/libs/proximity/built/debug/binary.js +8 -8
  44. package/libs/radio/built/debug/binary.js +8 -8
  45. package/libs/radio-broadcast/built/debug/binary.js +8 -8
  46. package/libs/rotary-encoder/built/debug/binary.js +8 -8
  47. package/libs/screen/built/debug/binary.js +50 -50
  48. package/libs/servo/built/debug/binary.js +8 -8
  49. package/libs/sprite-scaling/built/debug/binary.js +16091 -15946
  50. package/libs/storyboard/built/debug/binary.js +16091 -15946
  51. package/package.json +1 -1
@@ -165,7 +165,6 @@ namespace controller {
165
165
  //% vx.shadow="spriteSpeedPicker"
166
166
  //% vy.shadow="spriteSpeedPicker"
167
167
  //% parts="multiplayer"
168
- //% deprecated=true
169
168
  moveSprite(sprite: Sprite, vx: number = 100, vy: number = 100) {
170
169
  this._moveSpriteInternal(sprite, vx, vy);
171
170
  }
@@ -202,7 +201,6 @@ namespace controller {
202
201
  //% group="Multiplayer"
203
202
  //% help=controller/on-button-event
204
203
  //% parts="multiplayer"
205
- //% deprecated=true
206
204
  onButtonEvent(btn: ControllerButton, event: ControllerButtonEvent, handler: () => void) {
207
205
  this.button(btn).onEvent(event, handler);
208
206
  }
@@ -217,7 +215,6 @@ namespace controller {
217
215
  //% group="Multiplayer"
218
216
  //% help=controller/on-event
219
217
  //% parts="multiplayer"
220
- //% deprecated=true
221
218
  onEvent(event: ControllerEvent, handler: () => void) {
222
219
  control.onEvent(this.id, event, handler);
223
220
  }
@@ -240,7 +237,6 @@ namespace controller {
240
237
  //% blockId=ctrlispressed block="is %controller %button **button** pressed"
241
238
  //% group="Multiplayer"
242
239
  //% parts="multiplayer"
243
- //% deprecated=true
244
240
  isPressed(btn: ControllerButton): boolean {
245
241
  return this.button(btn).isPressed();
246
242
  }
@@ -254,7 +250,6 @@ namespace controller {
254
250
  //% step.defl=100
255
251
  //% group="Multiplayer"
256
252
  //% parts="multiplayer"
257
- //% deprecated=true
258
253
  dx(step: number = 100) {
259
254
  return this._dxInternal(step);
260
255
  }
@@ -284,7 +279,6 @@ namespace controller {
284
279
  //% step.defl=100
285
280
  //% group="Multiplayer"
286
281
  //% parts="multiplayer"
287
- //% deprecated=true
288
282
  dy(step: number = 100) {
289
283
  return this._dyInternal(step);
290
284
  }
package/libs/game/game.ts CHANGED
@@ -1,18 +1,102 @@
1
1
  /**
2
2
  * Game transitions and dialog
3
3
  **/
4
- //% color=#8854d0 weight=97 icon="\uf111"
5
- //% groups='["Gameplay", "Prompt"]'
6
4
  namespace game {
7
5
  /**
8
6
  * Determines if diagnostics are shown
9
7
  */
10
8
  export let debug = false;
11
9
  export let stats = false;
12
- export let winEffect: effects.BackgroundEffect = undefined;
13
- export let loseEffect: effects.BackgroundEffect = undefined;
14
- let loseSound: music.Melody = undefined;
15
- let winSound: music.Melody = undefined;
10
+
11
+ export enum ScoringType {
12
+ //% block="high score"
13
+ HighScore,
14
+ //% block="low score"
15
+ LowScore,
16
+ //% block="none"
17
+ None
18
+ }
19
+
20
+ export class GameOverConfig {
21
+ scoringType: ScoringType;
22
+ winEffect: effects.BackgroundEffect;
23
+ loseEffect: effects.BackgroundEffect;
24
+ loseSound: music.Melody;
25
+ winSound: music.Melody;
26
+ winMessage: string;
27
+ winMessageMultiplayer: string;
28
+ loseMessage: string;
29
+ effectSetByUser: boolean;
30
+ soundSetByUser: boolean;
31
+ messageSetByUser: boolean;
32
+ scoringTypeSetByUser: boolean;
33
+
34
+ constructor() {
35
+ this.init();
36
+ }
37
+
38
+ init() {
39
+ this.scoringType = ScoringType.HighScore;
40
+ this.winEffect = effects.confetti;
41
+ this.loseEffect = effects.melt;
42
+ this.winSound = music.powerUp;
43
+ this.loseSound = music.wawawawaa;
44
+ this.winMessage = "YOU WIN!";
45
+ this.winMessageMultiplayer = "${WINNER} WINS!";
46
+ this.loseMessage = "GAME OVER";
47
+ this.effectSetByUser = false;
48
+ this.soundSetByUser = false;
49
+ this.messageSetByUser = false;
50
+ this.scoringTypeSetByUser = false;
51
+ }
52
+
53
+ setScoringType(type: ScoringType, explicit?: boolean) {
54
+ if (!explicit && this.scoringTypeSetByUser) return;
55
+ this.scoringType = type;
56
+ if (explicit) this.scoringTypeSetByUser = true;
57
+ }
58
+
59
+ setEffect(win: boolean, effect: effects.BackgroundEffect, explicit?: boolean) {
60
+ if (!explicit && this.effectSetByUser) return;
61
+ if (win) this.winEffect = effect;
62
+ else this.loseEffect = effect;
63
+ if (explicit) this.effectSetByUser = true;
64
+ }
65
+ getEffect(win: boolean) {
66
+ return win ? this.winEffect : this.loseEffect;
67
+ }
68
+
69
+ setSound(win: boolean, sound: music.Melody, explicit?: boolean) {
70
+ if (!explicit && this.soundSetByUser) return;
71
+ if (win) this.winSound = sound;
72
+ else this.loseSound = sound;
73
+ if (explicit) this.soundSetByUser = true;
74
+ }
75
+ getSound(win: boolean) {
76
+ return win ? this.winSound : this.loseSound;
77
+ }
78
+
79
+ setMessage(win: boolean, message: string, explicit?: boolean) {
80
+ if (!explicit && this.messageSetByUser) return;
81
+ if (win) this.winMessage = message;
82
+ else this.loseMessage = message;
83
+ if (explicit) this.messageSetByUser = true;
84
+ }
85
+ getMessage(win: boolean, preferMultiplayer?: boolean) {
86
+ if (this.messageSetByUser)
87
+ return win ? this.winMessage : this.loseMessage;
88
+ else if (preferMultiplayer)
89
+ return win ? this.winMessageMultiplayer : this.loseMessage;
90
+ else
91
+ return win ? this.winMessage : this.loseMessage;
92
+ }
93
+ }
94
+
95
+ let _gameOverConfig: GameOverConfig;
96
+ export const gameOverConfig = () => {
97
+ if (!_gameOverConfig) _gameOverConfig = new GameOverConfig();
98
+ return _gameOverConfig;
99
+ }
16
100
 
17
101
  let _scene: scene.Scene;
18
102
  let _sceneStack: scene.Scene[];
@@ -48,16 +132,6 @@ namespace game {
48
132
  _scene = new scene.Scene(control.pushEventContext(), _scene);
49
133
  }
50
134
  _scene.init();
51
-
52
- if (!winEffect)
53
- winEffect = effects.confetti;
54
- if (!loseEffect)
55
- loseEffect = effects.melt;
56
-
57
- if (!winSound)
58
- winSound = music.powerUp;
59
- if (!loseSound)
60
- loseSound = music.wawawawaa;
61
135
  }
62
136
 
63
137
  export function pushScene() {
@@ -139,31 +213,81 @@ namespace game {
139
213
 
140
214
  /**
141
215
  * Set the effect that occurs when the game is over
142
- * @param win whether the animation should run on a win (true)
216
+ * @param win whether the effect should run on a win (true) or lose (false)
143
217
  * @param effect
144
218
  */
219
+ //% blockId=game_setgameovereffect
220
+ //% block="use effect $effect for $win"
221
+ //% effect.defl=effects.confetti
222
+ //% win.shadow=toggleWinLose
223
+ //% win.defl=true
224
+ //% group="Game Over"
225
+ //% weight=80
226
+ //% blockGap=8
227
+ //% help=game/set-game-over-effect
145
228
  export function setGameOverEffect(win: boolean, effect: effects.BackgroundEffect) {
146
229
  init();
147
- if (!effect) return;
148
- if (win)
149
- winEffect = effect;
150
- else
151
- loseEffect = effect;
230
+ const goc = game.gameOverConfig();
231
+ goc.setEffect(win, effect, true);
152
232
  }
153
233
 
154
234
  /**
155
- * Set the music that occurs when the player wins
156
- * @param win
235
+ * Set the music that occurs when the game is over
236
+ * @param win whether the sound should play on a win (true) or lose (false)
157
237
  * @param effect
158
238
  */
239
+ //% blockId=game_setgameoversound
240
+ //% block="use sound $sound for $win"
241
+ //% sound.defl=music.powerUp
242
+ //% win.shadow=toggleWinLose
243
+ //% win.defl=true
244
+ //% group="Game Over"
245
+ //% weight=80
246
+ //% blockGap=8
247
+ //% help=game/set-game-over-sound
159
248
  export function setGameOverSound(win: boolean, sound: music.Melody) {
160
249
  init();
161
- if (!sound) return;
162
- if (win)
163
- winSound = sound;
164
- else
165
- loseSound = sound;
250
+ const goc = game.gameOverConfig();
251
+ goc.setSound(win, sound, true);
166
252
  }
253
+
254
+ /**
255
+ * Set the message that displays when the game is over
256
+ * @param win whether the message should show on a win (true) or lose (false)
257
+ * @param message
258
+ */
259
+ //% blockId=game_setgameovermessage
260
+ //% block="use message $message for $win"
261
+ //% message.defl="GAME OVER!"
262
+ //% win.shadow=toggleWinLose
263
+ //% win.defl=true
264
+ //% group="Game Over"
265
+ //% weight=80
266
+ //% blockGap=8
267
+ //% help=game/set-game-over-message
268
+ export function setGameOverMessage(win: boolean, message: string) {
269
+ init();
270
+ const goc = game.gameOverConfig();
271
+ goc.setMessage(win, message, true);
272
+ }
273
+
274
+ /**
275
+ * Set the method of judging the best score for the game
276
+ * @param type the scoring type
277
+ */
278
+ //% blockId=game_setgameoverscoringtype
279
+ //% block="use $type as best score"
280
+ //% type.defl=ScoringType.HighScore
281
+ //% group="Game Over"
282
+ //% weight=80
283
+ //% blockGap=8
284
+ //% help=game/set-game-over-scoring-type
285
+ export function setGameOverScoringType(type: ScoringType) {
286
+ init();
287
+ const goc = game.gameOverConfig();
288
+ goc.setScoringType(type, true);
289
+ }
290
+
167
291
  /**
168
292
  * Set the function to call on game over. The 'win' boolean is
169
293
  * passed to the handler.
@@ -179,7 +303,30 @@ namespace game {
179
303
  //% group="Gameplay"
180
304
  //% blockId=gameOver block="game over %win=toggleWinLose || with %effect effect"
181
305
  //% weight=80 help=game/over
306
+ //% deprecated=true
182
307
  export function over(win: boolean = false, effect?: effects.BackgroundEffect) {
308
+ // Match legacy behavior unless effect was set by user
309
+ const goc = game.gameOverConfig();
310
+ goc.setEffect(win, effect, false);
311
+ _gameOverImpl(win);
312
+ }
313
+
314
+ //% blockId=gameOver2 block="game over $win"
315
+ //% win.shadow=toggleWinLose
316
+ //% win.defl=true
317
+ //% weight=80
318
+ //% blockGap=8
319
+ //% help=game/over
320
+ //% group="Game Over"
321
+ export function gameOver(win: boolean) {
322
+ _gameOverImpl(win);
323
+ }
324
+
325
+ export function gameOverPlayerWin(player: number) {
326
+ _gameOverImpl(true, player);
327
+ }
328
+
329
+ function _gameOverImpl(win: boolean, winnerOverride?: number) {
183
330
  init();
184
331
  if (__isOver) return;
185
332
  __isOver = true;
@@ -187,18 +334,24 @@ namespace game {
187
334
  if (__gameOverHandler) {
188
335
  __gameOverHandler(win);
189
336
  } else {
190
- if (!effect) {
191
- effect = win ? winEffect : loseEffect;
192
- }
337
+ const goc = game.gameOverConfig();
193
338
 
194
- // Save all scores as relevant to the game.
195
- info.saveAllScores();
339
+ const judged = !winnerOverride && goc.scoringType !== ScoringType.None;
340
+ const playersWithScores = info.playersWithScores();
341
+ const prevBestScore = judged && info.highScore();
342
+ const winner = judged && win && info.winningPlayer();
343
+ const scores = playersWithScores.map(player => new GameOverPlayerScore(player.number, player.impl.score(), player === winner));
196
344
 
197
- // collect the scores before poping the scenes
198
- const scoreInfo = info.player1.getState();
199
- const highScore = info.highScore();
200
- if (scoreInfo.score > highScore)
345
+ // Save scores if this was a judged game and there was a winner (don't save in the LOSE case).
346
+ if (judged && winner) {
347
+ info.saveAllScores();
201
348
  info.saveHighScore();
349
+ }
350
+
351
+ const preferMultiplayer = !!winnerOverride || (judged && info.multiplayerScoring());
352
+ const message = goc.getMessage(win, preferMultiplayer);
353
+ const effect = goc.getEffect(win);
354
+ const sound = goc.getSound(win);
202
355
 
203
356
  // releasing memory and clear fibers. Do not add anything that releases the fiber until background is set below,
204
357
  // or screen will be cleared on the new frame and will not appear as background in the game over screen.
@@ -209,16 +362,12 @@ namespace game {
209
362
  pushScene();
210
363
  scene.setBackgroundImage(screen.clone());
211
364
 
212
- if (win)
213
- winSound.play();
214
- else
215
- loseSound.play();
216
-
217
- effect.startScreenEffect();
365
+ if (sound) sound.play();
366
+ if (effect) effect.startScreenEffect();
218
367
 
219
368
  pause(400);
220
369
 
221
- const overDialog = new GameOverDialog(win, scoreInfo.score, highScore);
370
+ const overDialog = new GameOverDialog(win, message, judged, scores, prevBestScore, winnerOverride);
222
371
  scene.createRenderable(scene.HUD_Z, target => {
223
372
  overDialog.update();
224
373
  target.drawTransparentImage(
@@ -1,8 +1,6 @@
1
1
  /**
2
2
  * Game transitions and dialog
3
3
  **/
4
- //% color=#8854d0 weight=97 icon="\uf111"
5
- //% groups='["Gameplay", "Prompt"]'
6
4
  namespace game {
7
5
 
8
6
  /**
package/libs/game/info.ts CHANGED
@@ -35,7 +35,17 @@ namespace info {
35
35
  public lifeZeroHandler: () => void;
36
36
  public scoreReachedHandler: ScoreReachedHandler
37
37
 
38
- constructor() { }
38
+ public showScore?: boolean;
39
+ public showLife?: boolean;
40
+ public visibility: Visibility;
41
+ public showPlayer?: boolean;
42
+
43
+ constructor() {
44
+ this.visibility = Visibility.None;
45
+ this.showScore = undefined;
46
+ this.showLife = undefined;
47
+ this.showPlayer = undefined;
48
+ }
39
49
  }
40
50
 
41
51
  class InfoState {
@@ -148,7 +158,11 @@ namespace info {
148
158
  if (infoState.countdownEndHandler) {
149
159
  infoState.countdownEndHandler();
150
160
  } else {
151
- game.over();
161
+ // Clear effect and sound, unless set by user
162
+ const goc = game.gameOverConfig();
163
+ goc.setEffect(false, null, false);
164
+ goc.setSound(false, null, false);
165
+ game.gameOver(false);
152
166
  }
153
167
  }
154
168
  }
@@ -212,11 +226,26 @@ namespace info {
212
226
  `;
213
227
  }
214
228
 
229
+ export function multiplayerScoring() {
230
+ const pws = playersWithScores();
231
+ for (const p of pws) {
232
+ if (p.number > 1) {
233
+ return true;
234
+ }
235
+ }
236
+ return false;
237
+ }
238
+
239
+ export function playersWithScores(): PlayerInfo[] {
240
+ return players ? players.filter(item => item.impl.hasScore()) : [];
241
+ }
242
+
215
243
  export function saveAllScores() {
216
244
  const allScoresKey = "all-scores";
217
245
  let allScores: number[];
218
- if (players) {
219
- allScores = players.filter(item => item.impl.hasScore()).map(item => item.impl.score());
246
+ const pws = playersWithScores();
247
+ if (pws) {
248
+ allScores = pws.map(item => item.impl.score());
220
249
  }
221
250
  else {
222
251
  allScores = [];
@@ -225,15 +254,44 @@ namespace info {
225
254
  settings.writeJSON(allScoresKey, allScores);
226
255
  }
227
256
 
257
+ export function winningPlayer(): PlayerInfo {
258
+ let winner: PlayerInfo = null;
259
+ const pws = playersWithScores();
260
+ if (pws) {
261
+ const goc = game.gameOverConfig();
262
+ let hs: number = null;
263
+ pws.forEach(p => {
264
+ const s = p.impl.score();
265
+ if (isBetterScore(s, hs)) {
266
+ hs = s;
267
+ winner = p;
268
+ }
269
+ });
270
+ }
271
+ return winner;
272
+ }
273
+
274
+ export function isBetterScore(newScore: number, prevScore: number): boolean {
275
+ const goc = game.gameOverConfig();
276
+ switch (goc.scoringType) {
277
+ case game.ScoringType.HighScore: {
278
+ return prevScore == null || newScore > prevScore;
279
+ }
280
+ case game.ScoringType.LowScore: {
281
+ return prevScore == null || newScore < prevScore;
282
+ }
283
+ }
284
+ return false;
285
+ }
286
+
228
287
  export function saveHighScore() {
229
- if (players) {
230
- let hs = 0;
231
- players
232
- .filter(p => p && p.impl.hasScore())
233
- .forEach(p => hs = Math.max(hs, p.impl.score()));
234
- const curr = settings.readNumber("high-score")
235
- if (curr == null || hs > curr)
288
+ const winner = winningPlayer();
289
+ if (winner) {
290
+ let hs = winner.impl.score();
291
+ let curr = settings.readNumber("high-score");
292
+ if (isBetterScore(hs, curr)) {
236
293
  settings.writeNumber("high-score", hs);
294
+ }
237
295
  }
238
296
  }
239
297
 
@@ -576,10 +634,6 @@ namespace info {
576
634
  public bg: number; // background color
577
635
  public border: number; // border color
578
636
  public fc: number; // font color
579
- public showScore?: boolean;
580
- public showLife?: boolean;
581
- public visibility: Visibility;
582
- public showPlayer?: boolean;
583
637
  public x?: number;
584
638
  public y?: number;
585
639
  public left?: boolean; // if true banner goes from x to the left, else goes rightward
@@ -589,10 +643,6 @@ namespace info {
589
643
  this._player = player;
590
644
  this.border = 1;
591
645
  this.fc = 1;
592
- this.visibility = Visibility.None;
593
- this.showScore = undefined;
594
- this.showLife = undefined;
595
- this.showPlayer = undefined;
596
646
  this.left = undefined;
597
647
  this.up = undefined;
598
648
  if (this._player === 1) {
@@ -640,11 +690,11 @@ namespace info {
640
690
  }
641
691
 
642
692
  score(): number {
643
- if (this.showScore === undefined) this.showScore = true;
644
- if (this.showPlayer === undefined) this.showPlayer = true;
645
-
646
693
  const state = this.getState();
647
694
 
695
+ if (state.showScore === undefined) state.showScore = true;
696
+ if (state.showPlayer === undefined) state.showPlayer = true;
697
+
648
698
  if (state.score == null)
649
699
  state.score = 0;
650
700
  return state.score;
@@ -680,8 +730,9 @@ namespace info {
680
730
 
681
731
  life(): number {
682
732
  const state = this.getState();
683
- if (this.showLife === undefined) this.showLife = true;
684
- if (this.showPlayer === undefined) this.showPlayer = true;
733
+
734
+ if (state.showLife === undefined) state.showLife = true;
735
+ if (state.showPlayer === undefined) state.showPlayer = true;
685
736
 
686
737
  if (state.life === undefined) {
687
738
  state.life = 3;
@@ -725,7 +776,11 @@ namespace info {
725
776
  if (state.lifeZeroHandler) {
726
777
  state.lifeZeroHandler();
727
778
  } else if (gameOver) {
728
- game.over();
779
+ // Clear effect and sound, unless set by user
780
+ const goc = game.gameOverConfig();
781
+ goc.setEffect(false, null, false);
782
+ goc.setSound(false, null, false);
783
+ game.gameOver(false);
729
784
  }
730
785
  }
731
786
  }
@@ -753,6 +808,13 @@ namespace info {
753
808
  }
754
809
  }
755
810
 
811
+ /**
812
+ * Returns the one-based number of the player
813
+ */
814
+ get number() {
815
+ return this._player;
816
+ }
817
+
756
818
  get bg(): number {
757
819
  return this.impl.bg;
758
820
  }
@@ -778,35 +840,35 @@ namespace info {
778
840
  }
779
841
 
780
842
  get showScore(): boolean {
781
- return this.impl.showScore;
843
+ return this.impl.getState().showScore;
782
844
  }
783
845
 
784
846
  set showScore(value: boolean) {
785
- this.impl.showScore = value;
847
+ this.impl.getState().showScore = value;
786
848
  }
787
849
 
788
850
  get showLife(): boolean {
789
- return this.impl.showLife;
851
+ return this.impl.getState().showLife;
790
852
  }
791
853
 
792
854
  set showLife(value: boolean) {
793
- this.impl.showLife = value;
855
+ this.impl.getState().showLife = value;
794
856
  }
795
857
 
796
858
  get visibility(): Visibility {
797
- return this.impl.visibility;
859
+ return this.impl.getState().visibility;
798
860
  }
799
861
 
800
862
  set visibility(value: Visibility) {
801
- this.impl.visibility = value;
863
+ this.impl.getState().visibility = value;
802
864
  }
803
865
 
804
866
  get showPlayer(): boolean {
805
- return this.impl.showPlayer;
867
+ return this.impl.getState().showPlayer;
806
868
  }
807
869
 
808
870
  set showPlayer(value: boolean) {
809
- this.impl.showPlayer = value;
871
+ this.impl.getState().showPlayer = value;
810
872
  }
811
873
 
812
874
  get x(): number {
@@ -858,7 +920,6 @@ namespace info {
858
920
  //% blockId=piscore block="%player score"
859
921
  //% help=info/score
860
922
  //% parts="multiplayer"
861
- //% deprecated=true
862
923
  score(): number {
863
924
  return this.impl.score();
864
925
  }
@@ -871,7 +932,6 @@ namespace info {
871
932
  //% value.defl=0
872
933
  //% help=info/set-score
873
934
  //% parts="multiplayer"
874
- //% deprecated=true
875
935
  setScore(value: number) {
876
936
  this.impl.setScore(value);
877
937
  }
@@ -885,7 +945,6 @@ namespace info {
885
945
  //% value.defl=1
886
946
  //% help=info/change-score-by
887
947
  //% parts="multiplayer"
888
- //% deprecated=true
889
948
  changeScoreBy(value: number): void {
890
949
  this.impl.changeScoreBy(value);
891
950
  }
@@ -901,7 +960,6 @@ namespace info {
901
960
  //% blockid=piflife block="%player life"
902
961
  //% help=info/life
903
962
  //% parts="multiplayer"
904
- //% deprecated=true
905
963
  life(): number {
906
964
  return this.impl.life();
907
965
  }
@@ -914,7 +972,6 @@ namespace info {
914
972
  //% value.defl=3
915
973
  //% help=info/set-life
916
974
  //% parts="multiplayer"
917
- //% deprecated=true
918
975
  setLife(value: number): void {
919
976
  this.impl.setLife(value);
920
977
  }
@@ -928,7 +985,6 @@ namespace info {
928
985
  //% value.defl=-1
929
986
  //% help=info/change-life-by
930
987
  //% parts="multiplayer"
931
- //% deprecated=true
932
988
  changeLifeBy(value: number): void {
933
989
  this.impl.changeLifeBy(value);
934
990
  }
@@ -942,7 +998,6 @@ namespace info {
942
998
  //% blockId=pihaslife block="%player has life"
943
999
  //% help=info/has-life
944
1000
  //% parts="multiplayer"
945
- //% deprecated=true
946
1001
  hasLife(): boolean {
947
1002
  return this.impl.hasLife();
948
1003
  }
@@ -955,7 +1010,6 @@ namespace info {
955
1010
  //% blockId=playerinfoonlifezero block="on %player life zero"
956
1011
  //% help=info/on-life-zero
957
1012
  //% parts="multiplayer"
958
- //% deprecated=true
959
1013
  onLifeZero(handler: () => void) {
960
1014
  this.impl.onLifeZero(handler);
961
1015
  }
@@ -974,7 +1028,6 @@ namespace info {
974
1028
  //% help=info/on-score
975
1029
  //% group="Multiplayer"
976
1030
  //% parts="multiplayer"
977
- //% deprecated=true
978
1031
  onScore(score: number, handler: () => void) {
979
1032
  this.impl.onScore(score, handler);
980
1033
  }
@@ -990,8 +1043,8 @@ namespace info {
990
1043
  let lifeWidth = 0;
991
1044
  const offsetX = 1;
992
1045
  let offsetY = 2;
993
- let showScore = this.impl.showScore && state.score !== undefined;
994
- let showLife = this.impl.showLife && state.life !== undefined;
1046
+ let showScore = state.showScore && state.score !== undefined;
1047
+ let showLife = state.showLife && state.life !== undefined;
995
1048
 
996
1049
  if (showScore) {
997
1050
  score = "" + state.score;
@@ -1053,7 +1106,7 @@ namespace info {
1053
1106
  }
1054
1107
 
1055
1108
  // print player icon
1056
- if (this.impl.showPlayer) {
1109
+ if (state.showPlayer) {
1057
1110
  const pNum = "" + this._player;
1058
1111
 
1059
1112
  let iconWidth = pNum.length * font.charWidth + 1;