import { state } from "../state" ; import { Level } from "../level" ; import { Util } from "../util" ; import { Replay } from "../replay" ; import { Mission } from "../mission" ; import { Menu } from "./menu" ; export abstract class LoadingScreen { menu : Menu ; div : HTMLDivElement ; levelNameElement : HTMLParagraphElement ; cancelButton : HTMLImageElement ; progressBar : HTMLDivElement ; loadingIndex = 0 ; refresher : number ; abstract maxProgressBarWidth : number ; constructor ( menu ) { this . menu = menu ; this . initProperties ( ) ; menu . setupButton ( this . cancelButton , 'loading/cancel' , ( ) => { this . hide ( ) ; menu . levelSelect . show ( ) ; this . loadingIndex ++ ; clearInterval ( this . refresher ) ; } ) ; } abstract initProperties ( ) ; show ( ) { this . div . classList . remove ( 'hidden' ) ; } hide ( ) { this . div . classList . add ( 'hidden' ) ; } async loadLevel ( mission , getReplay ? ) { this . show ( ) ; let indexAtStart = this . loadingIndex ; this . levelNameElement . textContent = mission . title ; this . progressBar . style . width = '0px' ; await Util . wait ( 50 ) ; try { await mission . load ( ) ; if ( this . loadingIndex !== indexAtStart ) return ; this . refresher = setInterval ( ( ) => { let completion = level . getLoadingCompletion ( ) ; this . progressBar . style . width = ( completion * this . maxProgressBarWidth ) + 'px' ; } ) as unknown as number ; let level = new Level ( mission ) ; state . level = level ; await level . init ( ) ; if ( getReplay ) { let replay = getReplay ( ) ; level . replay = replay ; replay . level = level ; replay . mode = 'playback' ; } if ( this . loadingIndex !== indexAtStart ) { level . dispose ( ) ; return ; } clearInterval ( this . refresher ) ; let start = performance . now ( ) ; this . refresher = setInterval ( ( ) => { let completion = Util . clamp ( ( performance . now ( ) - start ) / 100 , 0 , 1 ) ; this . progressBar . style . width = ( completion * this . maxProgressBarWidth ) + 'px' ; } ) ; await Util . wait ( 150 ) ; if ( this . loadingIndex !== indexAtStart ) { level . dispose ( ) ; return ; } clearInterval ( this . refresher ) ; level . start ( ) ; this . hide ( ) ; this . menu . hide ( ) ; this . menu . showGameUi ( ) ; } catch ( e ) { console . error ( e ) ; this . cancelButton . click ( ) ; state . level = null ; state . menu . showAlertPopup ( 'Error' , "There was an error due to which the level couldn't be loaded." ) ; } } }