如何防止批处理脚本中cls引起的闪烁?

问题描述 投票:0回答:1

我一直在开发一个具有某种动画介绍的批处理脚本,我的第一个想法是在每一帧之前使用 cls 清除控制台,但这会导致可怕的闪烁,如本视频 https://streamable 所示。 com/o34k0e.

这是我使用的批处理代码:

@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

我还尝试使用 PowerShell,但它甚至无法显示第二帧,如下所示:

# 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
}

执行PowerShell文件的批处理代码:

@echo off
chcp 65001 >nul
PowerShell -NoProfile -ExecutionPolicy Bypass -File "%~dp0drip-animation.ps1"
pause

powershell batch-file animation terminal
1个回答
0
投票
  • 您可以在 [Console]

     .NET API的帮助下在 PowerShell 中解决问题,如下所示。

  • 要使用此解决方案,您既不需要在包装批处理文件中使用

    chcp 65001 >nul
    ,也不需要在 PowerShell 脚本中使用
    [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
    (在 PowerShell 中,
    [Console]::OutputEncoding
    仅与与外部程序通信相关)。

    • 但是,请务必将
      *.ps1
      保存为带有 BOM 的 UTF-8
      ,以便 Windows PowerShell 正确读取文件 (PowerShell (Core) 7,始终默认为 (BOM- less) UTF-8 也能正确读取无 BOM 的 UTF-8 文件。
# 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
© www.soinside.com 2019 - 2024. All rights reserved.