I have been working on a batch script which has some sort of animated intro, My first thought was to use cls to clear the console before every frame, but that caused horrible flickering, as shown in this video https://streamable.com/o34k0e.
this is the batch code I used:
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
::
:loop
cls
for /L %%A in (1,1,20) do (
cls
call :frame %%A
ping -n 1 -w 300 127.0.0.1 >nul
)
goto loop
goto :eof
:frame
:: full letters
set "letters1= █ █░▓█████ ██▓ ▄████▄ ▒█████ ███▄ ▄███▓▓█████"
set "letters2= ▓█░ █ ░█░▓█ ▀ ▓██▒ ▒██▀ ▀█ ▒██▒ ██▒▓██▒▀█▀ ██▒▓█ ▀"
set "letters3= ▒█░ █ ░█ ▒███ ▒██░ ▒▓█ ▄ ▒██░ ██▒▓██ ▓██░▒███"
set "letters4= ░█░ █ ░█ ▒▓█ ▄ ▒██░ ▒▓▓▄ ▄██▒▒██ ██░▒██ ▒██ ▒▓█ ▄"
set "letters5= ░░██▒██▓ ░▒████▒░██████▒▒ ▓███▀ ░░ ████▓▒░▒██▒ ░██▒░▒████▒"
set "letters6= ░ ▓░▒ ▒ ░░ ▒░ ░░ ▒░▓ ░░ ░▒ ▒ ░░ ▒░▒░▒░ ░ ▒░ ░ ░░░ ▒░ ░"
set "letters7= ▒ ░ ░ ░ ░ ░░ ░ ▒ ░ ░ ▒ ░ ▒ ▒░ ░ ░ ░ ░ ░ ░"
set "letters8= ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░"
set "letters9= ░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░"
set "letters10= ░"
:: play dripping effect by changing characters in the lines 5, 6, 7, 8, 9
if %1 lss 5 (
set "letters5=%letters5:▒= %"
) else if %1 lss 10 (
set "letters6=%letters6:░= %"
) else if %1 lss 15 (
set "letters7=%letters7:▒= %"
) else if %1 lss 20 (
set "letters8=%letters8:░= %"
) else if %1 lss 25 (
set "letters9=%letters9:▓= %"
)
:: display the letters with the "dripping" effect
echo.
echo !letters1!
echo !letters2!
echo !letters3!
echo !letters4!
if defined letters5 echo !letters5!
if defined letters6 echo !letters6!
if defined letters7 echo !letters7!
if defined letters8 echo !letters8!
if defined letters9 echo !letters9!
echo !letters10!
goto :eof
And I also tried using PowerShell which also failed to even display a second frame, as seen here:
# UTF-8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# define the letters for the animation
$lines = @(
" █ █░▓█████ ██▓ ▄████▄ ▒█████ ███▄ ▄███▓▓█████",
" ▓█░ █ ░█░▓█ ▀ ▓██▒ ▒██▀ ▀█ ▒██▒ ██▒▓██▒▀█▀ ██▒▓█ ▀",
" ▒█░ █ ░█ ▒███ ▒██░ ▒▓█ ▄ ▒██░ ██▒▓██ ▓██░▒███",
" ░█░ █ ░█ ▒▓█ ▄ ▒██░ ▒▓▓▄ ▄██▒▒██ ██░▒██ ▒██ ▒▓█ ▄",
" ░░██▒██▓ ░▒████▒░██████▒▒ ▓███▀ ░░ ████▓▒░▒██▒ ░██▒░▒████▒",
" ░ ▓░▒ ▒ ░░ ▒░ ░░ ▒░▓ ░░ ░▒ ▒ ░░ ▒░▒░▒░ ░ ▒░ ░ ░░░ ▒░ ░",
" ▒ ░ ░ ░ ░ ░░ ░ ▒ ░ ░ ▒ ░ ▒ ▒░ ░ ░ ░ ░ ░ ░",
" ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ░",
" ░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░",
" ░"
)
# loop for animation
while ($true) {
# clear the console
Clear-Host
# loop through each line to create the dripping effect
for ($i = 0; $i -lt $lines.Count; $i++) {
$line = $lines[$i]
# changq certain characters based on their index
if ($i -ge 4 -and $i -lt 9) {
if ($i -eq 4) { $line = $line -replace '▒', ' ' }
elseif ($i -eq 5) { $line = $line -replace '░', ' ' }
elseif ($i -eq 6) { $line = $line -replace '▒', ' ' }
elseif ($i -eq 7) { $line = $line -replace '░', ' ' }
elseif ($i -eq 8) { $line = $line -replace '▓', ' ' }
}
# the modified line
Write-Host $line
}
# wait before refreshing the display
Start-Sleep -Milliseconds 300
}
Batch code to execute the PowerShell file:
@echo off
chcp 65001 >nul
PowerShell -NoProfile -ExecutionPolicy Bypass -File "%~dp0drip-animation.ps1"
pause
You can solve the problem in PowerShell with the help of the [Console]
.NET API, as shown below.
[Console]::SetCursorPosition(0, 0)
to set the cursor back in the top-left corner before writing the next animation frame, which doesn't require clearing the whole screen first (cls
, Clear-Host
).To use this solution, you neither need chcp 65001 >nul
in your wrapper batch file, nor [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
in the PowerShell script (in PowerShell, [Console]::OutputEncoding
only matters with respect to communicating with external programs).
*.ps1
file as UTF-8 with BOM, so that Windows PowerShell reads the file correctly (PowerShell (Core) 7, which consistently defaults to (BOM-less) UTF-8, would also read a BOM-less UTF-8 file correctly.# Define the lines for the animation
$lines = @'
█ █░▓█████ ██▓ ▄████▄ ▒█████ ███▄ ▄███▓▓█████
▓█░ █ ░█░▓█ ▀ ▓██▒ ▒██▀ ▀█ ▒██▒ ██▒▓██▒▀█▀ ██▒▓█ ▀
▒█░ █ ░█ ▒███ ▒██░ ▒▓█ ▄ ▒██░ ██▒▓██ ▓██░▒███
░█░ █ ░█ ▒▓█ ▄ ▒██░ ▒▓▓▄ ▄██▒▒██ ██░▒██ ▒██ ▒▓█ ▄
░░██▒██▓ ░▒████▒░██████▒▒ ▓███▀ ░░ ████▓▒░▒██▒ ░██▒░▒████▒
░ ▓░▒ ▒ ░░ ▒░ ░░ ▒░▓ ░░ ░▒ ▒ ░░ ▒░▒░▒░ ░ ▒░ ░ ░░░ ▒░ ░
▒ ░ ░ ░ ░ ░░ ░ ▒ ░ ░ ▒ ░ ▒ ▒░ ░ ░ ░ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ░
░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░
░
'@ -split '\r?\n'
[Console]::Clear()
[Console]::CursorVisible = $false
foreach ($i in 1..20) {
[Console]::SetCursorPosition(0, 0)
[Console]::Write($lines -join "`n")
Start-Sleep -Milliseconds 300
if ($i -lt 5) { $lines[4] = $lines[4] -replace '▒', ' ' }
elseif ($i -lt 10) { $lines[5] = $lines[5] -replace '░', ' ' }
elseif ($i -lt 15) { $lines[6] = $lines[6] -replace '▒', ' ' }
elseif ($i -lt 20) { $lines[7] = $lines[7] -replace '░', ' ' }
elseif ($i -lt 25) { $lines[8] = $lines[8] -replace '▓', ' ' }
}
[Console]::CursorVisible = $true