pxt-arcade 1.12.27 → 1.12.28

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/sim.js CHANGED
@@ -154,12 +154,14 @@ var pxsim;
154
154
  (function (pxsim) {
155
155
  let forcedUpdateLoop;
156
156
  let isFirstRunSafari = true;
157
+ let themeFromQueryParameter = false;
157
158
  window.addEventListener("DOMContentLoaded", () => {
158
159
  const searchParams = new URL(window.location.toString()).searchParams;
159
160
  const setThemeIfDefined = (themeType) => {
160
161
  const paramVal = searchParams.get(themeType);
161
162
  if (paramVal) {
162
- setSimThemeColor(themeType, paramVal);
163
+ themeFromQueryParameter = true;
164
+ pxsim.theme.setSimThemeColor(themeType, paramVal);
163
165
  }
164
166
  };
165
167
  setThemeIfDefined("background-color");
@@ -167,6 +169,11 @@ var pxsim;
167
169
  setThemeIfDefined("text-color");
168
170
  setThemeIfDefined("button-fill");
169
171
  setThemeIfDefined("dpad-fill");
172
+ const skin = searchParams.get("skin");
173
+ if (skin) {
174
+ themeFromQueryParameter = true;
175
+ pxsim.theme.applySkin(skin);
176
+ }
170
177
  if (!!searchParams.get("pointer-events"))
171
178
  registerPointerEvents();
172
179
  if (!!searchParams.get("hideSimButtons"))
@@ -174,6 +181,10 @@ var pxsim;
174
181
  if (!!searchParams.get("noExtraPadding"))
175
182
  noExtraPadding();
176
183
  });
184
+ if (hasNavigator()) {
185
+ // only XBOX webview looks at this, to get rid of cursor
186
+ navigator.gamepadInputEmulation = "gamepad";
187
+ }
177
188
  function hideSimButtons() {
178
189
  const gamePlayer = document.getElementsByClassName("game-player");
179
190
  if (gamePlayer && gamePlayer.length) {
@@ -237,33 +248,17 @@ var pxsim;
237
248
  canvas.addEventListener("pointerout", reporter);
238
249
  canvas.addEventListener("wheel", wheelReporter);
239
250
  }
240
- function setSimThemeColor(part, color, elOverride) {
241
- if (!part || (!(color == undefined || /^[0-9A-F]{6}$/i.test(color))))
242
- return;
243
- if (part != "background-color"
244
- && part != "button-stroke"
245
- && part != "text-color"
246
- && part != "button-fill"
247
- && part != "dpad-fill") {
248
- return;
249
- }
250
- const propName = `--sim-${part}`;
251
- const propColor = color ? `#${color}` : undefined;
252
- const wrapper = elOverride || document.getElementById("wrap");
253
- if (propColor) {
254
- wrapper.style.setProperty(propName, propColor);
255
- }
256
- else {
257
- wrapper.style.removeProperty(propName);
258
- }
259
- }
260
251
  /**
261
252
  * This function gets called each time the program restarts
262
253
  */
263
254
  pxsim.initCurrentRuntime = (msg) => {
264
255
  pxsim.runtime.board = new Board();
265
256
  pxsim.initGamepad();
266
- board().setActivePlayer(msg.activePlayer);
257
+ const theme = pxsim.theme.parseTheme(msg.theme);
258
+ if (theme && !themeFromQueryParameter) {
259
+ pxsim.theme.applyTheme(theme);
260
+ }
261
+ board().setActivePlayer(msg.activePlayer, theme);
267
262
  if (!forcedUpdateLoop) {
268
263
  forcedUpdateLoop = true;
269
264
  // this is used to force screen update if game loop is stuck or not set up properly
@@ -375,11 +370,11 @@ var pxsim;
375
370
  if (ev.data.type == "setactiveplayer") {
376
371
  const b = board();
377
372
  if (!(b.multiplayerState && b.multiplayerState.origin)) {
378
- b.setActivePlayer(ev.data.playerNumber);
373
+ b.setActivePlayer(ev.data.playerNumber, theme);
379
374
  }
380
375
  }
381
376
  else if (ev.data.type == "setsimthemecolor") {
382
- setSimThemeColor(ev.data.part, (_a = ev.data.color) === null || _a === void 0 ? void 0 : _a.replace("#", ""));
377
+ pxsim.theme.setSimThemeColor(ev.data.part, (_a = ev.data.color) === null || _a === void 0 ? void 0 : _a.replace("#", ""));
383
378
  }
384
379
  });
385
380
  }
@@ -464,29 +459,24 @@ var pxsim;
464
459
  throttleAnimation((cb) => (this.screenState.onChange = cb), () => this.gameplayer.draw(this.screenState));
465
460
  this.activePlayer = undefined;
466
461
  }
467
- setActivePlayer(playerNumber) {
462
+ setActivePlayer(playerNumber, theme) {
468
463
  if (this.multiplayerState && this.multiplayerState.origin)
469
464
  return;
470
- // TODO: this is duplicated in pxt/multiplayer's ArcadeSimulator.tsx;
471
- // we could dedup this by starting a set of 'named' themes in the future
472
- // (e.g. player1, player2, hotrodflames, ...)
473
- // [[backgroundColor, buttonStroke]]
474
465
  const playerThemes = [
475
- [undefined, undefined],
476
- ["ED3636", "8D2525"],
477
- ["4E4EE9", "3333A1"],
478
- ["FF9A14", "B0701A"],
479
- ["4EB94E", "245D24"],
466
+ undefined,
467
+ "p1",
468
+ "p2",
469
+ "p3",
470
+ "p4",
480
471
  ];
481
472
  const newPlayerTheme = playerThemes[playerNumber || 0];
482
473
  if (!newPlayerTheme) {
483
474
  // invalid playerNumber
484
475
  return;
485
476
  }
486
- const themeOverrideElement = document.querySelector(".game-player");
487
- setSimThemeColor("background-color", newPlayerTheme[0], themeOverrideElement);
488
- setSimThemeColor("button-stroke", newPlayerTheme[1], themeOverrideElement);
489
- setSimThemeColor("dpad-fill", newPlayerTheme[1], themeOverrideElement);
477
+ if ((!theme || !Object.keys(theme).length) && !themeFromQueryParameter) {
478
+ pxsim.theme.applySkin(newPlayerTheme);
479
+ }
490
480
  this.activePlayer = playerNumber || undefined;
491
481
  }
492
482
  getDefaultPitchPin() {
@@ -585,7 +575,11 @@ var pxsim;
585
575
  const wrapper = document.getElementById("wrap");
586
576
  wrapper && wrapper.classList.add("mp-client");
587
577
  }
588
- this.setActivePlayer(msg.activePlayer);
578
+ const theme = pxsim.theme.parseTheme(msg.theme);
579
+ if (theme && !themeFromQueryParameter) {
580
+ pxsim.theme.applyTheme(theme);
581
+ }
582
+ this.setActivePlayer(msg.activePlayer, theme);
589
583
  this.updateStats();
590
584
  let safariEnablePromise;
591
585
  if (isFirstRunSafari && !safariEnablePromise) {
@@ -695,10 +689,185 @@ function isSafari() {
695
689
  })(ButtonMethods = pxsim.ButtonMethods || (pxsim.ButtonMethods = {}));
696
690
  })(pxsim || (pxsim = {}));
