functions/MiniGameSnake/scene/loop.ps1

param($var, $func, $canvas, $sound, $object, $stop)

$var.velocity = $var.nextVelocity
$characters = $var.difficulty.chars
$snakeTail = $var.snake | Select-Object -Last 1

$snakeHead = [System.Numerics.Vector2]@{
    X = $var.snake[0].X + $var.velocity.X
    Y = $var.snake[0].Y + $var.velocity.Y
}

### Every element of the snake is moved to the position of the element in front of it
for ($index = $var.snake.Count - 1; $index -GE 1; $index--) {
    $var.snake[$index] = [System.Numerics.Vector2]@{
        X = $var.snake[$index - 1].X
        Y = $var.snake[$index - 1].Y
    } 
}

$canvas.Draw($var.snake[0], $characters.Snake.Body)
$canvas.Draw($snakeHead, $characters.Snake.Head)

<#
 
    The logic for growing the snake:
    - a new snake tail is created
    - it is added as the last element of the snake
 
    When not growing:
    - remove the tail from the collision map and undraw it
#>

if ($var.snake.Count -LT $var.snakeLength) {
    $snakeTail = [System.Numerics.Vector2]@{
        X = $snakeTail.X
        Y = $snakeTail.Y
    }
    $var.snake += $snakeTail
    $canvas.Draw($snakeTail, $characters.Snake.Body)
}
else {
    $var.collisionMap.Remove($snakeTail)
    $canvas.Undraw($snakeTail, $characters.Snake.Body)
}



<#
 
    The collision checks:
    - Check if the snake has hit a wall
    - Check if the snake has hit itself
    - Else: add the new head to the snake and collision map
#>

if ($canvas.Bounds.IsOutside('cage', $snakeHead)) {
    $stop.Invoke('Snake hit a Wall')
}
elseif ($var.collisionMap.ContainsKey($snakeHead)) {
    $stop.Invoke('Snake hit itself')
}
else {
    $var.collisionMap.Add($snakeHead, $null)
    $var.snake[0] = $snakeHead
}


<#
 
    Snack the snake snack and create a new snake snack.
#>

if (
    $null -EQ $var.snakeSnack -OR 
    $snakeHead.Equals($var.snakeSnack)
) {
    $func.snack.Invoke($var, $canvas, $sound)
}


<#
 
    Draw the stats on the canvas:
#>


$canvas.Draw(0, 2, "Snacks eaten: $($var.snackedSnakeSnacks)")
$canvas.DrawRight(0, 2, "Snake: $($var.snakeLength)")

$canvas.ForeGround.onceRGB($var.difficulty.color.text)
$canvas.Draw(0, 1, $var.difficulty.name)