Switch-Level.ps1
function Switch-Level { <# .Synopsis Switches the game level .Description Switches to a different level of the game. If the level does not exist, a message will be written to -Verbose, and the game will otherwise continue to run. This enables virtual levels of increasing difficulty. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "", Justification="Games Must Use the Host")] [OutputType([Nullable])] param( # The name of the level [Parameter(Mandatory,Position=0)] [Alias('Level')] [string] $Name, # A script to run after switching the level. This can be used to provide dynamic level setup [ScriptBlock] $Then, # If set, will not run the Level's initialize routine [Alias('NoInit','DoNotInitialize')] [switch] $NoInitialize, # If set, will not clear the screen, clear the spritemap, and clear the sprite list [Alias('DoNotClear')] [switch] $NoClear, # If set, will clear the screen and redraw the current level. [switch] $Redraw ) process { if (-not $Global:Game) { Write-Error "Cannot switch a level without initializing the game." return } if ($Global:Game.CurrentLevelName -eq $Name) { return } if (-not $Global:Game.Levels[$Name]) { #region Initialize Dynamic Level Write-Verbose "Level name $name not found in $($game.Name)" $Global:Game.CurrentLevel = [PSCustomObject]@{ PSTypeName='PowerArcade.Level'; Name=$Name; Sprites=[Collections.Generic.List[PSObject]]::new() SpatialMap = [Collections.Generic.Dictionary[ string, [Collections.Generic.List[PSObject]] ]]::new([StringComparer]::OrdinalIgnoreCase) SpritesByID = [Collections.Generic.Dictionary[ string, [PSObject] ]]::new([StringComparer]::OrdinalIgnoreCase) SpriteMap=[Collections.Generic.Dictionary[string,[Collections.Queue]]]::new([StringComparer]::OrdinalIgnoreCase) } foreach ($X in 0..$game.CellWidth) { foreach ($Y in 0..$game.CellHeight) { $Game.CurrentLevel.SpatialMap["$X,$y"] = [Collections.Generic.List[PSObject]]::new() } } #endregion Initialize Dynamic Level } else { $Global:Game.CurrentLevel = $Global:Game.Levels[$Name] } $Global:Game.CurrentLevelName = $Name $OnKey = @{} foreach ($method in @($Global:Game.psobject.Methods; $Global:Game.CurrentLevel.psobject.Methods)) { if ($method.Name -like 'OnKey_*') { $onKey[$method.Name.Substring(6)] = $method.Script } } $Global:Game.PSObject.Members.Add([PSNoteProperty]::new('KeyHandlers', $OnKey)) if ($Redraw) { Clear-Host if ($game.BackgroundColor) { # [Console]::Write(('' + [char]0x1b + '[1049l')) ([PSCustomObject]@{ PSTypeName='PowerArcade.Box' BackgroundColor = $game.BackgroundColor } | Out-String -Width 1kb).Trim() | Write-Host -NoNewline } $Game.CurrentLevel.Draw() return } if (-not $NoClear) { Clear-Host if ($game.BackgroundColor) { # [Console]::Write(('' + [char]0x1b + '[1049l')) [Console]::Write(([PSCustomObject]@{ PSTypeName='PowerArcade.Box' BackgroundColor = $game.BackgroundColor } | Out-String -Width 1kb).Trim()) } [Console]::CursorVisible = $false if ($game.CurrentLevel.Sprites.Clear) { $game.CurrentLevel.Sprites.Clear() } if ($game.CurrentLevel.SpriteMap.Clear) { $game.CurrentLevel.SpriteMap.Clear() } } if (-not $NoInitialize) { $Global:Game.CurrentLevel | Add-Member NoteProperty Initializing $true -Force if ($Global:Game.LevelBaseObject.Initialize.Invoke) { $Global:Game.LevelBaseObject.Initialize() } if ($Global:Game.CurrentLevel.Initialize.Invoke) { $Global:Game.CurrentLevel.Initialize() } if ($then) { $Global:Game.CurrentLevel | Add-Member NoteProperty DynamicInitialize $then -Force } if ($Global:Game.CurrentLevel.DynamicInitialize.Invoke) { $Global:Game.CurrentLevel.DynamicInitialize.Invoke() } $Global:Game.CurrentLevel.Initializing = $false } $Global:Game.CurrentLevel.Draw() #[Console]::CursorVisible = $false } } |