정현파 ASCII 아트 애니메이션 텍스트


11

컴퓨터가 i3, i5 및 i7 대신 x86이라고 불리는 컴퓨터의 기능을 보여주는 오래된 데모는 다소 누락되었습니다. 제가 386에서 처음으로 본 것은 미래의 승무원언리얼 데모 였습니다 . 25 주년을 축하합니다. 에서 분 0시 43분 데모의 첫 번째 부분은 시작하고 우리는 사인 곡선 경로를 따라 스크롤 텍스트를 참조하십시오. ASCII 아트에서 그 효과를 모방 해 봅시다!

도전

이 경로가 주어지면 :

***                                ***
   ***                          ***
      **                      **
        *                    *
         *                  *
         *                  *
          *                *
           **            **
             ***      ***
                ******

입력 텍스트는 다음과 같이 해당 경로를 따라 텍스트를 그립니다.

Thi                                Golf! 
   s i                          de       Yay
      s                       Co            !
        P                     
         r                  d
         o                  n
          g                a
           ra            s 
             mmi      zle
                ng Puz

공백은 경로에서 문자로 계산되며 텍스트가 샘플보다 길면 경로 자체가 반복됩니다.

애니메이션 부분

텍스트를 그린 후에는 약 10fps의 애니메이션을 만들기 위해 100ms 동안 기다렸다가 경로의 다음 위치에서 시작하여 텍스트를 다시 그립니다. 따라서 frame의 경우 텍스트가 항상 캔버스 왼쪽에 정렬 된 경로의 다음 위치에서 #n계산 n modulo 40하고 그리기를 시작하십시오.

***                                ***
|  ***                          ***  |
|     **                      **     |
|       *                    *       |
|        *                  *        |
|        *                  *        |
|         *                *         |
|          **            **          |
|            ***      ***            |
|               ******               |
Position 0                 Position 39

따라서 프레임 10의 경우 다음을 갖습니다.

                           and Co
                        es       de 
                      zl            Go
                     z                l
                    u                  f
T                   P                  !
 h                                       
  is             ng                       Ya
     is       mmi                           y!
        Progra

메모

  • 입력은 애니메이션을 적용 할 텍스트 가 포함 된 단일 string(또는 char배열 등)이며 항상 1 자 이상이어야합니다.
  • 애니메이션을 적용 할 수있는 유효한 문자는 인쇄 가능한 ASCII 세트의 문자입니다 .
  • 따라야 할 경로는 정확하게 주어진 것입니다.
  • 텍스트는 항상 캔버스의 왼쪽에 맞춰 지므로 텍스트 변위없이 깃발처럼 흔들리는 텍스트가 효과가됩니다. 그리고 캔버스라는 말은 화면 또는 텍스트를 표시하는 데 사용할 것을 의미 합니다 . ;-)
  • 문자 / 픽셀이 두 프레임에서 동일하지 않으면 프레임은 이전 프레임에서 문자 / 픽셀을 제거해야합니다.
  • 애니메이션 속도는 장치가 매끄 럽거나 빠르게 실행되는 한 중요하지 않습니다 (최소 5fps로 설정할 수 있지만 필수 사항은 아닙니다). 속도를 조정하여 유동적으로 만들고 대기 시간이 정확히 같지 않아도 걱정하지 마십시오.
  • 애니메이션은 끝없이 반복됩니다.

이것은 이므로 텍스트를 애니메이션 할 수있는 가장 짧은 프로그램이나 기능이 승리 할 수 ​​있습니다!



1
40 개가 아닌 38 개 열을 셀 수 있습니다.
Arnauld

1
@Arnauld는 열이 아닌 경로의 위치가 무엇인지 계산하기 때문입니다.
Charlie

아 알 겠어요 말이된다.
Arnauld

출력으로 알았지? 입력을 사인파 형태로 표시하고 끝없이 반복됩니다. 물론 비디오는 그래픽 교환 형식이므로 실제로는 더 빠릅니다.
R. Kap

