BASIC (ベーシック) であそぼう 2
〜 十進 BASIC で Matrix のアレ 〜
2022-03-21 作成 福島
TOP > asob > decbasic-anime
[ TIPS | TOYS | OTAKU | LINK | MOVIE | CGI | AvTitle | ConfuTerm | HIST | AnSt | Asob | Shell ]

アニメーションとは

知っている人も多いと思いますが、少しずつ異なる複数枚の絵を定期的に入れ替えると絵が動いて見えます。
それがアニメーションです。よくパラパラマンガに例えられます。

これと同じように、コンピュータでもいくつかの絵を用意し、定期的に切り替えることによってアニメーションを作ることが出来ます。
ビデオゲームも、同じ原理で作られます。

絵を用意するのは大変なうえ、ここではコンピュータの使い方を説明するので、「文字を使った疑似画*1」を切り替えることによって、アニメーションを実現します。
この疑似画を、もっと細かくしたのが「CG アニメーション」と呼ばれるものになります。
*1アスキーアートとも呼ばれます。

映画 Matrix のオープニングで有名な、文字が上から流れる画面を真似てみます。
かなりカクカクとした表示ですが、基本の学習にはちょうど良いでしょう。
ぜひ、滑らかに表示される方法を考えてみてください。


0. 事前準備

0-1. この章では、十進 BASIC を使います。
インストールがまだなら、ここ (ラズパイ400)ここ (CentOS) の gtk2 版か、
ここ (Windows10) を参考にしてインストールしておいてください。
0-2. この章では、別のテキストエディタを使いません。
十進 BASIC には専用のエディタ画面があるので、これを使います。
0-3. 未経験者向けの情報を省いています。
プログラミング未経験の方は、予めこちら (BASIC であそぼう 1) を学習しておくことを推奨します。


1. 文字のアニメーションプログラム

' ' は空白文字 (スペースキーで入力) です。TAB 文字とは異なるので注意してください。
タイミング同期用副プログラム BogusTick はこちらを使用しています。
DIM page$(17,9)
!   # 1
LET page$(1,1) = "                 "
LET page$(1,2) = "                 "
LET page$(1,3) = "                 "
LET page$(1,4) = "                 "
LET page$(1,5) = "                 "
LET page$(1,6) = "                 "
LET page$(1,7) = "                 "
LET page$(1,8) = "                 "
LET page$(1,9) = "                 "

!   # 2
LET page$(2,1) = "              z  "
LET page$(2,2) = "                 "
LET page$(2,3) = "                 "
LET page$(2,4) = "                 "
LET page$(2,5) = "                 "
LET page$(2,6) = "                 "
LET page$(2,7) = "                 "
LET page$(2,8) = "                 "
LET page$(2,9) = "                 "

!   # 3
LET page$(3,1) = "    Z         i  "
LET page$(3,2) = "              z  "
LET page$(3,3) = "                 "
LET page$(3,4) = "                 "
LET page$(3,5) = "                 "
LET page$(3,6) = "                 "
LET page$(3,7) = "                 "
LET page$(3,8) = "                 "
LET page$(3,9) = "                 "

!   # 4
LET page$(4,1) = "G  _[   mS  ( = 3"
LET page$(4,2) = "    Z         i  "
LET page$(4,3) = "              z  "
LET page$(4,4) = "                 "
LET page$(4,5) = "                 "
LET page$(4,6) = "                 "
LET page$(4,7) = "                 "
LET page$(4,8) = "                 "
LET page$(4,9) = "                 "

!   # 5
LET page$(5,1) = ":  pGy  YQ  y ] H"
LET page$(5,2) = "G  _[   mS  ( = 3"
LET page$(5,3) = "    Z         i  "
LET page$(5,4) = "              z  "
LET page$(5,5) = "                 "
LET page$(5,6) = "                 "
LET page$(5,7) = "                 "
LET page$(5,8) = "                 "
LET page$(5,9) = "                 "

!   # 6
LET page$(6,1) = "B VgU8S(E* V/ eu@"
LET page$(6,2) = ":  pGy  YQ  y ] H"
LET page$(6,3) = "G  _[   mS  ( = 3"
LET page$(6,4) = "    Z         i  "
LET page$(6,5) = "              z  "
LET page$(6,6) = "                 "
LET page$(6,7) = "                 "
LET page$(6,8) = "                 "
LET page$(6,9) = "                 "

!   # 7
LET page$(7,1) = "b 2E;XsLT9 xP M!w"
LET page$(7,2) = "B VgU8S(E* V/ eu@"
LET page$(7,3) = ":  pGy  YQ  y ] H"
LET page$(7,4) = "G  _[   mS  ( = 3"
LET page$(7,5) = "    Z         i  "
LET page$(7,6) = "              z  "
LET page$(7,7) = "                 "
LET page$(7,8) = "                 "
LET page$(7,9) = "                 "

