160 lines
5.6 KiB
TypeScript
160 lines
5.6 KiB
TypeScript
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();
|