functions/Start-MiniGameFirework.ps1

function Start-MiniGameFirework {
    <#
    .SYNOPSIS
    A function for creating fireworks in the Terminal.
 
    .DESCRIPTION
    A function for creating fireworks in the Terminal.
    Shoots fireworks in random intervalls. May not work correctly at times.
    Mainly just testing capabillities of Powershell Terminal.
 
    .OUTPUTS
                                                         *..*
                                                        *_\/_*
                  '.\'/.' *..*
                  -= o =-
                  .'/.\'.
 
                                    '
                                  = o =
                                    .
                                               .
                                               ^
 
                    .
                    ^
 
 
 
     
    .EXAMPLE
 
    Start Fireworks with cure hearts only:
 
    PS> Start-Fireworks hearts
     
 
 
    .LINK
     
    #>


    

    [CmdletBinding( )]
    param (
        # Set the types of fireworks to use.
        [Parameter(
            Position = 0
        )]
        [System.String]
        [ValidateSet(
            'hearts',
            'normal'
        )]
        $FireworkType,

        # Enables the game sound to be played.
        [Parameter(
            Position = 1
        )]
        [switch]
        $Sound
    )

    $gameSettings = @{
        TickSpanMilliseconds = 75
        InvertY              = $true
        Mute                 = -NOT $Sound.IsPresent
    }
    $gameUtility = New-MiniGameRunUtility @gameSettings 
    $gameUtility.sound.Add('explosion_01', "$PSScriptRoot\assets\sounds\firework_explosion_01.wav")
    $gameUtility.sound.Add('explosion_02', "$PSScriptRoot\assets\sounds\firework_explosion_02.wav")
    $gameUtility.sound.Add('explosion_03', "$PSScriptRoot\assets\sounds\firework_explosion_03.wav")
    $gameUtility.set(
        @{
            Velocity   = 1
            StageTicks = 5 
            Intervall  = 7
            Explosion  = @{
                Max   = 20
                Count = -1
            }
        }
    )
    if ($FireWorkType -IEQ 'hearts') {
        $gameUtility.set(
            @{
                Types  = (Import-PowerShellDataFile -Path "$PSScriptRoot/assets/data/fireworks.hearts.psd1").fire_works
                Colors = @('Red', 'Magenta')
            }
        )
    }
    else {
        $gameUtility.set(
            @{
                Types  = (Import-PowerShellDataFile -Path "$PSScriptRoot/assets/data/fireworks.normal.psd1").fire_works
                Colors = @('Red', 'Green', 'Yellow', 'Blue', 'Magenta', 'Cyan', 'White')
            }
        )
    }
    $gameUtility.func('generate', 
        {
            param($var, $canvas, $object)
            $randomX = Get-Random -Minimum 5 -Maximum ($canvas.Maximum.X - 5)
            $randomY = Get-Random -Minimum 5 -Maximum ($canvas.Maximum.Y - 5)
            $rocket = $object.Add()
            $rocket.Group('rocket')
            $rocket.SetVel(0, $var.Velocity)
            $rocket.SetPos($randomX, 0)
            $rocket.Set('explosionY', $randomY)
            $rocket.AddCanvas(
                @(
                    'o',
                    '|'
                )
            )
        }
    )
    $gameUtility.func('fly', 
        {
            param($rocket, $var, $canvas, $sound, $object)
            if ($rocket.Y -LT $rocket.Get('explosionY')) {
                $rocket.Move()
                $rocket.Redraw()
                return
            }

            $random = Get-Random -Minimum 1 -Maximum 4
            $sound.Play("explosion_0$random")

            $randomColor = Get-Random -Minimum 0 -Maximum ($var.Colors.Count)
            $randomExplosion = Get-Random -Minimum 0 -Maximum ($var.Types.Count)
            $fireworkColor = $var.Colors[$randomColor]
            $fireworkType = $var.Types[$randomExplosion]

            $calcX = $rocket.position.x - $fireworkType[0][0].Length / 2
            $explosion = $object.Add()
            $explosion.Group('explosion')
            $explosion.SetPos($calcX, $rocket.position.y)
            for ($index = $fireworkType.Count - 1; $index -GE 0; $index--) {
                $explosion.AddCanvas($index, $fireworkType[$index])
            }
            $explosion.Set('color', $fireworkColor)
            $explosion.Set('stage', $fireworkType.Count)
            $explosion.Set('time', 0)

            $canvas.ForeGround.onceColor($fireworkColor)
            $rocket.Remove()
            $explosion.Draw()
        }
    )
    $gameUtility.func('expand', 
        {
            param($explosion, $var, $canvas)

            $color = $explosion.Get('color')
            $stage = $explosion.Get('stage')
            $time = $explosion.Get('time')
            $explosion.Add('time', 1)

            if ($time % $var.stageTicks -NE 0) {
                continue
            }

            if ($stage -EQ 0) {
                $explosion.Remove()
                continue
            }

            $canvas.ForeGround.onceColor($color)
            $explosion.Sub('stage', 1)
            $explosion.SetCanvas($stage - 1)
            $explosion.Redraw()
        }
    )
    $gameUtility.loop( 
        {
            param($var, $func, $canvas, $sound, $object, $stop)

            $rockets = $object.GetGroup('rocket')
            $explosions = $object.GetGroup('explosion')
  
            foreach ($rocket in $rockets) {
                $func.fly.Invoke($rocket, $var, $canvas, $sound, $object)
            }

            foreach ($explosion in $explosions) {
                $func.expand.Invoke($explosion, $var, $canvas)
            }

            # Generate new fireworks at random intervals between 0 and 50 ticks.
            $random = Get-Random -Minimum 0 -Maximum $var.Intervall
            if ($random -EQ 0 -AND $explosions.Count -LE $var.Explosion.Max) {
                # $sound.Play('takeoff')
                $func.generate.Invoke($var, $canvas, $object)
            }

            # Redraw the count of explosions on every tick.
            if ($var.Explosion.Count -NE $explosions.Count) {
                $canvas.undraw(0, $canvas.Maximum.Y - 1, "Explosions: XXX")
                $canvas.draw(0, $canvas.Maximum.Y - 1, "Explosions: $($explosions.Count)")
                $var.Explosion.Count = $explosions.Count
            }
        }
    )

}