pxt-common-packages 10.2.5 → 10.2.7
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/built/common-sim.d.ts +5 -0
- package/built/common-sim.js +28 -4
- package/libs/azureiot/built/debug/binary.js +461 -461
- package/libs/color/built/debug/binary.js +8 -8
- package/libs/color-sensor/built/debug/binary.js +8 -8
- package/libs/controller/built/debug/binary.js +6968 -6968
- package/libs/controller---none/built/debug/binary.js +6950 -6950
- package/libs/datalogger/built/debug/binary.js +63 -63
- package/libs/edge-connector/built/debug/binary.js +8 -8
- package/libs/esp32/built/debug/binary.js +462 -462
- package/libs/game/_locales/game-jsdoc-strings.json +1 -0
- package/libs/game/built/debug/binary.js +6889 -6889
- package/libs/game/controller.ts +27 -3
- package/libs/game/info.ts +263 -91
- package/libs/game/sim/multiplayer.ts +38 -8
- package/libs/lcd/built/debug/binary.js +8 -8
- package/libs/light-spectrum-sensor/built/debug/binary.js +8 -8
- package/libs/lora/built/debug/binary.js +8 -8
- package/libs/matrix-keypad/built/debug/binary.js +8 -8
- package/libs/mqtt/built/debug/binary.js +176 -176
- package/libs/net/built/debug/binary.js +176 -176
- package/libs/net-game/built/debug/binary.js +8478 -8478
- package/libs/palette/built/debug/binary.js +6888 -6888
- package/libs/pixel/built/debug/binary.js +8 -8
- package/libs/power/built/debug/binary.js +8 -8
- package/libs/proximity/built/debug/binary.js +8 -8
- package/libs/radio/built/debug/binary.js +8 -8
- package/libs/radio-broadcast/built/debug/binary.js +8 -8
- package/libs/rotary-encoder/built/debug/binary.js +8 -8
- package/libs/screen/built/debug/binary.js +50 -50
- package/libs/servo/built/debug/binary.js +8 -8
- package/libs/sprite-scaling/built/debug/binary.js +6888 -6888
- package/libs/storyboard/built/debug/binary.js +6888 -6888
- package/package.json +2 -2
package/libs/game/controller.ts
CHANGED
|
@@ -164,7 +164,14 @@ namespace controller {
|
|
|
164
164
|
//% group="Multiplayer"
|
|
165
165
|
//% vx.shadow="spriteSpeedPicker"
|
|
166
166
|
//% vy.shadow="spriteSpeedPicker"
|
|
167
|
+
//% parts="multiplayer"
|
|
167
168
|
moveSprite(sprite: Sprite, vx: number = 100, vy: number = 100) {
|
|
169
|
+
this._moveSpriteInternal(sprite, vx, vy);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// use this instead of movesprite internally to avoid adding the "multiplayer" part
|
|
173
|
+
// to the compiled program
|
|
174
|
+
_moveSpriteInternal(sprite: Sprite, vx: number = 100, vy: number = 100) {
|
|
168
175
|
if (!sprite) return;
|
|
169
176
|
if (!this._controlledSprites) this._controlledSprites = [];
|
|
170
177
|
let cp = this._controlledSprites.find(cp => cp.s.id == sprite.id);
|
|
@@ -193,6 +200,7 @@ namespace controller {
|
|
|
193
200
|
//% blockId=ctrlonbuttonevent block="on %controller %button **button** %event"
|
|
194
201
|
//% group="Multiplayer"
|
|
195
202
|
//% help=controller/on-button-event
|
|
203
|
+
//% parts="multiplayer"
|
|
196
204
|
onButtonEvent(btn: ControllerButton, event: ControllerButtonEvent, handler: () => void) {
|
|
197
205
|
this.button(btn).onEvent(event, handler);
|
|
198
206
|
}
|
|
@@ -206,6 +214,7 @@ namespace controller {
|
|
|
206
214
|
//% blockId=ctrlonevent block="on %controller %event"
|
|
207
215
|
//% group="Multiplayer"
|
|
208
216
|
//% help=controller/on-event
|
|
217
|
+
//% parts="multiplayer"
|
|
209
218
|
onEvent(event: ControllerEvent, handler: () => void) {
|
|
210
219
|
control.onEvent(this.id, event, handler);
|
|
211
220
|
}
|
|
@@ -227,6 +236,7 @@ namespace controller {
|
|
|
227
236
|
//% weight=96 blockGap=8 help=controller/button/is-pressed
|
|
228
237
|
//% blockId=ctrlispressed block="is %controller %button **button** pressed"
|
|
229
238
|
//% group="Multiplayer"
|
|
239
|
+
//% parts="multiplayer"
|
|
230
240
|
isPressed(btn: ControllerButton): boolean {
|
|
231
241
|
return this.button(btn).isPressed();
|
|
232
242
|
}
|
|
@@ -239,7 +249,14 @@ namespace controller {
|
|
|
239
249
|
//% blockId=ctrldx block="%controller dx (left-right buttons)||scaled by %step"
|
|
240
250
|
//% step.defl=100
|
|
241
251
|
//% group="Multiplayer"
|
|
252
|
+
//% parts="multiplayer"
|
|
242
253
|
dx(step: number = 100) {
|
|
254
|
+
return this._dxInternal(step);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// use this instead of dx internally to avoid adding the "multiplayer" part
|
|
258
|
+
// to the compiled program
|
|
259
|
+
_dxInternal(step: number = 100) {
|
|
243
260
|
const ctx = control.eventContext();
|
|
244
261
|
if (!ctx) return 0;
|
|
245
262
|
|
|
@@ -261,7 +278,14 @@ namespace controller {
|
|
|
261
278
|
//% blockId=ctrldy block="%controller dy (up-down buttons)||scaled by %step"
|
|
262
279
|
//% step.defl=100
|
|
263
280
|
//% group="Multiplayer"
|
|
281
|
+
//% parts="multiplayer"
|
|
264
282
|
dy(step: number = 100) {
|
|
283
|
+
return this._dyInternal(step);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// use this instead of dy internally to avoid adding the "multiplayer" part
|
|
287
|
+
// to the compiled program
|
|
288
|
+
_dyInternal(step: number = 100) {
|
|
265
289
|
const ctx = control.eventContext();
|
|
266
290
|
if (!ctx) return 0;
|
|
267
291
|
|
|
@@ -386,7 +410,7 @@ namespace controller {
|
|
|
386
410
|
//% vx.shadow=spriteSpeedPicker
|
|
387
411
|
//% vy.shadow=spriteSpeedPicker
|
|
388
412
|
export function moveSprite(sprite: Sprite, vx: number = 100, vy: number = 100) {
|
|
389
|
-
_player1().
|
|
413
|
+
_player1()._moveSpriteInternal(sprite, vx, vy);
|
|
390
414
|
}
|
|
391
415
|
|
|
392
416
|
/**
|
|
@@ -398,7 +422,7 @@ namespace controller {
|
|
|
398
422
|
//% step.defl=100
|
|
399
423
|
//% group="Single Player"
|
|
400
424
|
export function dx(step: number = 100) {
|
|
401
|
-
return _player1().
|
|
425
|
+
return _player1()._dxInternal(step);
|
|
402
426
|
}
|
|
403
427
|
|
|
404
428
|
/**
|
|
@@ -410,7 +434,7 @@ namespace controller {
|
|
|
410
434
|
//% step.defl=100
|
|
411
435
|
//% group="Single Player"
|
|
412
436
|
export function dy(step: number = 100) {
|
|
413
|
-
return _player1().
|
|
437
|
+
return _player1()._dyInternal(step);
|
|
414
438
|
}
|
|
415
439
|
|
|
416
440
|
class AnyButton extends Button {
|
package/libs/game/info.ts
CHANGED
|
@@ -121,18 +121,18 @@ namespace info {
|
|
|
121
121
|
// First draw players
|
|
122
122
|
ps.forEach(p => p.drawPlayer());
|
|
123
123
|
// Then run life over events
|
|
124
|
-
ps.forEach(p => p.raiseLifeZero(false));
|
|
124
|
+
ps.forEach(p => p.impl.raiseLifeZero(false));
|
|
125
125
|
} else { // single player
|
|
126
126
|
// show score
|
|
127
127
|
const p = player1;
|
|
128
|
-
if (p.hasScore() && (infoState.visibilityFlag & Visibility.Score)) {
|
|
128
|
+
if (p.impl.hasScore() && (infoState.visibilityFlag & Visibility.Score)) {
|
|
129
129
|
p.drawScore();
|
|
130
130
|
}
|
|
131
131
|
// show life
|
|
132
|
-
if (p.hasLife() && (infoState.visibilityFlag & Visibility.Life)) {
|
|
132
|
+
if (p.impl.hasLife() && (infoState.visibilityFlag & Visibility.Life)) {
|
|
133
133
|
p.drawLives();
|
|
134
134
|
}
|
|
135
|
-
p.raiseLifeZero(true);
|
|
135
|
+
p.impl.raiseLifeZero(true);
|
|
136
136
|
}
|
|
137
137
|
// show countdown in both modes
|
|
138
138
|
if (infoState.gameEnd !== undefined && infoState.visibilityFlag & Visibility.Countdown) {
|
|
@@ -216,7 +216,7 @@ namespace info {
|
|
|
216
216
|
const allScoresKey = "all-scores";
|
|
217
217
|
let allScores: number[];
|
|
218
218
|
if (players) {
|
|
219
|
-
allScores = players.filter(item => item.hasScore()).map(item => item.score());
|
|
219
|
+
allScores = players.filter(item => item.impl.hasScore()).map(item => item.impl.score());
|
|
220
220
|
}
|
|
221
221
|
else {
|
|
222
222
|
allScores = [];
|
|
@@ -229,8 +229,8 @@ namespace info {
|
|
|
229
229
|
if (players) {
|
|
230
230
|
let hs = 0;
|
|
231
231
|
players
|
|
232
|
-
.filter(p => p && p.hasScore())
|
|
233
|
-
.forEach(p => hs = Math.max(hs, p.score()));
|
|
232
|
+
.filter(p => p && p.impl.hasScore())
|
|
233
|
+
.forEach(p => hs = Math.max(hs, p.impl.score()));
|
|
234
234
|
const curr = settings.readNumber("high-score")
|
|
235
235
|
if (curr == null || hs > curr)
|
|
236
236
|
settings.writeNumber("high-score", hs);
|
|
@@ -245,13 +245,13 @@ namespace info {
|
|
|
245
245
|
//% help=info/score
|
|
246
246
|
//% group="Score"
|
|
247
247
|
export function score() {
|
|
248
|
-
return player1.score();
|
|
248
|
+
return player1.impl.score();
|
|
249
249
|
}
|
|
250
250
|
|
|
251
251
|
//%
|
|
252
252
|
//% group="Score"
|
|
253
253
|
export function hasScore() {
|
|
254
|
-
return player1.hasScore();
|
|
254
|
+
return player1.impl.hasScore();
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
/**
|
|
@@ -273,7 +273,7 @@ namespace info {
|
|
|
273
273
|
//% help=info/set-score
|
|
274
274
|
//% group="Score"
|
|
275
275
|
export function setScore(value: number) {
|
|
276
|
-
player1.setScore(value);
|
|
276
|
+
player1.impl.setScore(value);
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
/**
|
|
@@ -285,7 +285,7 @@ namespace info {
|
|
|
285
285
|
//% help=info/change-score-by
|
|
286
286
|
//% group="Score"
|
|
287
287
|
export function changeScoreBy(value: number) {
|
|
288
|
-
player1.changeScoreBy(value);
|
|
288
|
+
player1.impl.changeScoreBy(value);
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
/**
|
|
@@ -296,12 +296,12 @@ namespace info {
|
|
|
296
296
|
//% help=info/life
|
|
297
297
|
//% group="Life"
|
|
298
298
|
export function life() {
|
|
299
|
-
return player1.life();
|
|
299
|
+
return player1.impl.life();
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
//% group="Life"
|
|
303
303
|
export function hasLife() {
|
|
304
|
-
return player1.hasLife();
|
|
304
|
+
return player1.impl.hasLife();
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
/**
|
|
@@ -313,7 +313,7 @@ namespace info {
|
|
|
313
313
|
//% help=info/set-life
|
|
314
314
|
//% group="Life"
|
|
315
315
|
export function setLife(value: number) {
|
|
316
|
-
player1.setLife(value);
|
|
316
|
+
player1.impl.setLife(value);
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
/**
|
|
@@ -325,7 +325,7 @@ namespace info {
|
|
|
325
325
|
//% help=info/change-life-by
|
|
326
326
|
//% group="Life"
|
|
327
327
|
export function changeLifeBy(value: number) {
|
|
328
|
-
player1.changeLifeBy(value);
|
|
328
|
+
player1.impl.changeLifeBy(value);
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
/**
|
|
@@ -337,7 +337,7 @@ namespace info {
|
|
|
337
337
|
//% help=info/on-life-zero
|
|
338
338
|
//% group="Life"
|
|
339
339
|
export function onLifeZero(handler: () => void) {
|
|
340
|
-
player1.onLifeZero(handler);
|
|
340
|
+
player1.impl.onLifeZero(handler);
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
/**
|
|
@@ -355,7 +355,7 @@ namespace info {
|
|
|
355
355
|
//% help=info/on-score
|
|
356
356
|
//% group="Score"
|
|
357
357
|
export function onScore(score: number, handler: () => void) {
|
|
358
|
-
player1.onScore(score, handler);
|
|
358
|
+
player1.impl.onScore(score, handler);
|
|
359
359
|
}
|
|
360
360
|
|
|
361
361
|
/**
|
|
@@ -564,9 +564,14 @@ namespace info {
|
|
|
564
564
|
}
|
|
565
565
|
}
|
|
566
566
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
567
|
+
/**
|
|
568
|
+
* Splits the implementation of the player info from the user-facing APIs so that
|
|
569
|
+
* we can reference this internally without causing the "multiplayer" part to show
|
|
570
|
+
* up in the usedParts array of the user program's compile result. Make sure to
|
|
571
|
+
* use the APIs on this class and not the PlayerInfo to avoid false-positives when
|
|
572
|
+
* we detect if a game is multiplayer or not
|
|
573
|
+
*/
|
|
574
|
+
export class PlayerInfoImpl {
|
|
570
575
|
protected _player: number;
|
|
571
576
|
public bg: number; // background color
|
|
572
577
|
public border: number; // border color
|
|
@@ -614,9 +619,6 @@ namespace info {
|
|
|
614
619
|
this.left = true;
|
|
615
620
|
this.up = true;
|
|
616
621
|
}
|
|
617
|
-
|
|
618
|
-
if (!players) players = [];
|
|
619
|
-
players[this._player - 1] = this;
|
|
620
622
|
}
|
|
621
623
|
|
|
622
624
|
private init() {
|
|
@@ -637,12 +639,6 @@ namespace info {
|
|
|
637
639
|
return this._player;
|
|
638
640
|
}
|
|
639
641
|
|
|
640
|
-
/**
|
|
641
|
-
* Get the player score
|
|
642
|
-
*/
|
|
643
|
-
//% group="Multiplayer"
|
|
644
|
-
//% blockId=piscore block="%player score"
|
|
645
|
-
//% help=info/score
|
|
646
642
|
score(): number {
|
|
647
643
|
if (this.showScore === undefined) this.showScore = true;
|
|
648
644
|
if (this.showPlayer === undefined) this.showPlayer = true;
|
|
@@ -654,13 +650,6 @@ namespace info {
|
|
|
654
650
|
return state.score;
|
|
655
651
|
}
|
|
656
652
|
|
|
657
|
-
/**
|
|
658
|
-
* Set the player score
|
|
659
|
-
*/
|
|
660
|
-
//% group="Multiplayer"
|
|
661
|
-
//% blockId=pisetscore block="set %player score to %value"
|
|
662
|
-
//% value.defl=0
|
|
663
|
-
//% help=info/set-score
|
|
664
653
|
setScore(value: number) {
|
|
665
654
|
const state = this.getState();
|
|
666
655
|
if (!(infoState.visibilityFlag & Visibility._ExplicitlySetScore)) {
|
|
@@ -680,6 +669,211 @@ namespace info {
|
|
|
680
669
|
}
|
|
681
670
|
}
|
|
682
671
|
|
|
672
|
+
changeScoreBy(value: number): void {
|
|
673
|
+
this.setScore(this.score() + value);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
hasScore() {
|
|
677
|
+
const state = this.getState();
|
|
678
|
+
return state.score !== undefined;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
life(): number {
|
|
682
|
+
const state = this.getState();
|
|
683
|
+
if (this.showLife === undefined) this.showLife = true;
|
|
684
|
+
if (this.showPlayer === undefined) this.showPlayer = true;
|
|
685
|
+
|
|
686
|
+
if (state.life === undefined) {
|
|
687
|
+
state.life = 3;
|
|
688
|
+
}
|
|
689
|
+
return state.life || 0;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
setLife(value: number): void {
|
|
693
|
+
const state = this.getState();
|
|
694
|
+
if (!(infoState.visibilityFlag & Visibility._ExplicitlySetLife)) {
|
|
695
|
+
updateFlag(Visibility.Life, true);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
this.life(); // invoked for side effects
|
|
699
|
+
state.life = (value | 0);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
changeLifeBy(value: number): void {
|
|
703
|
+
this.setLife(this.life() + value);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
hasLife(): boolean {
|
|
707
|
+
const state = this.getState();
|
|
708
|
+
return state.life !== undefined && state.life !== null;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
onLifeZero(handler: () => void) {
|
|
712
|
+
const state = this.getState();
|
|
713
|
+
state.lifeZeroHandler = handler;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
onScore(score: number, handler: () => void) {
|
|
717
|
+
const state = this.getState();
|
|
718
|
+
state.scoreReachedHandler = new ScoreReachedHandler(score, handler);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
raiseLifeZero(gameOver: boolean) {
|
|
722
|
+
const state = this.getState();
|
|
723
|
+
if (state.life !== null && state.life <= 0) {
|
|
724
|
+
state.life = null;
|
|
725
|
+
if (state.lifeZeroHandler) {
|
|
726
|
+
state.lifeZeroHandler();
|
|
727
|
+
} else if (gameOver) {
|
|
728
|
+
game.over();
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
//% fixedInstances
|
|
735
|
+
//% blockGap=8
|
|
736
|
+
export class PlayerInfo {
|
|
737
|
+
protected _player: number;
|
|
738
|
+
public impl: PlayerInfoImpl;
|
|
739
|
+
|
|
740
|
+
constructor(player: number) {
|
|
741
|
+
this._player = player;
|
|
742
|
+
this.impl = new PlayerInfoImpl(player);
|
|
743
|
+
|
|
744
|
+
if (!players) players = [];
|
|
745
|
+
players[this._player - 1] = this;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
private init() {
|
|
749
|
+
initHUD();
|
|
750
|
+
if (this._player > 1) initMultiHUD();
|
|
751
|
+
if (!infoState.playerStates[this._player - 1]) {
|
|
752
|
+
infoState.playerStates[this._player - 1] = new PlayerState();
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
get bg(): number {
|
|
757
|
+
return this.impl.bg;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
set bg(value: number) {
|
|
761
|
+
this.impl.bg = value;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
get border(): number {
|
|
765
|
+
return this.impl.border;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
set border(value: number) {
|
|
769
|
+
this.impl.border = value;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
get fc(): number {
|
|
773
|
+
return this.impl.fc;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
set fc(value: number) {
|
|
777
|
+
this.impl.fc = value;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
get showScore(): boolean {
|
|
781
|
+
return this.impl.showScore;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
set showScore(value: boolean) {
|
|
785
|
+
this.impl.showScore = value;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
get showLife(): boolean {
|
|
789
|
+
return this.impl.showLife;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
set showLife(value: boolean) {
|
|
793
|
+
this.impl.showLife = value;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
get visibility(): Visibility {
|
|
797
|
+
return this.impl.visibility;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
set visibility(value: Visibility) {
|
|
801
|
+
this.impl.visibility = value;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
get showPlayer(): boolean {
|
|
805
|
+
return this.impl.showPlayer;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
set showPlayer(value: boolean) {
|
|
809
|
+
this.impl.showPlayer = value;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
get x(): number {
|
|
813
|
+
return this.impl.x;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
set x(value: number) {
|
|
817
|
+
this.impl.x = value;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
get y(): number {
|
|
821
|
+
return this.impl.y;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
set y(value: number) {
|
|
825
|
+
this.impl.y = value;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
get left(): boolean {
|
|
829
|
+
return this.impl.left;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
set left(value: boolean) {
|
|
833
|
+
this.impl.left = value;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
get up(): boolean {
|
|
837
|
+
return this.impl.up;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
set up(value: boolean) {
|
|
841
|
+
this.impl.up = value;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
getState(): PlayerState {
|
|
845
|
+
this.init();
|
|
846
|
+
return infoState.playerStates[this._player - 1];
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// the id numbera of the player
|
|
850
|
+
id(): number {
|
|
851
|
+
return this.impl.id();
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* Get the player score
|
|
856
|
+
*/
|
|
857
|
+
//% group="Multiplayer"
|
|
858
|
+
//% blockId=piscore block="%player score"
|
|
859
|
+
//% help=info/score
|
|
860
|
+
//% parts="multiplayer"
|
|
861
|
+
score(): number {
|
|
862
|
+
return this.impl.score();
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* Set the player score
|
|
867
|
+
*/
|
|
868
|
+
//% group="Multiplayer"
|
|
869
|
+
//% blockId=pisetscore block="set %player score to %value"
|
|
870
|
+
//% value.defl=0
|
|
871
|
+
//% help=info/set-score
|
|
872
|
+
//% parts="multiplayer"
|
|
873
|
+
setScore(value: number) {
|
|
874
|
+
this.impl.setScore(value);
|
|
875
|
+
}
|
|
876
|
+
|
|
683
877
|
/**
|
|
684
878
|
* Change the score of a player
|
|
685
879
|
* @param value
|
|
@@ -688,13 +882,13 @@ namespace info {
|
|
|
688
882
|
//% blockId=pichangescore block="change %player score by %value"
|
|
689
883
|
//% value.defl=1
|
|
690
884
|
//% help=info/change-score-by
|
|
885
|
+
//% parts="multiplayer"
|
|
691
886
|
changeScoreBy(value: number): void {
|
|
692
|
-
this.
|
|
887
|
+
this.impl.changeScoreBy(value);
|
|
693
888
|
}
|
|
694
889
|
|
|
695
890
|
hasScore() {
|
|
696
|
-
|
|
697
|
-
return state.score !== undefined;
|
|
891
|
+
return this.impl.hasScore();
|
|
698
892
|
}
|
|
699
893
|
|
|
700
894
|
/**
|
|
@@ -703,15 +897,9 @@ namespace info {
|
|
|
703
897
|
//% group="Multiplayer"
|
|
704
898
|
//% blockid=piflife block="%player life"
|
|
705
899
|
//% help=info/life
|
|
900
|
+
//% parts="multiplayer"
|
|
706
901
|
life(): number {
|
|
707
|
-
|
|
708
|
-
if (this.showLife === undefined) this.showLife = true;
|
|
709
|
-
if (this.showPlayer === undefined) this.showPlayer = true;
|
|
710
|
-
|
|
711
|
-
if (state.life === undefined) {
|
|
712
|
-
state.life = 3;
|
|
713
|
-
}
|
|
714
|
-
return state.life || 0;
|
|
902
|
+
return this.impl.life();
|
|
715
903
|
}
|
|
716
904
|
|
|
717
905
|
/**
|
|
@@ -721,14 +909,9 @@ namespace info {
|
|
|
721
909
|
//% blockId=pisetlife block="set %player life to %value"
|
|
722
910
|
//% value.defl=3
|
|
723
911
|
//% help=info/set-life
|
|
912
|
+
//% parts="multiplayer"
|
|
724
913
|
setLife(value: number): void {
|
|
725
|
-
|
|
726
|
-
if (!(infoState.visibilityFlag & Visibility._ExplicitlySetLife)) {
|
|
727
|
-
updateFlag(Visibility.Life, true);
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
this.life(); // invoked for side effects
|
|
731
|
-
state.life = (value | 0);
|
|
914
|
+
this.impl.setLife(value);
|
|
732
915
|
}
|
|
733
916
|
|
|
734
917
|
/**
|
|
@@ -739,8 +922,9 @@ namespace info {
|
|
|
739
922
|
//% blockId=pichangelife block="change %player life by %value"
|
|
740
923
|
//% value.defl=-1
|
|
741
924
|
//% help=info/change-life-by
|
|
925
|
+
//% parts="multiplayer"
|
|
742
926
|
changeLifeBy(value: number): void {
|
|
743
|
-
this.
|
|
927
|
+
this.impl.changeLifeBy(value);
|
|
744
928
|
}
|
|
745
929
|
|
|
746
930
|
/**
|
|
@@ -751,9 +935,9 @@ namespace info {
|
|
|
751
935
|
//% group="Multiplayer"
|
|
752
936
|
//% blockId=pihaslife block="%player has life"
|
|
753
937
|
//% help=info/has-life
|
|
938
|
+
//% parts="multiplayer"
|
|
754
939
|
hasLife(): boolean {
|
|
755
|
-
|
|
756
|
-
return state.life !== undefined && state.life !== null;
|
|
940
|
+
return this.impl.hasLife();
|
|
757
941
|
}
|
|
758
942
|
|
|
759
943
|
/**
|
|
@@ -763,9 +947,9 @@ namespace info {
|
|
|
763
947
|
//% group="Multiplayer"
|
|
764
948
|
//% blockId=playerinfoonlifezero block="on %player life zero"
|
|
765
949
|
//% help=info/on-life-zero
|
|
950
|
+
//% parts="multiplayer"
|
|
766
951
|
onLifeZero(handler: () => void) {
|
|
767
|
-
|
|
768
|
-
state.lifeZeroHandler = handler;
|
|
952
|
+
this.impl.onLifeZero(handler);
|
|
769
953
|
}
|
|
770
954
|
|
|
771
955
|
/**
|
|
@@ -781,21 +965,9 @@ namespace info {
|
|
|
781
965
|
//% score.defl=100
|
|
782
966
|
//% help=info/on-score
|
|
783
967
|
//% group="Multiplayer"
|
|
968
|
+
//% parts="multiplayer"
|
|
784
969
|
onScore(score: number, handler: () => void) {
|
|
785
|
-
|
|
786
|
-
state.scoreReachedHandler = new ScoreReachedHandler(score, handler);
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
raiseLifeZero(gameOver: boolean) {
|
|
790
|
-
const state = this.getState();
|
|
791
|
-
if (state.life !== null && state.life <= 0) {
|
|
792
|
-
state.life = null;
|
|
793
|
-
if (state.lifeZeroHandler) {
|
|
794
|
-
state.lifeZeroHandler();
|
|
795
|
-
} else if (gameOver) {
|
|
796
|
-
game.over();
|
|
797
|
-
}
|
|
798
|
-
}
|
|
970
|
+
this.impl.onScore(score, handler);
|
|
799
971
|
}
|
|
800
972
|
|
|
801
973
|
drawPlayer() {
|
|
@@ -809,8 +981,8 @@ namespace info {
|
|
|
809
981
|
let lifeWidth = 0;
|
|
810
982
|
const offsetX = 1;
|
|
811
983
|
let offsetY = 2;
|
|
812
|
-
let showScore = this.showScore && state.score !== undefined;
|
|
813
|
-
let showLife = this.showLife && state.life !== undefined;
|
|
984
|
+
let showScore = this.impl.showScore && state.score !== undefined;
|
|
985
|
+
let showLife = this.impl.showLife && state.life !== undefined;
|
|
814
986
|
|
|
815
987
|
if (showScore) {
|
|
816
988
|
score = "" + state.score;
|
|
@@ -830,27 +1002,27 @@ namespace info {
|
|
|
830
1002
|
// bump size for space between lines
|
|
831
1003
|
if (showScore && showLife) height++;
|
|
832
1004
|
|
|
833
|
-
const x = this.x - (this.left ? width : 0);
|
|
834
|
-
const y = this.y - (this.up ? height : 0);
|
|
1005
|
+
const x = this.impl.x - (this.impl.left ? width : 0);
|
|
1006
|
+
const y = this.impl.y - (this.impl.up ? height : 0);
|
|
835
1007
|
|
|
836
1008
|
// Bordered Box
|
|
837
1009
|
if (showScore || showLife) {
|
|
838
|
-
screen.fillRect(x, y, width, height, this.border);
|
|
839
|
-
screen.fillRect(x + 1, y + 1, width - 2, height - 2, this.bg);
|
|
1010
|
+
screen.fillRect(x, y, width, height, this.impl.border);
|
|
1011
|
+
screen.fillRect(x + 1, y + 1, width - 2, height - 2, this.impl.bg);
|
|
840
1012
|
}
|
|
841
1013
|
|
|
842
1014
|
// print score
|
|
843
1015
|
if (showScore) {
|
|
844
|
-
const bump = this.left ? width - scoreWidth : 0;
|
|
845
|
-
screen.print(score, x + offsetX + bump + 1, y + 2, this.fc, font);
|
|
1016
|
+
const bump = this.impl.left ? width - scoreWidth : 0;
|
|
1017
|
+
screen.print(score, x + offsetX + bump + 1, y + 2, this.impl.fc, font);
|
|
846
1018
|
}
|
|
847
1019
|
|
|
848
1020
|
// print life
|
|
849
1021
|
if (showLife) {
|
|
850
|
-
const xLoc = x + offsetX + (this.left ? width - lifeWidth : 0);
|
|
1022
|
+
const xLoc = x + offsetX + (this.impl.left ? width - lifeWidth : 0);
|
|
851
1023
|
|
|
852
1024
|
let mult = infoState.multiplierImage.clone();
|
|
853
|
-
mult.replace(1, this.fc);
|
|
1025
|
+
mult.replace(1, this.impl.fc);
|
|
854
1026
|
|
|
855
1027
|
screen.drawTransparentImage(
|
|
856
1028
|
infoState.heartImage,
|
|
@@ -866,24 +1038,24 @@ namespace info {
|
|
|
866
1038
|
life,
|
|
867
1039
|
xLoc + infoState.heartImage.width + infoState.multiplierImage.width + 1,
|
|
868
1040
|
y + offsetY,
|
|
869
|
-
this.fc,
|
|
1041
|
+
this.impl.fc,
|
|
870
1042
|
font
|
|
871
1043
|
);
|
|
872
1044
|
}
|
|
873
1045
|
|
|
874
1046
|
// print player icon
|
|
875
|
-
if (this.showPlayer) {
|
|
1047
|
+
if (this.impl.showPlayer) {
|
|
876
1048
|
const pNum = "" + this._player;
|
|
877
1049
|
|
|
878
1050
|
let iconWidth = pNum.length * font.charWidth + 1;
|
|
879
1051
|
const iconHeight = Math.max(height, font.charHeight + 2);
|
|
880
|
-
let iconX = this.left ? (x - iconWidth + 1) : (x + width - 1);
|
|
1052
|
+
let iconX = this.impl.left ? (x - iconWidth + 1) : (x + width - 1);
|
|
881
1053
|
let iconY = y;
|
|
882
1054
|
|
|
883
1055
|
// adjustments when only player icon shown
|
|
884
1056
|
if (!showScore && !showLife) {
|
|
885
|
-
iconX += this.left ? -1 : 1;
|
|
886
|
-
if (this.up) iconY -= 3;
|
|
1057
|
+
iconX += this.impl.left ? -1 : 1;
|
|
1058
|
+
if (this.impl.up) iconY -= 3;
|
|
887
1059
|
}
|
|
888
1060
|
|
|
889
1061
|
screen.fillRect(
|
|
@@ -891,20 +1063,20 @@ namespace info {
|
|
|
891
1063
|
iconY,
|
|
892
1064
|
iconWidth,
|
|
893
1065
|
iconHeight,
|
|
894
|
-
this.border
|
|
1066
|
+
this.impl.border
|
|
895
1067
|
);
|
|
896
1068
|
screen.print(
|
|
897
1069
|
pNum,
|
|
898
1070
|
iconX + 1,
|
|
899
1071
|
iconY + (iconHeight >> 1) - (font.charHeight >> 1),
|
|
900
|
-
this.bg,
|
|
1072
|
+
this.impl.bg,
|
|
901
1073
|
font
|
|
902
1074
|
);
|
|
903
1075
|
}
|
|
904
1076
|
}
|
|
905
1077
|
|
|
906
1078
|
drawScore() {
|
|
907
|
-
const s = this.score() | 0;
|
|
1079
|
+
const s = this.impl.score() | 0;
|
|
908
1080
|
|
|
909
1081
|
let font: image.Font;
|
|
910
1082
|
let offsetY: number;
|