697
691
  var pxsim;
692
+ (function (pxsim) {
693
+ var theme;
694
+ (function (theme_1) {
695
+ function parseTheme(theme) {
696
+ if (!theme)
697
+ return undefined;
698
+ return (typeof theme == "string") ? { skin: theme } : theme;
699
+ }
700
+ theme_1.parseTheme = parseTheme;
701
+ function applyTheme(theme) {
702
+ const parsedTheme = parseTheme(theme);
703
+ if (parsedTheme.skin) {
704
+ applySkin(parsedTheme.skin.toLowerCase());
705
+ }
706
+ const setThemeIfDefined = (themeType) => {
707
+ const paramVal = parsedTheme[themeType];
708
+ if (paramVal) {
709
+ setSimThemeColor(themeType, paramVal);
710
+ }
711
+ };
712
+ setThemeIfDefined("background-color");
713
+ setThemeIfDefined("button-stroke");
714
+ setThemeIfDefined("text-color");
715
+ setThemeIfDefined("button-fill");
716
+ setThemeIfDefined("dpad-fill");
717
+ }
718
+ theme_1.applyTheme = applyTheme;
719
+ function setSimThemeColor(part, color) {
720
+ if (!part || (!(color == undefined || /^(#|0x)?[0-9A-F]{6}$/i.test(color))))
721
+ return;
722
+ if (part != "background-color"
723
+ && part != "button-stroke"
724
+ && part != "text-color"
725
+ && part != "button-fill"
726
+ && part != "dpad-fill") {
727
+ return;
728
+ }
729
+ const propName = `--sim-${part}`;
730
+ const propColor = color ? `#${color.replace(/^(#|0x)/i, "")}` : undefined;
731
+ const wrapper = document.getElementById("wrap");
732
+ if (propColor) {
733
+ wrapper.style.setProperty(propName, propColor);
734
+ }
735
+ else {
736
+ wrapper.style.removeProperty(propName);
737
+ }
738
+ }
739
+ theme_1.setSimThemeColor = setSimThemeColor;
740
+ function applySkin(skin) {
741
+ switch (skin) {
742
+ case "zune": {
743
+ zuneSkin();
744
+ break;
745
+ }
746
+ case "p1":
747
+ case "red": {
748
+ redSkin();
749
+ break;
750
+ }
751
+ case "p2":
752
+ case "blue": {
753
+ blueSkin();
754
+ break;
755
+ }
756
+ case "p3":
757
+ case "orange": {
758
+ orangeSkin();
759
+ break;
760
+ }
761
+ case "p4":
762
+ case "green": {
763
+ greenSkin();
764
+ break;
765
+ }
766
+ case "brown": {
767
+ brownSkin();
768
+ break;
769
+ }
770
+ case "bubblegum": {
771
+ bubblegumSkin();
772
+ break;
773
+ }
774
+ case "purple": {
775
+ purpleSkin();
776
+ break;
777
+ }
778
+ case "microcode": {
779
+ microcodeSkin();
780
+ break;
781
+ }
782
+ default:
783
+ break;
784
+ }
785
+ }
786
+ theme_1.applySkin = applySkin;
787
+ function zuneSkin() {
788
+ setSimThemeColor("background-color", "#564131");
789
+ setSimThemeColor("button-stroke", "#524F4E");
790
+ setSimThemeColor("text-color", "#E7E7E7");
791
+ const wrapper = document.getElementById("wrap");
792
+ if (wrapper) {
793
+ wrapper.classList.add("zune", "portrait-only");
794
+ /** SVG overriding a, b button positions: b on left, a on right
795
+ <svg class="game-button-svg" viewBox="0 0 40 40"=>"0 0 100 28">
796
+ <circle class="button-b" cx="13"=>"18" cy="28"=>"12" />
797
+ <text class="label-b no-select" x="13"=>"18" y="28"=>"12">B</text>
798
+ <circle class="button-a" cx="28"=>"82" cy="12.5"=>"12"/>
799
+ <text class="label-a no-select" x="28"=>"82" y="12.5"=>"12">A</text>
800
+ </svg>
801
+ // simplify viewBox
802
+ <svg class="game-joystick-svg" viewBox="1 0 40 40"=>"0 0 40 40"/>
803
+ **/
804
+ const gameButtonSvg = document.querySelector(".game-button-svg");
805
+ gameButtonSvg.removeAttribute("width");
806
+ gameButtonSvg.removeAttribute("height");
807
+ gameButtonSvg.setAttribute("viewBox", "0 0 100 28");
808
+ const joystickSvg = document.querySelector(".game-joystick-svg");
809
+ joystickSvg.setAttribute("viewBox", "0 0 40 40");
810
+ const bButton = document.querySelector(".button-b");
811
+ const bLabel = document.querySelector(".label-b");
812
+ bButton.setAttribute("cx", "18");
813
+ bButton.setAttribute("cy", "12");
814
+ bLabel.setAttribute("x", "18");
815
+ bLabel.setAttribute("y", "12");
816
+ const aButton = document.querySelector(".button-a");
817
+ const aLabel = document.querySelector(".label-a");
818
+ aButton.setAttribute("cx", "82");
819
+ aButton.setAttribute("cy", "12");
820
+ aLabel.setAttribute("x", "82");
821
+ aLabel.setAttribute("y", "12");
822
+ }
823
+ }
824
+ function brownSkin() {
825
+ setSimThemeColor("background-color", "#8B4513");
826
+ setSimThemeColor("button-stroke", "#68320C");
827
+ }
828
+ function bubblegumSkin() {
829
+ setSimThemeColor("background-color", "#F7ABB9");
830
+ setSimThemeColor("button-stroke", "#71C1C9");
831
+ setSimThemeColor("button-fill", "#92F5FF");
832
+ setSimThemeColor("text-color", "#4E4E4E");
833
+ setSimThemeColor("dpad-fill", "#F7ABB9");
834
+ const msftLogo = document.querySelector(".game-player-msft");
835
+ if (msftLogo) {
836
+ msftLogo.classList.add("gray");
837
+ }
838
+ }
839
+ function redSkin() {
840
+ setSimThemeColor("background-color", "#ED3636");
841
+ setSimThemeColor("button-stroke", "#8D2525");
842
+ }
843
+ function blueSkin() {
844
+ setSimThemeColor("background-color", "#4E4EE9");
845
+ setSimThemeColor("button-stroke", "#3333A1");
846
+ }
847
+ function orangeSkin() {
848
+ setSimThemeColor("background-color", "#FF9A14");
849
+ setSimThemeColor("button-stroke", "#B0701A");
850
+ }
851
+ function greenSkin() {
852
+ setSimThemeColor("background-color", "#4EB94E");
853
+ setSimThemeColor("button-stroke", "#245D24");
854
+ }
855
+ function purpleSkin() {
856
+ setSimThemeColor("background-color", "#660fC7");
857
+ setSimThemeColor("button-stroke", "#4C0B95");
858
+ }
859
+ function microcodeSkin() {
860
+ setSimThemeColor("background-color", "#3F3F3F");
861
+ setSimThemeColor("button-stroke", "#212121");
862
+ setSimThemeColor("button-fill", "#2D2D2D");
863
+ setSimThemeColor("text-color", "#D9D9D9");
864
+ }
865
+ })(theme = pxsim.theme || (pxsim.theme = {}));
866
+ })(pxsim || (pxsim = {}));
867
+ var pxsim;
698
868
  (function (pxsim) {
699
869
  var visuals;
700
870
  (function (visuals) {
701
- const SVG_WIDTH = 40;
702
871
  class GameButtons {
703
872
  // <div id="game-buttons-container" class="game-buttons">
704
873
  // <div class="spacer" />
@@ -760,14 +929,16 @@ var pxsim;
760
929
  });
761
930
  this.bindings = [];
762
931
  }
932
+ pointIsWithinCircle(x, y, circle) {
933
+ const bounds = circle.getBoundingClientRect();
934
+ const radius = bounds.width / 2;
935
+ const distance = Math.sqrt(Math.pow(x - (bounds.left + radius), 2)
936
+ + Math.pow(y - (bounds.top + radius), 2));
937
+ return distance < radius;
938
+ }
763
939
  updateButtonGesture(x, y) {
764
- const bounds = this.dragSurface.getBoundingClientRect();
765
- const dx = ((x - bounds.left) * (SVG_WIDTH / bounds.width));
766
- const dy = ((y - bounds.top) * (SVG_WIDTH / bounds.height));
767
- const aDistance = Math.sqrt(Math.pow(dx - 30, 2) + Math.pow(dy - 15, 2));
768
- const bDistance = Math.sqrt(Math.pow(dx - 15, 2) + Math.pow(dy - 28, 2));
769
- this.setButtonState(pxsim.Key.A, aDistance < 8);
770
- this.setButtonState(pxsim.Key.B, bDistance < 8);
940
+ this.setButtonState(pxsim.Key.A, this.pointIsWithinCircle(x, y, this.aButton));
941
+ this.setButtonState(pxsim.Key.B, this.pointIsWithinCircle(x, y, this.bButton));
771
942
  pxsim.indicateFocus(true);
772
943
  }
773
944
  clearButtonPresses() {
@@ -914,10 +1085,9 @@ var pxsim;
914
1085
  this.screen = document.getElementById("game-screen");
915
1086
  this.menu = document.getElementsByClassName("game-menu-button")[0];
916
1087
  this.reset = document.getElementsByClassName("game-reset-button")[0];
917
- // TODO: localize; currently can't use lf in this repo
918
- this.menu.setAttribute("aria-label", "Menu");
919
- this.reset.setAttribute("aria-label", "Reset Game");
920
1088
  if (this.menu) {
1089
+ // TODO: localize; currently can't use lf in this repo
1090
+ this.menu.setAttribute("aria-label", "Menu");
921
1091
  this.menu.onclick = () => {
922
1092
  visuals.pressButton(pxsim.Key.Menu);
923
1093
  visuals.releaseButton(pxsim.Key.Menu);
@@ -925,6 +1095,7 @@ var pxsim;
925
1095
  };
926
1096
  }
927
1097
  if (this.reset) {
1098
+ this.reset.setAttribute("aria-label", "Reset Game");
928
1099
  this.reset.onclick = () => {
929
1100
  visuals.pressButton(pxsim.Key.Reset);
930
1101
  visuals.releaseButton(pxsim.Key.Reset);
@@ -993,12 +1164,12 @@ var pxsim;
993
1164
  }
994
1165
  indicateFocus(focused) {
995
1166
  if (focused) {
996
- this.menu.setAttribute("aria-disabled", "false");
997
- this.reset.setAttribute("aria-disabled", "false");
1167
+ this.menu && this.menu.setAttribute("aria-disabled", "false");
1168
+ this.reset && this.reset.setAttribute("aria-disabled", "false");
998
1169
  }
999
1170
  else {
1000
- this.menu.setAttribute("aria-disabled", "true");
1001
- this.reset.setAttribute("aria-disabled", "true");
1171
+ this.menu && this.menu.setAttribute("aria-disabled", "true");
1172
+ this.reset && this.reset.setAttribute("aria-disabled", "true");
1002
1173
  }
1003
1174
  }
1004
1175
  }