import { levels } from '../data' ; import { Observer } from '.' ; import { Task } from '../helpers' ; import { Interaction , Position , SceneTransition , Tile } from '../interfaces' ; export class Level extends Observer { public root : HTMLElement ; public name : string ; public grid : any ; constructor ( name , root , isDebugMode = false ) { super ( ) ; this . _acceptedTasks = new Set ( [ 'scene-transition-start' ] ) ; this . root = root ; this . name = name ; this . grid = levels [ name ] ; if ( isDebugMode ) { this . triggerDebugView ( ) ; } } handleUpdate ( { name , action } ) { switch ( name ) { case 'scene-transition-start' : this . handleSceneTransitionStart ( action ) ; break ; } } handleSceneTransitionStart ( action ) { const { level , } = action ; this . changeGrid ( level ) ; const { path } = this . grid ; this . changeMap ( path ) ; } getTile ( x , y ) { return this . grid [ `${ x }/${ y }` ] ; } getSceneTransition ( x , y ) { return this . getTile ( x , y ) . sceneTransition ; } getInteraction ( x , y ) { return this . getTile ( x , y ) . interaction ; } isSpaceWalkable ( x , y ) { if ( ! this . getTile ( x , y ) ) return false ; return this . getTile ( x , y ) . isWalkable ; } isSceneTransition ( x , y ) { if ( ! this . getTile ( x , y ) ) return false ; return ! ! this . getTile ( x , y ) . sceneTransition ; } isInteraction ( x , y ) { if ( ! this . getTile ( x , y ) ) return false ; return ! ! this . getTile ( x , y ) . interaction ; } triggerDebugView ( ) { for ( const tile in this . grid ) { const { x , y , isWalkable } = this . grid [ tile ] ; const element = document . createElement ( 'div' ) ; element . className = 'space' ; element . style . top = `${ y * 64 }px` ; element . style . left = `${ x * 32 }px` ; element . textContent = `${ x }/${ y }` ; if ( isWalkable ) { element . style . border = '2px solid green' ; } else { element . style . border = '2px solid red' ; } this . root . append ( element ) ; } this . root . style . width = '1920px' ; this . root . style . height = '1280px' ; } changeMap ( path ) { this . root . style . backgroundImage = `url('${ path }')` ; } changeGrid ( gridName ) { this . grid = levels [ gridName ] ; } shiftBackgroundPosition ( x , y ) { this . root . style . backgroundPosition = `${ x }px ${ y }px` ; } async loadBackgroundImages ( ) { const filePaths = Object . values ( levels ) . map ( ( l ) => l . path ) ; await Promise . all ( filePaths . map ( path => { return new Promise ( ( resolve , reject ) => { const image = new Image ( ) ; image . onload = resolve ; image . onerror = reject ; image . src = path ; } ) ; } ) ) ; } async init ( ) { await this . loadBackgroundImages ( ) ; const { path , playerSpawnPoint , backgroundSpawnPoint } = this . grid ; const [ x , y ] = backgroundSpawnPoint ; this . changeMap ( path ) ; this . shiftBackgroundPosition ( x , y ) ; return playerSpawnPoint ; } }