Windows CMD Bildflakern?

1 Antwort

Erstmal gleich vorn weg: Batch ist eine Sprache zur Steuerung administrativer Abläufe und nicht unbedingt angetan um Animationen zu programmieren.

Ich hab aus Spaß mal eine Animation geschrieben mit Hilde dieses Befehls: Ping localhost -n 2 >nul

...entschuldig das lies mich erstmal grinsen... Diese Variante des Ping-Befehls macht nichts weiter als eine Pause von . 1 Sekunde einzulegen. Zudem verwendet heute kaum noch jemand Ping für diese Zwecke. Timeout 1 tut es auch. Allerdings ist eine Sekunde zu lang für eine Animation. Eine Bremsschleife ist zwar sehr ungenau, lässt sich jedoch relativ leicht "dosieren".

@echo off
  rem  fenstergröße  festlegen
mode 60,20
  rem anzahl der Durchläufe  für  die Bremsschleife
set "delay=20000"
  rem 1000 Punkte zeichnen (mal  ohne  for-l-Loop)
set "Punkte=."

:loop
cls
echo %Punkte%
  rem mitzählen, damit wir wissen wann Schluß ist..
set /a "count+=1"
  rem einen Punkt  zur Variable Punkte  hinzufügen
set "Punkte=%Punkte%."
  rem bremsschleife...(tut  nichts  weiter als einige 1000mal Nichts zu tun)
for /l %%. in (1,1,%delay%) do rem
if %count% leq 1000 goto :loop
pause

Das Flackern beruht darauf, das vor jedem Zeichnen eines neuen Frames das alte Bild mit CLS gelöscht wird (es wird ein leeres Fenster gezeichnet und dann etwas reingeschrieben. der Effekt ist: "leer, nichtleer,leer,nichtleer,aus,an,aus,an ,aus,an...",das flackert). ...und da liegt die Cruks. CLS überschreibt den gesamten Consolenbereich und setzt den Cursor an den Anfang. Je größer das Fenster ist (inclusive Puffer) um so mehr muss überschrieben werden und das dauert. Hinzu kommt auch noch das die Animation auch nicht mit der Refreshrate des Bildschirms synchronisiert werden kann und die Befehlszeiten in der Console nicht unbedingt immer die gleiche Zeit benötigen. Je nach dem, wie der Lösch/Schreibvorgang gerade mit der Prozesszeit/Prozessorauslastung korreliert flackerts mal mehr mal weniger (zeitliche Interferenz)

Das bleibt auch mir bei der Art wie die Animation arbeitet nicht erspart.

Windows 10 kann (teilweise) mit Ansi-Escapesequenzen umgehen. Dies setzt voraus, das dies auf dem Zielsystem aktiviert ist! (ForceV2)

Mit Escapesequenzen kann man auch den Cursor platzieren. bevor ein Zeichen ausgegeben wird. http://ascii-table.com/ansi-escape-sequences.php

@echo off
  rem nur der !!!DWord!!!-Wert ForceV2=0 deaktiviert, alles andere erlaubt Escapesequenzen (ansonsten scheinen ANSISequenzen inzwischen by default unterstützt zu werden)
reg query "HKCU\Console" /v "ForceV2"|find "REG_DWORD    0x0">nul && (
    echo Sorry ANSI-Escapesequenzen sind fur diese Console deaktiviert.
    timeout 5 >nul
    exit /b
)
  rem Escapezeichen erzeugen...
for /f "delims=;" %%. in ('"prompt $E; & for %%. in (nul) do rem"') do ( set "ESC=%%.")
  rem cursor ausblenden
echo %ESC%[?25l
  rem von  rechts unten  nach links  oben   zeichnen
  rem cls  ist  nicht  nötig,  da  ich  den cursor  einfach dahin  setze, wo ich  ihn haben  will
for /l %%a in (20,-1,1) do (
      rem  zeichne ein X  an  Position %%a,%%a
    echo %ESC%[%%a;%%aHX
      rem  wider unsere bremsschleife
    for /l %%. in (1,1,500000) do rem
)
  rem man kann auch mehrere Positionierungen in einer Ausgabeanweisung platzieren...
  rem ...das  ist wesentlich schneller  als  mit einzelnen Aufrufen von echo
echo %ESC%[10;25HEs ist vollbracht%ESC%[15;5H...blubb
pause >nul

Jetzt noch eine synchrone Bewegung zweier Texte. Auch hier wird auf das Löschen des gesamten Bildes verzichtet. Stattdessen wird der alte Text mit eine geichlangen Anzahl von Leerzeichen überschrieben.

@echo off
chcp 65001 >nul
setlocal enableDelayedExpansion


  rem nur der !!!DWord!!!-Wert ForceV2=0 deaktiviert, alles andere erlaubt Escapesequenzen (ansonsten scheinen ANSISequenzen inzwischen by default unterstützt zu werden)
reg query "HKCU\Console" /v "ForceV2"|find "REG_DWORD    0x0">nul && (
    echo Sorry ANSI-Escapesequenzen sind fur diese Console deaktiviert.
    timeout 5 >nul
    exit /b
)
for /f "delims=;" %%. in ('"prompt $E; & for %%. in (nul) do rem"') do ( set "ESC=%%.")


set "CursorOff=%ESC%[?25l"
set "Block1=Hallo Welt"
set "Empty1=          " & rem Muss genauso lang sein wie der "Block"
set "Block2=Hallo Mond"
set "Empty2=          " & rem Muss genauso lang sein wie der "Block"


echo %CursorOff%%ESC%[38;5;222m
set "oldPos1=5;1"
set "oldPos2=1;1"
for /l %%y in (1,1,20) do (
    set /a "_y=%%y*2"
      rem zwei verschidene  Bewegungen gleichzeitig...
    echo %ESC%[!oldPos2!H%Empty1%%ESC%[%%y;%%yH%Block1%%ESC%[!oldPos1!H%Empty2%%ESC%[0;!_y!H%Block2%
    set "oldPos1=0;!_y!"
    set "oldPos2=%%y;%%y"
      rem  Bremsschleife , damit man überhaupt die Bewegung Wahrnimmt
    for /l %%. in (0,1,200000) do rem
)
echo %ESC%[20;0H
pause

Wie bereits erwähnt ist nicht sichergestellt, dass die Console so eingestellt ist, dass sie Escapesequenzen unterstützt.

Letztlich bleibt das Ganze eine Spielerei.

Wenn wenn Du wirklich mit Animationen arbeiten willst Stecke keine Energie in Batch. Andere Sprachen wie HTML/CSS/Javascript bieten da wesentlich umfangreichere Möglichkeiten.

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren
Butzibu 
Fragesteller
 06.10.2020, 07:11

Okay vielen vielen Dank für deine Antwort, mir ist bewusst das Bauch nicht dafür da ist es macht mir dennoch damit Spaß in Bauch rumzuwerkeln :D

1