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.
- 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 +15483 -15338
- package/libs/controller---none/built/debug/binary.js +15467 -15322
- 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 +8 -3
- package/libs/game/_locales/game-strings.json +11 -0
- package/libs/game/ask.ts +0 -1
- package/libs/game/built/debug/binary.js +16092 -15947
- package/libs/game/controller.ts +0 -6
- package/libs/game/game.ts +194 -45
- package/libs/game/gameutil.ts +0 -2
- package/libs/game/info.ts +98 -45
- package/libs/game/multiplayer.ts +9 -8
- package/libs/game/ns.ts +5 -0
- package/libs/game/numberprompt.ts +0 -1
- package/libs/game/particleeffects.ts +30 -0
- package/libs/game/prompt.ts +0 -1
- package/libs/game/pxt.json +1 -0
- package/libs/game/textDialogs.ts +275 -40
- 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/mixer/instrument.ts +20 -1
- package/libs/mixer/melody.ts +13 -15
- package/libs/mixer/playable.ts +181 -0
- package/libs/mixer/pxt.json +1 -0
- package/libs/mixer/soundEffect.ts +19 -2
- package/libs/mqtt/built/debug/binary.js +176 -176
- package/libs/multiplayer/ns.ts +6 -0
- package/libs/multiplayer/player.ts +24 -6
- package/libs/multiplayer/pxt.json +1 -0
- package/libs/music/ns.ts +1 -1
- package/libs/net/built/debug/binary.js +176 -176
- package/libs/net-game/built/debug/binary.js +20403 -20258
- package/libs/palette/built/debug/binary.js +16083 -15938
- 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 +16091 -15946
- package/libs/storyboard/built/debug/binary.js +16091 -15946
- package/package.json +1 -1
package/libs/game/controller.ts
CHANGED
|
@@ -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
|
-
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
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
|
-
|
|
148
|
-
|
|
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
|
|
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
|
-
|
|
162
|
-
|
|
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
|
-
|
|
191
|
-
effect = win ? winEffect : loseEffect;
|
|
192
|
-
}
|
|
337
|
+
const goc = game.gameOverConfig();
|
|
193
338
|
|
|
194
|
-
|
|
195
|
-
info.
|
|
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
|
-
//
|
|
198
|
-
|
|
199
|
-
|
|
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 (
|
|
213
|
-
|
|
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,
|
|
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(
|
package/libs/game/gameutil.ts
CHANGED
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
219
|
-
|
|
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
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
684
|
-
if (
|
|
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
|
-
|
|
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 =
|
|
994
|
-
let showLife =
|
|
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 (
|
|
1109
|
+
if (state.showPlayer) {
|
|
1057
1110
|
const pNum = "" + this._player;
|
|
1058
1111
|
|
|
1059
1112
|
let iconWidth = pNum.length * font.charWidth + 1;
|