Печать многострочной ASCII-анимации в консоли

Я хотел бы сделать небольшую анимацию в консольном приложении, и для этого я создал ASCII-арт:

                       ,.:b-'::'     ,`::-/,._
                  _.\\,,-/` /| |     ,' .`| ,_: ,.
               ` -_,'[ ._-|/,'Y      ` `  /  -/,-.:`.
             ,'/[(o _.. _,".`':| ___  ::/|.`][,'/,,/,'`.
           `:-\-. `','\`,-' [:_,.....'__ ^..,|-.'-  ,,\ :.
         ,'-\-.` _ `[.-  --'             '-..`'-[''\ .L-",`.
       ,L< ':],, ,` ,-                       '- , .''Y"-'.-'`
     _'_,::''/-]._,'        _ ..     .._         `.`]'. -,-:,^.
    _'/,[``.-'/'-       _ :].-''`'''''--.[         -.  .|/:L:| \
    '[' ]>] ' /'       _,'                `-  .      ``\'` ,u[<L'
   /,`.  [-' /        ,`                    ,. `.     `.`,,``..| |
  P.P.`[o'),      ,''`__-.                 ,' /'\,      .\'( ; .:]
 /`/  `  .'/XXX  `,'    . -.             ,' ,'   `.       \.>  :,`
 | \.u[/\'|X   X/\'      'v ^,         ,' ,'       \     \ `^/:.-, |
.:-<.. [||/ XXX '/         `\ `\     ,' /'         .\     || \]::`.'
| |::>,-b|     ||            ^. '---' ,'           Y|     || [./.'/\
| /_,[| ||     ||              | ,.  /             ||     || |> --||
Y=]L__`=[|     ||              | ,-  '             ||     | ::_,==:
| |i .| |'.     \            /' ,..._ `'           ||     || /L. ,
|_]L,.'-] |     [\         ,- ,'     ,' '.         ||     'P..L, / |
 v...-L\ \\     `/.      ,' ,'         `. -_      /      /|'Y\-.`::'
 \  -:,'\..,     \`\  _,' /'             ^,      /,        .[-` ,'
  )_  '   '.\     `[`,  /'                 `.'\,''       /`..:-  |
   <`...,`./ `      `[.=                    `= /        ,_/-/.` ''
    \`[,-'.v'\`.      ".`._               _.:'         '-' '.>/ '
      [,_,L!`, [`       '  `-...______.,-'           v /'''|]:.'
      ``\ //'. .`.`.         ' --- -- ''          ',-|' '  b''
       `.Yv-]-, ',-.'-                          ,-'''\ [,.-,'
         `['./,L|'`.],..  .__           _    ,.',. .[ ]'v']
           `v-/|  <." ..`\-.. ::_   |: ,.-\\',.\'-  ' '','
             `.:`[/   / ' > .:',.||::_|/--'. ``,\ '/: '
                -',:.\`[| .'/,[/ L',]   ^  /``,] ``-`
                    -\|, -,: |`-|||/ |``.,..\`_,-'
                       ''--.' ==='|::::\'-''

(Да, это рулетка)

Я создал такие же ASCII-арты с мячом в разных положениях (как и крест на рулетке).

Проблема у меня, как мне кажется, довольно хитрая: хотелось бы вывести рулетку на консоль где-то 4 раза в секунду (может и больше, точно не знаю) в одно и то же место, чтобы выглядело как гифка. У меня нет проблем с загрузкой файлов и преобразованием их в строку, но я не нашел способа перезаписать в том же месте (\r не будет работать для многострочного текста).

Было бы здорово, если бы я мог сделать это без использования какой-либо библиотеки вроде curses (хотя я большой поклонник ncurses в Python!).


person Laurent Meyer    schedule 01.11.2014    source источник
comment
Итак, я сделал черновик, так что если вы хотите взглянуть: github.com/lolobosse/CurseRoulette (работает на OSX и Linux, на Windows не проверял)   -  person Laurent Meyer    schedule 12.11.2014


Ответы (2)


Я думаю, что проклятия или что-то в этом роде будут необходимы.

Насколько я помню (проклятия были давным-давно), у curses было два аспекта - разные терминалы и эффективность на медленных терминальных соединениях. Вы столкнетесь с обеими проблемами, в зависимости от того, как подключены терминалы и как часто вы в конечном итоге захотите перекрасить экран.

Curses проанализировал желаемый результат, чтобы определить наиболее эффективный способ рисования — должен ли он позиционировать курсор три раза и рисовать объекты по отдельности или выводить несколько строк и рисовать их только один раз? И какие последовательности символов были необходимы для позиционирования курсора?

Удачи в этом, несмотря ни на что.

person arcy    schedule 01.11.2014
comment
Хорошо, спасибо, это был не тот ответ, которого я ожидал, но если это единственный способ... И может ли он работать с кодами ascii? - person Laurent Meyer; 01.11.2014
comment
Не уверен, что вы имеете в виду - вы имеете в виду, можете ли вы закодировать строку как ASCII? Вы можете вывести строку в поток как ASCII, подробности смотрите в кодировке потоков. Вы не можете хранить внутреннюю строку как ASCII в Java, но тогда я не знаю ни одной ситуации, в которой вам это нужно. - person arcy; 01.11.2014
comment
Нет этого очень старого кода с экранированными символами для перемещения курсора, но это не проблема, я использую lanterna (curses), и это работает. Держу вас в курсе :) - person Laurent Meyer; 01.11.2014

Чтобы у вас было с чего начать, этот код печатает внешний толстый круг, внутренний тонкий круг и крестик в центре вашей фигуры со случайной пунктуацией ASCII. символы:

                            *$%,'"++-(                            
                      (,%,(#)&"("%#!'/%*.*)&                      
                %%%&"&'$#'*#/,)$-,/,$/'..*+/*%--#)                
              &.#'''&.(,%)""$'-/.&.".(+)$##,)%.*))'$              
            )-.+,#*'*./&+)"$#,,$+')*%*.")"$(%-)&-$/(-&            
          $(%#/)'*-!%)."#'              *%..&**,*.!%.+/'          
        ('&!"%!-$/#,*/                      !.-&.)+!#!."/!        
      *+#/!)&$'+-$                              &$//)$*/.#(*      
    .$-+&'+).'!%          .'/+,-&#&!%,,%          ($$'),-,&*!'    
    '*"#!/(.&(        /"$%!'%%'+$+$/&-/!(+/!        %".%).%&//    
    $+''.)/&.#      **""**              )&/(*.      /,-%-*(,'&    
  +&*//##+.&      ,'&*&$                  ,+$$)-      $)%$#))!..  
  /'"#!$%.'&      +#/)  (&              -.  ".--      &(/+'#,)%*  
  '$.#-,//      $&'!      &+          "#      !/,'      ,-+&/$#,  
%'%+)&,,$'      ".$(        .!      (-        +$'"      /(&'.*,(&*
!#/%"/.-+)      $+,.          "&  .-          +($#      )'.#!&"(./
%&$"%%/).$      -%"#            &%            $%'$      ,#"$,(-#$.
!$"$#*(#*)      +*&#          &*  $#          ###&      *'$/#,.)(.
"$(*-'.*!(      $""/        ),      %,        $/&(      %*&$$)'-,&
  /,#-$-**      +**-      %$          $-      (.%,      %$(%*)+'  
  #*,**,&(%*      /"*"  &/              #-  '&##      ,./+'$&,&(  
  &!!&*--*+%      /#-.)&                  !"#/%-      ',".&-#!+*  
    '$'"!"*"$"      !.)(,"              .,&,.)      -+)$//$/*+    
    '/#&"+%%-"        ',+*,&&)/!**-$,$/(*!+'        .!#-$'..$(    
    -#&%!-%),"--          --+#-,$!#-#$/+          +/'#*#*#*+./    
      ()$"**!$//'/                              +"+(+/,)%)*"      
        "+#'.$'-!*&"&$                      )/!..,(-&.*/#(        
          )-#%/#!!!.$..#)*              $'/%-/+#+)%.-*'.          
            /'#-+.%#$),)$/**%%&++%#,)"(+/,&((-($*'"+'*            
              *!**!+,#&-&-%"&&..,*/(&'!/&##-/&*+%%,"              
                /."($&$'!!))/&$#%))"/*&&)!"'$%/,+-                
                      (+$.-)%#*#!$.)*###/*&(                      
                            #"*'"*#+(!                            

Java 8:

int r = 16;
IntStream.rangeClosed(-r, r)
        .map(Math::abs)
        .peek(i -> IntStream.rangeClosed(-r, r)
                .map(Math::abs)
                // printing a kind of thick circle,
                // thin circle and cross in the center
                .mapToObj(j -> i == j && i < r/3 || // cross
                        // outer thick circle
                        Math.abs(i*i + j*j - r*r/1.3) < 4*r ||
                        // inner thin circle
                        Math.abs(i*i + j*j - r*r/4) < r
                        // cast to String
                        ? ""
                        // two random ASCII punctuation
                        // symbols: !"#$%&'()*+,-./
                        + (char) (33 + Math.random() * 15)
                        + (char) (33 + Math.random() * 15)
                        // two whitespaces
                        : "  ")
                .forEach(System.out::print))
        .forEach(i -> System.out.println());

См. также: Распечатайте круг и оси ASCII

person Community    schedule 26.03.2021