.game-upintheair {
container-type: inline-size;
box-sizing: border-box;
- width: calc(100% - 2 * var(--game-margin));
- height: calc(100svh - 2 * var(--game-margin));
+ width: 100cqw;
+ height: 100cqh;
+ padding: var(--game-margin);
font-family: sans-serif;
line-height: 1;
display: flex;
align-items: flex-start;
--game-margin: 2rem;
}
+ .game-upintheair:fullscreen {
+ background: #eee;
+ }
+ @media (prefers-color-scheme: dark) {
+ .game-upintheair:fullscreen {
+ background: #111;
+ }
+ }
.game-upintheair .ui-container {
position: relative;
width: min(calc(100cqh - 2 * var(--game-margin)), calc(100cqw));
width: min(4cm, 100cqw, calc(100cqh - 2 * var(--game-margin)));
aspect-ratio: 1 / 1;
position: absolute;
- bottom: 0;
- right: 0;
+ bottom: var(--game-margin);
+ right: var(--game-margin);
z-index: 25;
}
.virtual-input-left .virtual-input-widget {
justify-content: space-evenly;
align-items: center;
}
- .ui-page.options .feather input {
+ .ui-page.options .feather input, .ui-page.title .system-buttons input {
position: absolute;
left: -99999px;
width: 1px;
background: #f9c8d5;
border-image-source: url('textures/button-pressed.png');
}
+ .ui-page.title .system-buttons {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ padding: .7ex;
+ display: flex;
+ flex-direction: column;
+ align-items: start;
+ gap: 1ex;
+ }
+ .ui-page.title.end .system-buttons {
+ left: unset;
+ right: 0;
+ align-items: end;
+ }
+ @media not (hover: hover) {
+ .ui-page.title .system-buttons {
+ font-size: 2em;
+ }
+ }
+ .ui-page.title .system-buttons svg {
+ width: 2em;
+ height: 2em;
+ }
+ .ui-page.title .system-buttons svg:hover {
+ filter: drop-shadow(0 0 1px #000);
+ }
+ .ui-page.title .system-buttons label input:not(:checked) + svg g {
+ display: none;
+ }
+ .ui-page.title .system-buttons button {
+ appearance: none;
+ display: block;
+ margin: 0;
+ padding: 0;
+ border: none;
+ background: none;
+ font-size: 1em;
+ }
.ui-page.title .footer {
position: absolute;
right: 0;
<button class="goto openingcutscene">Start Game</button>
<button class="goto options">Options</button>
<button class="goto credits">Credits</button>
+<div class="system-buttons">
+<label>
+<input type="checkbox" name="mute">
+<svg version="1.1" viewBox="0 0 34 34" xmlns="http://www.w3.org/2000/svg" aria-label="Mute audio">
+<path d="m14 4v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-5v1h-1v1h-1v8h1v1h1v1h5v1h1v1h1v1h1v1h1v1h1v1h1v1h4v-1h1v-6h1v1h1v1h3v2h1v1h4v-1h1v-2h1v-2h1v-4h1v-4h-1v-5h-1v-1h-1v-2h-1v-1h-4v1h-1v2h-3v1h-1v1h-1v-6h-1v-1h-3z" fill="#fff"/>
+<path d="m15 6v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-5v1h-1v6h1v1h5v1h1v1h1v1h1v1h1v1h1v1h1v1h2v-22h-1zm11 2v3h1v2h1v8h-1v2h-1v3h2v-2h1v-2h1v-4h1v-2h-1v-5h-1v-1h-1v-2h-1zm-4 3v1h1v2h1v6h-1v2h-1v1h3v-1h1v-4h1v-2h-1v-4h-1v-1h-2zm-2 2v1h-1v1h1v4h-1v1h1v1h1v-1h1v-6h-1v-1z" fill="#000"/>
+<g>
+<path d="m27 0v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v4h1v1h1v1h1v1h4v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-4h-1v-1h-1v-1h-1v-1h-3z" fill="#fff"/>
+<path d="m28 2v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v2h1v1h1v1h2v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-2h-1v-1h-1v-1h-1z" fill="#000"/>
+</g>
+</svg>
+</label>
+<button>
+<svg version="1.1" viewBox="0 0 34 34" xmlns="http://www.w3.org/2000/svg">
+<path d="m0 0v11h7v-4h4v-7h-11zm23 0v7h4v4h7v-11h-11zm-23 23v11h11v-7h-4v-4h-7zm27 0v4h-4v7h11v-11h-7z" fill="#fff"/>
+<path d="m2 2v7h3v-4h4v-3h-7zm23 0v3h4v4h3v-7h-7zm-23 23v7h7v-3h-4v-4h-3zm27 0v4h-4v3h7v-7h-3z" fill="#000"/>
+</svg>
+</button>
+</div>
<div class="footer">
<span>Version: dev</span>
<span>A game for <a href="https://itch.io/jam/fedi-jam" target="_blank" class="fediverse">FediJam 2024</a></span>
let sound = new THREE.Audio(game.view.audioListener);
sound.setBuffer(game.assets['audio']['sound' + index + '-' + game.settings['audio']['theme']]);
sound.setVolume(game.settings['audio']['sounds']);
- if(game.settings['audio']['sounds'] > 0) {
+ if(!game.view.muted && game.settings['audio']['sounds'] > 0) {
sound.play();
}
}
game.objects = {};
game.view = {};
+ game.view.muted = false;
game.view.canvas = canvas;
game.ui.virtualInput = canvas.closest('.game-upintheair').querySelector('.virtual-input-widget');
if(!game.ui.reachedStart) {
if(game.timeProgress < 1) {
game.ui.root.querySelector('.ui-page.title h1').style.opacity = '0';
- game.ui.root.querySelectorAll('.ui-page.title button').forEach((btn) => {
+ game.ui.root.querySelectorAll('.ui-page.title > button').forEach((btn) => {
btn.disabled = true;
btn.style.position = 'relative';
btn.style.left = '10em';
btn.style.opacity = '0';
});
game.ui.root.querySelector('.ui-page.title .footer').style.opacity = '0';
+ game.ui.root.querySelector('.ui-page.title .system-buttons').style.opacity = '0';
cameraX += Math.max(0.0, 1 - easeInOut(0.5 + game.timeProgress / 2));
cameraY += Math.max(0.0, 10 * Math.pow(0.5 - game.timeProgress / 2, 2));
} else if(game.timeProgress >= 1.0 && game.timeProgress <= 2.1) {
game.ui.root.querySelector('.ui-page.title h1').style.opacity = Math.min(1.0, game.timeProgress - 1.0).toFixed(2);
}
if(game.timeProgress >= 1.5 && game.timeProgress <= 3.0) {
- game.ui.root.querySelectorAll('.ui-page.title button').forEach((btn) => {
+ game.ui.root.querySelectorAll('.ui-page.title > button').forEach((btn) => {
let timeOffset = Array.from(btn.parentNode.children).indexOf(btn) - 2;
btn.style.left = 10 * easeInOut(Math.max(0.0, Math.min(1.0, 0.3 * timeOffset + 2.5 - game.timeProgress))).toFixed(2) + 'em';
let opacity = easeInOut(Math.max(0.0, Math.min(1.0, -0.3 * timeOffset + game.timeProgress - 1.5)));
}
if(game.timeProgress >= 3.0 && game.timeProgress <= 4.0) {
game.ui.root.querySelector('.ui-page.title .footer').style.opacity = easeInOut(Math.max(0.0, Math.min(1.0, game.timeProgress - 3.0))).toFixed(2);
+ game.ui.root.querySelector('.ui-page.title .system-buttons').style.opacity = easeInOut(Math.max(0.0, Math.min(1.0, game.timeProgress - 3.0))).toFixed(2);
}
if(game.timeProgress > 4.0 && !game.ui.reachedStart) {
game.ui.root.querySelector('.ui-page.title h1').removeAttribute('style');
- game.ui.root.querySelectorAll('.ui-page.title button').forEach(btn => { btn.disabled = false; btn.removeAttribute('style'); });
+ game.ui.root.querySelectorAll('.ui-page.title > button').forEach(btn => { btn.disabled = false; btn.removeAttribute('style'); });
game.ui.root.querySelector('.ui-page.title .footer').removeAttribute('style');
+ game.ui.root.querySelector('.ui-page.title .system-buttons').removeAttribute('style');
game.ui.reachedStart = true;
}
}
if(!game.view.windSound.isPlaying) {
game.view.windSound.setVolume(game.settings['audio']['sounds']);
game.view.windSound.offset = 0;
- game.view.windSound.play();
+ if(!game.view.muted) {
+ game.view.windSound.play();
+ }
}
}
if(game.timeProgress > 1.0 && game.timeProgress <= 5.0) {
elem.style.opacity = opacity.toFixed(2);
});
game.view.music.offset = 0;
- game.view.music.play();
+ if(!game.view.muted) {
+ game.view.music.play();
+ }
moveToPage(game, 'gameplay', true);
}
} else if(game.ui.currentPage == 'endingcutscene') {
const remainingRealTime = (game.timeTotal - game.timeProgress) / (game.settings['difficulty']['speed'] / 100);
if(remainingRealTime >= game.assets['audio']['music-' + game.settings['audio']['theme']].duration - 2) {
game.view.music.offset = 0;
- game.view.music.play();
+ if(!game.view.muted) {
+ game.view.music.play();
+ }
}
}
game.ui.root.querySelector('.ui-page.title h1').removeAttribute('style');
game.ui.root.querySelectorAll('.ui-page.title button').forEach(btn => { btn.disabled = false; btn.removeAttribute('style'); });
game.ui.root.querySelector('.ui-page.title .footer').removeAttribute('style');
+ game.ui.root.querySelector('.ui-page.title .system-buttons').removeAttribute('style');
game.ui.reachedStart = true;
}, fadeDuration);
}
if(game.timeProgress >= 1.0) {
game.view.windSound.offset = game.timeProgress - 1.0;
game.view.windSound.setVolume(game.settings['audio']['sounds']);
- game.view.windSound.play();
+ if(!game.view.muted) {
+ game.view.windSound.play();
+ }
}
} else if(game.ui.currentPage == 'pause' && target == 'gameplay') {
game.view.music.offset = (game.timeProgress / (game.settings['difficulty']['speed'] / 100)) % game.assets['audio']['music-' + game.settings['audio']['theme']].duration;
- game.view.music.play();
+ if(!game.view.muted) {
+ game.view.music.play();
+ }
}
game.ui.previousPage = game.ui.currentPage;
game.ui.currentPage = target;
}
});
});
+game.ui.root.querySelector('.ui-page.title .system-buttons input').addEventListener('change', (e) => {
+ game.view.muted = e.target.checked;
+});
+game.ui.root.querySelector('.ui-page.title .system-buttons button').addEventListener('click', (e) => {
+ if(document.fullscreenElement == game.ui.root.parentNode) {
+ document.exitFullscreen();
+ } else {
+ game.ui.root.parentNode.requestFullscreen();
+ }
+});
game.ui.root.querySelectorAll('.ui-page .audio input[type=range]').forEach((elem) => {
elem.addEventListener('input', (e) => {
let audioCategory = Array.from(e.target.classList).filter(v => ['music', 'sounds'].includes(v))[0];
}
} else {
game.view.music.offset = 36;
- game.view.music.play();
+ if(!game.view.muted) {
+ game.view.music.play();
+ }
game.view.music.timeoutID = setTimeout(() => {
game.view.music.stop();
}, 6000);