BASH Shell 交互会话 - 如何修复 ASCII 艺术动画输出?

4
我正在尝试为以下ASCII艺术添加动画效果。(目前有两个文件,以后可能会添加更多文件以实现更精细的动画效果。)
$ cat ~/aks1.txt
        \            RTX            /
         \                         /
          \       WAZUH LAB       /
           ]                     [    ,'|
           ]                     [   /  |
           ]___               ___[ ,'   |
           ]  ]\             /[  [ |:   |
           ]  ] \           / [  [ |:   |
           ]  ]  ]         [  [  [ |:   |
           ]  ]  ]__     __[  [  [ |:   |
           ]  ]  ] ]\ _ /[ [  [  [ |:   |
           ]  ]  ] ] (A) [ [  [  [ :===='
           ]  ]  ]_].nRn.[_[  [  [
           ]  ]  ]  HHUHH. [  [  [
           ]  ] /   `HN("N  \ [  [
           ]__]/     HNH  "  \[__[
           ]         NNN         [
           ]       / N/" \       [
           ]      /  N H  \      [
          /          N            \
         /           q,            \
        /                           \

$ cat ~/aks2.txt
        \            RTX            /
         \                         /
          \       WAZUH LAB       /
           ]                     [    ,'|
           ]                     [   /  |
           ]___               ___[ ,'   |
           ]  ]\             /[  [ |:   |
           ]  ] \           / [  [ |:   |
           ]  ]  ]         [  [  [ |:   |
           ]  ]  ]__     __[  [  [ |:   |
           ]  ]  ] ]\ _ /[ [  [  [ |:   |
           ]  ]  ] ] (A) [ [  [  [ :===='
           ]  ]  ]_].nRn.[_[  [  [
           ]  ]  ] .HHUHH  [  [  [
           ]  ] /  #")NH`   \ [  [
           ]__]/   " HNH     \[__[
           ]         NNN         [
           ]       / "\N         [
           ]         H N  \      [
          /      /     N   \      \
         /      /     ,p    \      \
        /                           \

这是我的代码:

if [[ -t 0 ]]; then
    old_tty=$(stty --save)
    stty raw -echo min 0
fi
while IFS= read -r REPLY; [[ -z "$REPLY" ]]; do
    clear
    cat ~/aks1.txt
    usleep 500000
    clear
    cat ~/aks2.txt
    ((c++)) && usleep 500000
done
if [[ -t 0 ]]; then
    stty "$old_tty"
fi
echo

优点:

  1. 简单的方法/解决方案
  2. 不需要复杂的变量替换(在tput cup屏幕位置)
  3. 在任何键被按下之前都能很好地工作,因此不需要为动画运行时间硬编码计数器变量。
  4. 动画已经开始运行(动画正在进行中,但输出效果并不完美)。

缺点:

  1. 动画输出效果混乱/糟糕。

如何修复输出效果?

4个回答

3
当您切换到原始模式时,换行符(\n)不再将光标移回第一列,它们仅将其下移一行,您需要打印回车符( \r )以重置列。使用sed禁用在每行末尾添加回车符即可实现此功能:
sed 's/$/\r/g' ~/aks1.txt

或者,您可以跳过切换到原始模式并将终端保留在其默认状态。要防止read 命令阻塞,请使用read -t 0 添加0秒超时。如果用户没有按键,它将立即返回,而不是等待他们按下任何键。

until read -t 0; do
    ...
done

1
这个版本在我的Debian/Xterm上运行良好:

function animate {
    local aks1="$(cat ~/aks1.txt)"
    local aks2="$(cat ~/aks2.txt)"
    local c
    for (( c=0; c < 5; c++ )); do
        read -rsn1 -t .001 && return
        clear; printf "%s\n" "$aks1"; sleep .5
        clear; printf "%s\n" "$aks2"; sleep .5
    done
    echo
}
setterm -cursor off
animate
setterm -cursor on

0

这是“我的主题”,试一下。

#!/bin/bash

sprites=( "$(cat aks1.txt)" "$(cat aks2.txt)" )

XY () { printf "\e[$2;${1}H$3"; }
animation () {
    for sprite in "${sprites[@]}"; {
        sleep 0.5
        XY 1 1 "$sprite"
    }    
    animation
}

animation

同时,查看thisthis项目,以获取更多有关动画的创意。


-1

使用alias的方式,动态显示ASCII ART,并在按下任意键时立即停止:

alias animate_arun='until read -t 0; do clear && cat ~/aks1.txt && sleep .5 && clear && cat ~/aks2.txt && sleep .5; done; echo;'

将上述别名放入~/.bash_profile中,并调用别名animate_arun,对于任何新的交互式登录shell都行得通。
参考文章:使用tput cup动画ASCII艺术,直到用户按下一个键

Arun,你的回答似乎解决了核心问题,即每行末尾缺少\r,但这个问题早在@JohnKugelman之前就已经得到了回答。为什么不接受他的答案呢?创建别名的其他参考资料与您最初的问题似乎无关。 - rtx13
@rtx13 我原来的帖子使用了别名,所以我也包含了这个。我已经接受了他的回复并点赞了。"until" 没有起作用。 - AKS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接