답변:


9

HTML + ES6, 241 (244) 237 바이트

고장:

  • HTML : 16 바이트
  • JS 함수 : 221 바이트

let f =

s=>setInterval(_=>o.innerHTML=[...s].map((c,i)=>([j,y]=[...Array(40)].map((_,k)=>[j=k%20,y,y+=77732>>j&1?k<20||-1:0],y=0)[(i+p)%40],a[y]=a[y]||[...s].fill` `)[x]=(x+=j!=9,c),x=0,a=[],p++)&&a.map(r=>r.join``).join`
`,p=30)

f("This is Programming Puzzles and Code Golf! Yay!")
<pre id=o></pre>

어떻게?

경로 구축

다음 코드는 경로를 빌드합니다.

[...Array(40)].map((_, k) =>
  [
    j = k % 20,
    y,
    y += 77732 >> j & 1 ? k < 20 || -1 : 0
  ],
  y = 0
)

이 배열의 배열 제공 j는 위치 모듈로 20을, Y는 은이 위치에서 Y 좌표이며, Z는 (단지 몇 바이트를 구하기 위해서 계산 될 일) 이상 사용되지 않는다.[j, y, z]

경로는 대칭이므로 첫 20 개의 위치 만 인코딩하면됩니다. 우리는 각 1비트가 y 를 업데이트해야 한다는 이진 숫자를 사용하여이를 수행합니다 (상반기에는 +1, 후반에는 -1).

001
   001
      01
        1
         1
         1
          1
           01
             001
                000

첫 번째 위치가 최하위 비트에 매핑되면 다음이 제공됩니다.

00010010111110100100 as binary = 77732 as decimal

이 이진수 자체도 대칭이기 때문에 하반기에 같은 순서로 읽을 수 있습니다.

따라서 공식 :

y += (77732 >> j) & 1 ? (k < 20 ? 1 : -1) : 0

다음과 같이 쓸 수도 있습니다 :

y += (77732 >> j) & 1 ? k < 20 || -1 : 0

여기서 k 는 위치이고 j 는 위치 모듈러스 20입니다.

x를 업데이트하는 것이 훨씬 쉽습니다. 위치 모듈로 20을 9와 비교하여 감지 할 수있는 특별한 경우가 하나 있습니다.

텍스트 그리기

다음 코드에서 위에서 설명한 경로 작성 코드는 path가독성 을 위해 변수 로 대체되었습니다 .

s => setInterval(                       // set a periodic timer:
  _ =>                                  //   with an anonymous callback
    o.innerHTML =                       //   which updates the content of 'o'
      [...s].map((c, i) => (            //   for each character c of the string s
          [j, y] = path[(i + p) % 40],  //     retrieve j and y from the path
          a[y] = a[y] || [...s].fill` ` //     initialize a[y] if it's undefined
        )[x] = (x += j! = 9, c),        //     update a[y][x] / update x
        x = 0,                          //     initialize x
        a = [],                         //     initialize a[]
        p++                             //     increment the phase
      ) &&                              //   end of map()
      a.map(r => r.join``).join`\n`,    //   join everything together
  p = 30                                //   initial phase = interval period = 30
)                                       // end of timer definition

이것은 훌륭하고 요청 된 경로에 매우 가깝지만 경로는 내가 그린 경로가 아닙니다. *세로로 두 개가 포함 된 두 개의 열 은 정렬되지 않고 (같은 높이로) 또 다른 작은 nitpick입니다. 그러나 코드에서 웨이브 효과를 만드는 방법을 여전히 모른다고 말해야합니다 (무엇을 y+=155464합니까?). 축하합니다!
Charlie

@CarlosAlejo 이제 경로를 수정해야한다고 생각합니다. 다시 확인해 주시겠습니까? 사용 된 방법에 대한 설명을 추가하겠습니다.
Arnauld

1
경로를 확인하고 설명해 주셔서 대단히 감사합니다!
Charlie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.