Up-in-the-Air – commitdiff

You can use Git to clone the repository via the web URL. Download snapshot (zip)
Include optional credits CSS in open source version
authorJulian Fietkau <git@fietkau.software>
Mon, 30 Sep 2024 15:33:48 +0000 (17:33 +0200)
committerJulian Fietkau <git@fietkau.software>
Mon, 30 Sep 2024 15:33:48 +0000 (17:33 +0200)
index.html
main.js

index 4e2a234497ba5f181566b0b6ac4f7edace6d622d..0e6ac7e4db91f005a181f9d3b8cfa8e61b70a5f8 100644 (file)
@@ -85,7 +85,7 @@
       background: #111;
     }
   }
-  .game-upintheair {
+  .upInTheAirGame {
     container-type: inline-size;
     box-sizing: border-box;
     width: min(100cqw, 100svw);
     align-items: flex-start;
     --game-margin: 2rem;
   }
-  .game-upintheair:fullscreen {
+  .upInTheAirGame:fullscreen {
     background: #eee;
   }
   @media (prefers-color-scheme: dark) {
-    .game-upintheair:fullscreen {
+    .upInTheAirGame:fullscreen {
       background: #111;
     }
   }
-  .game-upintheair .ui-container {
+  .upInTheAirGame .ui-container {
     position: relative;
     width: min(calc(100cqh - 2 * var(--game-margin)), calc(100cqw));
     aspect-ratio: 1 / 1;
   }
   @media (min-width: 15cm) and (min-height: 15cm) {
     @container (min-width: calc(100cqh - 4cm - 1rem - 4rem)) {
-      .game-upintheair .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
+      .upInTheAirGame .ui-container.control-touchpad, .upInTheAirGame .ui-container.control-thumbstick {
         margin: 0 calc(1rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin))));
         align-self: flex-end;
       }
     }
     @container (min-width: calc(100cqh - 4cm - 1rem - 4rem)) and (max-width: calc(100cqh + 2 * 4cm + 2rem)) {
-      .game-upintheair .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
+      .upInTheAirGame .ui-container.control-touchpad, .upInTheAirGame .ui-container.control-thumbstick {
         margin: 0 calc(1rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin)))) 0 0;
         align-self: flex-end;
       }
-      .game-upintheair.virtual-input-left .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
+      .upInTheAirGame.virtual-input-left .ui-container.control-touchpad, .upInTheAirGame .ui-container.control-thumbstick {
         margin: 0 0 0 calc(1rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin))));
         align-self: flex-end;
       }
     }
   }
   @media (max-width: 15cm) or (max-height: 15cm) {
-    .game-upintheair {
+    .upInTheAirGame {
       --game-margin: 0px;
     }
     .virtual-input-widget {
       right: unset;
     }
     @container (min-width: calc(100cqh - 4cm - 2rem)) {
-      .game-upintheair .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
+      .upInTheAirGame .ui-container.control-touchpad, .upInTheAirGame .ui-container.control-thumbstick {
         margin: 0 calc(2rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin))));
         align-self: flex-end;
       }
     }
     @container (min-width: calc(100cqh - 4cm - 2rem)) and (max-width: calc(100cqh + 2 * 4cm + 4rem)) {
-      .game-upintheair .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
+      .upInTheAirGame .ui-container.control-touchpad, .upInTheAirGame .ui-container.control-thumbstick {
         margin: 0 calc(2rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin)))) 0 0;
         align-self: flex-end;
       }
-      .game-upintheair.virtual-input-left .ui-container.control-touchpad, .game-upintheair .ui-container.control-thumbstick {
+      .upInTheAirGame.virtual-input-left .ui-container.control-touchpad, .upInTheAirGame .ui-container.control-thumbstick {
         margin: 0 0 0 calc(2rem + min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin))));
         align-self: flex-end;
       }
     }
   }
