import { glMatrix } from 'gl-matrix'; import { LampBase, overrideDeserialization, PlanetBase, CharacterBase, ProjectileBase, } from 'shared'; import './main.scss'; import './scripts/analytics'; import '../static/og-image.png'; import '../static/favicons/apple-touch-icon.png'; import '../static/favicons/favicon-16x16.png'; import '../static/favicons/favicon-32x32.png'; import '../static/favicons/favicon.ico'; import { LandingPageBackground } from './scripts/landing-page-background'; import { JoinFormHandler } from './scripts/join-form-handler'; import { handleFullScreen } from './scripts/helper/handle-full-screen'; import { Game } from './scripts/game'; import ResizeObserver from 'resize-observer-polyfill'; import { OptionsHandler } from './scripts/options-handler'; import { hide } from './scripts/helper/hide'; import { show } from './scripts/helper/show'; import { SoundHandler, Sounds } from './scripts/sound-handler'; import { VibrationHandler } from './scripts/vibration-handler'; import { CharacterView } from './scripts/objects/types/character-view'; import { LampView } from './scripts/objects/types/lamp-view'; import { PlanetView } from './scripts/objects/types/planet-view'; import { ProjectileView } from './scripts/objects/types/projectile-view'; glMatrix.setMatrixArrayType(Array); overrideDeserialization(CharacterBase, CharacterView); overrideDeserialization(PlanetBase, PlanetView); overrideDeserialization(LampBase, LampView); overrideDeserialization(ProjectileBase, ProjectileView); const landingUI = document.querySelector('#landing-ui') as HTMLElement; const nameInput = document.querySelector('#name') as HTMLInputElement; const joinGameForm = document.querySelector('#join-game-form') as HTMLFormElement; const serverContainer = document.querySelector('#server-container') as HTMLElement; const canvas = document.querySelector('canvas') as HTMLCanvasElement; const overlay = document.querySelector('#overlay') as HTMLElement; const settings = document.querySelector('#settings') as HTMLElement; const toggleSettingsButton = document.querySelector( '#toggle-settings-container', ) as HTMLElement; const minimize = document.querySelector('#minimize') as HTMLElement; const maximize = document.querySelector('#maximize') as HTMLElement; const logoutButton = document.querySelector('#logout') as HTMLElement; const enableSounds = document.querySelector('#enable-sounds') as HTMLInputElement; const enableMusic = document.querySelector('#enable-music') as HTMLInputElement; const enableVibration = document.querySelector('#enable-vibration') as HTMLInputElement; const spinner = document.querySelector('#spinner-container') as HTMLElement; const toggleSettings = () => { settings.className = settings.className === 'open' ? '' : 'open'; SoundHandler.play(Sounds.click); }; const applyServerContainerShadows = () => { const topShadow = 'inset 0 -8px 8px -8px rgba(0, 0, 0, 0.4)'; const bottomShadow = 'inset 0 8px 8px -8px rgba(0, 0, 0, 0.4)'; const { scrollHeight, clientHeight, scrollTop } = serverContainer; if (scrollHeight > clientHeight) { if (scrollTop <= 0) { serverContainer.style.boxShadow = topShadow; } else if (scrollTop + clientHeight >= scrollHeight) { serverContainer.style.boxShadow = bottomShadow; } else { serverContainer.style.boxShadow = topShadow + ',' + bottomShadow; } } else { serverContainer.style.boxShadow = ''; } }; const main = async () => { try { let game: Game; const storedUserName = localStorage?.getItem('userName'); if (storedUserName) { nameInput.value = JSON.parse(storedUserName); } const firstClickListener = () => { SoundHandler.initialize( () => { enableMusic.checked = true; enableMusic.dispatchEvent(new Event('change')); }, () => { enableMusic.checked = false; enableMusic.dispatchEvent(new Event('change')); }, ); document.removeEventListener('click', firstClickListener); }; document.addEventListener('click', firstClickListener); if (!VibrationHandler.isVibrationEnabledHeuristics) { hide(document.querySelector("label[for='enable-vibration']") as HTMLElement, true); } handleFullScreen(minimize, maximize); toggleSettingsButton.addEventListener('click', toggleSettings); new ResizeObserver(applyServerContainerShadows).observe(serverContainer); serverContainer.addEventListener('scroll', applyServerContainerShadows); OptionsHandler.initialize({ soundsEnabled: enableSounds, vibrationEnabled: enableVibration, musicEnabled: enableMusic, }); logoutButton.addEventListener('click', () => { game.destroy(); toggleSettings(); }); window.onpopstate = () => game.destroy(); for (;;) { show(spinner); hide(logoutButton, true); show(landingUI, true, 'flex'); const background = new LandingPageBackground(canvas); const joinHandler = new JoinFormHandler(joinGameForm, serverContainer); await background.renderer; hide(spinner); const playerDecision = await joinHandler.getPlayerDecision(); localStorage?.setItem('userName', JSON.stringify(playerDecision.name)); if (!history.state) { history.pushState(true, ''); } hide(landingUI, true); show(spinner); background.destroy(); game = new Game(playerDecision, canvas, overlay); const gameOver = game.start(); await game.started; hide(spinner); show(logoutButton, true, 'block'); await gameOver; } } catch (e) { console.error(e); alert(e); } }; main();