!   # 8
LET page$(8,1) = "PFRpx(Y_%| 742Oy="
LET page$(8,2) = "b 2E;XsLT9 xP M!w"
LET page$(8,3) = "B VgU8S(E* V/ eu@"
LET page$(8,4) = ":  pGy  YQ  y ] H"
LET page$(8,5) = "G  _[   mS  ( = 3"
LET page$(8,6) = "    Z         i  "
LET page$(8,7) = "              z  "
LET page$(8,8) = "                 "
LET page$(8,9) = "                 "

!   # 9
LET page$(9,1) = "WrBj*B_Q5;+87u5:p"
LET page$(9,2) = "PFRpx(Y_%| 742Oy="
LET page$(9,3) = "b 2E;XsLT9 xP M!w"
LET page$(9,4) = "B VgU8S(E* V/ eu@"
LET page$(9,5) = ":  pGy  YQ  y ] H"
LET page$(9,6) = "G  _[   mS  ( = 3"
LET page$(9,7) = "    Z         i  "
LET page$(9,8) = "              z  "
LET page$(9,9) = "                 "

!   # 10
LET page$(10,1) = "n_k(z0q@uxV:tY|7p"
LET page$(10,2) = "WrBj*B_Q5;+87u5:p"
LET page$(10,3) = "PFRpx(Y_%| 742Oy="
LET page$(10,4) = "b 2E;XsLT9 xP M!w"
LET page$(10,5) = "B VgU8S(E* V/ eu@"
LET page$(10,6) = ":  pGy  YQ  y ] H"
LET page$(10,7) = "G  _[   mS  ( = 3"
LET page$(10,8) = "    Z         i  "
LET page$(10,9) = "              z  "

!   # 11
LET page$(11,1) = "=DbX=U5sUK1dO6I'P"
LET page$(11,2) = "n_k(z0q@uxV:tY|7p"
LET page$(11,3) = "WrBj*B_Q5;+87u5:p"
LET page$(11,4) = "PFRpx(Y_%| 742Oy="
LET page$(11,5) = "b 2E;XsLT9 xP M!w"
LET page$(11,6) = "B VgU8S(E* V/ eu@"
LET page$(11,7) = ":  pGy  YQ  y ] H"
LET page$(11,8) = "G  _[   mS  ( = 3"
LET page$(11,9) = "    Z         i  "

!   # 12
LET page$(12,1) = "!F;p6vbv<XTRiOKNi"
LET page$(12,2) = "=DbX=U5sUK1dO6I'P"
LET page$(12,3) = "n_k(z0q@uxV:tY|7p"
LET page$(12,4) = "WrBj*B_Q5;+87u5:p"
LET page$(12,5) = "PFRpx(Y_%| 742Oy="
LET page$(12,6) = "b 2E;XsLT9 xP M!w"
LET page$(12,7) = "B VgU8S(E* V/ eu@"
LET page$(12,8) = ":  pGy  YQ  y ] H"
LET page$(12,9) = "G  _[   mS  ( = 3"

!   # 13
LET page$(13,1) = "Hsa3_51Iqq]w<)+8["
LET page$(13,2) = "!F;p6vbv<XTRiOKNi"
LET page$(13,3) = "=DbX=U5sUK1dO6I'P"
LET page$(13,4) = "n_k(z0q@uxV:tY|7p"
LET page$(13,5) = "WrBj*B_Q5;+87u5:p"
LET page$(13,6) = "PFRpx(Y_%| 742Oy="
LET page$(13,7) = "b 2E;XsLT9 xP M!w"
LET page$(13,8) = "B VgU8S(E* V/ eu@"
LET page$(13,9) = ":  pGy  YQ  y ] H"

!   # 14
LET page$(14,1) = "ab:D3myzTJ|EDZx*Z"
LET page$(14,2) = "Hsa3_51Iqq]w<)+8["
LET page$(14,3) = "!F;p6vbv<XTRiOKNi"
LET page$(14,4) = "=DbX=U5sUK1dO6I'P"
LET page$(14,5) = "n_k(z0q@uxV:tY|7p"
LET page$(14,6) = "WrBj*B_Q5;+87u5:p"
LET page$(14,7) = "PFRpx(Y_%| 742Oy="
LET page$(14,8) = "b 2E;XsLT9 xP M!w"
LET page$(14,9) = "B VgU8S(E* V/ eu@"