-  .game-upintheair .ui-container.font-atkinson * {
+  .upInTheAirGame .ui-container.font-atkinson * {
     font-family: 'Atkinson Hyperlegible' !important;
   }
-  .game-upintheair .ui-container.font-atkinson > .ui-page {
+  .upInTheAirGame .ui-container.font-atkinson > .ui-page {
     font-size: .9em;
   }
-  .game-upintheair .ui-container.font-opendyslexic * {
+  .upInTheAirGame .ui-container.font-opendyslexic * {
     font-family: 'OpenDyslexic' !important;
   }
-  .game-upintheair .ui-container.font-opendyslexic > .ui-page {
+  .upInTheAirGame .ui-container.font-opendyslexic > .ui-page {
     font-size: .8em;
   }
   .virtual-input-widget.touchpad {
     display: inline;
     margin-left: 1ex;
   }
-  .game-upintheair.font-opendyslexic .ui-page.options .graphics *:not(.audio) label,
-  .game-upintheair.font-opendyslexic .ui-page.options .audiotheme:not(.audio) label {
+  .upInTheAirGame.font-opendyslexic .ui-page.options .graphics *:not(.audio) label,
+  .upInTheAirGame.font-opendyslexic .ui-page.options .audiotheme:not(.audio) label {
     margin-left: 0;
   }
-  .game-upintheair.font-opendyslexic .ui-page.options .graphics p {
+  .upInTheAirGame.font-opendyslexic .ui-page.options .graphics p {
     display: flex;
     align-items: center;
     gap: 1ex;
   }
-  .game-upintheair.font-opendyslexic .ui-page.options .audiotheme:not(.audio) label {
+  .upInTheAirGame.font-opendyslexic .ui-page.options .audiotheme:not(.audio) label {
     margin-right: 1em;
   }
   .ui-page.options p.annotation {
 </script>
 </head>
 <body>
-<div class="game-upintheair">
+<div class="upInTheAirGame">
 <div class="ui-container">
 <div class="ui-page loading">
 <img src="textures/pinwheel.png" alt="Spinning red pinwheel loading animation">
 <script type="module" src="main.js"></script>
 <script>
 if(!['https:', 'http:'].includes(window.location.protocol)) {
-  document.querySelectorAll('.game-upintheair .ui-page:not(.loading)').forEach(page => page.remove());
-  document.querySelector('.game-upintheair .loading div').innerText = 'This game cannot run without a web server.';
+  document.querySelectorAll('.upInTheAirGame .ui-page:not(.loading)').forEach(page => page.remove());
+  document.querySelector('.upInTheAirGame .loading div').innerText = 'This game cannot run without a web server.';
 }
 </script>
 </body>
diff --git a/main.js b/main.js
index 4eea458f25013e5410b1a021a89b04b946cb9980..694365d212bb53723d1ac62969e23796e2eae08f 100644 (file)
--- a/main.js
+++ b/main.js
@@ -262,7 +262,7 @@ function initializeGame(game, canvas) {
   game.view = {};
   game.view.muted = false;
   game.view.canvas = canvas;
-  game.ui.virtualInput = canvas.closest('.game-upintheair').querySelector('.virtual-input-widget');
+  game.ui.virtualInput = canvas.closest('.upInTheAirGame').querySelector('.virtual-input-widget');
 
   const scene = new THREE.Scene();
   game.view.camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 1000);
@@ -1915,7 +1915,7 @@ function unlockWithKey(game, input) {
 window['game'] = {
   state: 'loadingAssets',
   ui: {
-    root: document.querySelector('.game-upintheair .ui-container'),
+    root: document.querySelector('.upInTheAirGame .ui-container'),
     gamepads: [],
   },
   settings: {},
@@ -1961,6 +1961,19 @@ window['game'] = {
 loadSettings(window['game']);
 applySettings(window['game']);
 
+if(game.ui.root.querySelectorAll('.ui-page.credits .area h3').length > 3) {
+  // If the credits have more than three third-level headers, that means we are
+  // in the freeware version and can make the CSS adjustments it needs.
+  let css = document.styleSheets[0];
+  css.insertRule('.upInTheAirGame .ui-page.credits .person { position: relative; height: 4em; padding-left: calc(4em + 1ex); display: flex; flex-direction: column; justify-content: center; }');
+  css.insertRule('.upInTheAirGame .ui-page.credits .person::before { content: " "; position: absolute; left: 0; box-sizing: border-box; width: 4em; height: 4em; background-size: contain; border-radius: .6em; border: .1em solid #d53c59; }');
+  game.ui.root.querySelectorAll('.ui-page.credits .area .person').forEach((person) => {
+    let personName = Array.from(person.classList).filter(c => c != 'person')[0];
+    let imageFormat = (personName == 'nina') ? 'png' : 'jpg';
+    css.insertRule('.upInTheAirGame .ui-page.credits .person.' + personName + '::before { background-image: url("textures/person-' + personName + '.' + imageFormat + '"); }');
+  });
+}
+
 game.ui.root.querySelectorAll('button.goto').forEach((btn) => {
   btn.addEventListener('click', (e) => {
     if(game.view && !game.view.music) {