!   # 15
LET page$(15,1) = ")0k>JS$jjvTl8j)gC"
LET page$(15,2) = "ab:D3myzTJ|EDZx*Z"
LET page$(15,3) = "Hsa3_51Iqq]w<)+8["
LET page$(15,4) = "!F;p6vbv<XTRiOKNi"
LET page$(15,5) = "=DbX=U5sUK1dO6I'P"
LET page$(15,6) = "n_k(z0q@uxV:tY|7p"
LET page$(15,7) = "WrBj*B_Q5;+87u5:p"
LET page$(15,8) = "PFRpx(Y_%| 742Oy="
LET page$(15,9) = "b 2E;XsLT9 xP M!w"

!   # 16
LET page$(16,1) = "F*wz0eU;1;_1FgQ*M"
LET page$(16,2) = ")0k>JS$jjvTl8j)gC"
LET page$(16,3) = "ab:D3myzTJ|EDZx*Z"
LET page$(16,4) = "Hsa3_51Iqq]w<)+8["
LET page$(16,5) = "!F;p6vbv<XTRiOKNi"
LET page$(16,6) = "=DbX=U5sUK1dO6I'P"
LET page$(16,7) = "n_k(z0q@uxV:tY|7p"
LET page$(16,8) = "WrBj*B_Q5;+87u5:p"
LET page$(16,9) = "PFRpx(Y_%| 742Oy="

!   # 17
LET page$(17,1) = "vG+m/[I*od'_6C;T'"
LET page$(17,2) = "F*wz0eU;1;_1FgQ*M"
LET page$(17,3) = ")0k>JS$jjvTl8j)gC"
LET page$(17,4) = "ab:D3myzTJ|EDZx*Z"
LET page$(17,5) = "Hsa3_51Iqq]w<)+8["
LET page$(17,6) = "!F;p6vbv<XTRiOKNi"
LET page$(17,7) = "=DbX=U5sUK1dO6I'P"
LET page$(17,8) = "n_k(z0q@uxV:tY|7p"
LET page$(17,9) = "WrBj*B_Q5;+87u5:p"

! 副プログラムの使用予告
DECLARE EXTERNAL SUB PageDisplay
DECLARE EXTERNAL SUB BogusTick

! グラフィック画面の準備
SET WINDOW 0,39,19,0
SET COLOR MIX(0) 0,0,0      ! 背景色(色番号0) に RGB(0.0, 0.0, 0.0)=黒色 を割り当てる。
SET COLOR MIX(3) 0,0.5,0    ! 描画色(色番号3) に RGB(0.0, 0.5, 0.0)=暗い緑色 を割り当てる。

LET BogusTick_before = -1   ! BogusTick() 使用の準備 (前回時刻の初期化)
LET pageMax = UBOUND(page$,1) ! 表示ページ数
LET pageCnt = 0   ! 表示ページのインデックス
DO
   CALL BogusTick(BogusTick_before, 2)    ! WAIT を入れる (2fps)

   ! [Esc] キーで終了する。キーの ON/OFF を見ているので fps が少ない時は反応が鈍い。
   IF GetKeyState(27) < 0 THEN EXIT DO

   CALL PageDisplay(page$, 1 + pageCnt)   ! 画面をひとつ描画する
   LET pageCnt = MOD(pageCnt + 1, pageMax)     ! 次の画面へ進める。
LOOP

END  ! メインプログラムの終了


! 画面を描画する副プログラム EXTERNAL SUB PageDisplay(page$(,),idx) SET DRAW MODE Hidden ! 描画中に画面更新しないモードにする。*2 CLEAR ! グラフィック画面を背景色で塗りつぶす。 SET COLOR 3 ! 描画色として色番号 3(緑色) を指定する。 FOR y = 1 TO UBOUND(page$,2) ! 指定ページの行数分繰り返す。 LET line$ = page$(idx,y) ! 1 行を取得する。 FOR x = 1 TO LEN(line$) ! 1 行分繰り返す。 LET c$ = mid$(line$, x, 1) ! 1 文字を取り出す。 PLOT TEXT ,AT x,y:c$ ! 取り出した 1 文字を描画する。 NEXT x NEXT y SET DRAW MODE Explicit ! 画面更新モードを元に戻す。*2 END SUB
! BogusTick version 1.0 written by fuku@rouge.gr.jp EXTERNAL SUB BogusTick(before, fps) IF before >= 0 AND fps > 0 THEN LET current = TIME IF before > current THEN LET before = before - 24 * 3600 LET this_wait = 1 / fps - (current - before) IF this_wait > 0 THEN WAIT DELAY this_wait END IF LET before = TIME END SUB
*2 一時的に描画を画面に反映させないことで、以下 2 つの効果を狙っています。
  · 意図しない画面の明滅を抑止する。(画面更新と描画のタイミングが重なると、画面表示がおかしくなる瞬間が発生する)
  · 描画処理を速くする。(というか、遅くしない)
この章は、ここで終了です。