【#12】~DAS・ARR編~新人プログラマーはテトリスを作れるのか?【C#.NET】

2021.08.10

CATEGORY : C#.NET プログラミング

こんにちは、あんみんどうふです。

今回はDASとARRの実装です。今まで結構テトリスやってきている私も単語自体は初めて聞きました。

前回の記事はこちら。

こんにちは、あんみんどうふです。 今回はスコアを実装します。やはりゲームにはこれが無いとやりがいがありませんね! 前回の記事はこちら。 https://www.terasol.co.jp/%e3%83%97%e3%83%a...

全編見たい方はタグからどうぞ。

12-0.DAS・ARRとは

DASは「Delayer Auto Shift」の頭文字を取った略語で、左右へ入力し続けた時の溜め時間のことです。日本のテトラーからは「横タメ」と呼ばれているそうですが、私は聞いたことないです。

説明だけだとわかりづらいので試してみましょう。Windowsのメモ帳を開いて、どのキーでもいいので押し続けてみてください。

押し続け始めたとき、少し溜めてから同じ文字が入力されましたよね?
DASはこの溜め時間の部分を指します。

で、文字が連続で入力される間隔がARRです。「Auto Repeat Rate」の略語で、この時間が短ければ短いほど短い間隔で入力されます。

設置した時、既に他の方向へ入力されていればDASを挟むことなくARRの状態を継続して移動できるテクニックがあり、上級プレイヤーはこれを利用して高速でミノを積み上げています。

 

Windowsには内部的にDASとARRが標準で設定されているらしく、何もしなくてもそれっぽくなっていました。

ですが、ここまでテトリス開発しているとどうも本家に寄せたくなってしまいます。なんなら、この開発も「なるべく本家に寄せる」というコンセプトでやってきていますし。

 

要するにただの拘りであり自己満足に過ぎないですが、本家らしさを出すためにDASとARRを実装します。

12-1.DAS・ARRの仕様

方向キーを押しっぱなしにしているとその方向に1マス移動し、DASが開始されます。

キーが押されたままDASが終了すると、今度はARRが開始されます。

キーが押されたままARRが終了すると入力方向にもう1マス移動し、再度ARRが開始されます。

キーを離すと、DASARRを終了します。

こんな流れです。
DASしたら後はずっとARRで、キー離したらどっちも止めます。

また、対象であるすべてのキーが離されない限りARRは継続されます。

 

12-2.DAS・ARR用Timer

DASとARR、どちらも時間関連のものなのでデザイナーを開いてTimerを追加します。nameは「dasTimer」「arrTimer」にしました。
Intervalはコード内で設定するのでそのまま。

 

コードに戻り、DASとARRを設定します。
本家テトリスではDASやARRの時間が作品ごとに異なるようなので、今回も「ぷよぷよテトリス」を基準にすることにしました。一番この作品が馴染みあるので…。

というわけで、いつものグローバル変数の所に追加します。
ぷよぷよテトリスのDAS11FARR2Fとなってます。

(F(フレーム)は1/60秒を基準とした単位です。格闘ゲーム等でよく聞くやつです)

ARRを開始するにはDASが終了したことを知る必要があるため、フラグを用意しています。
また、方向キーの入力フラグは上下左右4キーのどれかが押されていたら、各要素の値をtrueにします。これにより、ミノ設置後もARRを継続したまま操作できます。
最初は配列でなく普通のint型でもいけると思ったのですが、押されたキーを1つしか判定できないのでやめました。

 

Tips. 入力デバッグ機能

作るの割と大変だったので、方向キーの入力状況を可視化できるようにデバッグ機能を追加していました。

「debugViewControl」というlabelを追加し、配列controlStatusの値を数値で表示させてます(コードは後ほど)。

 

12-3.TimerのInterval設定

次にTimerのIntervalを設定します。mainForm_Loadイベントに追記します。
Loadイベント内ならどこに書いても構いませんが、各コントロールの値を変更している所にまとめておくとわかりやすいです。

1F(フレーム)=1/60秒なので1000ミリ秒÷60×フレーム数で計算しています。

 

12-4.DAS・ARRの処理

DAS・ARRで繰り返し実行される処理として新規メソッド「controlRepeat」を作成し、以下を入力します。

配列controlStatusを順にチェックし、入力されているキーに応じて移動させてます。
最後の方にあるのはさっきのデバッグ用(debugViewControl)です。

 

Tips. 自由落下初期化のメソッド化

見慣れないメソッド「freeFallRestart」が紛れていますね・・・。
自由落下のリセット処理なんですけど書くのが面倒なのでメソッド化しました。それだけです。


 

また、Timerで処理を行うため、DASとARRのTimer_Tickイベントを作ります。

Tickイベントで行う処理はこれだけ。

 

今まで移動処理(minoMoving)はmainForm_keyDownでキーが押されたときに行っていましたが、DAS・ARRの実装に伴いcontrolRepeatメソッドにお引越しすることにしました。

というわけで、mainForm_keyDownの追記・修正です。

キー入力処理後、配列内要素のどれかがtrueであればDASを開始します。
同時にdasTimerが開始し、11F経過後ARRを開始します。

ただ、このままだとキーを離してもARRが継続されたままになっているので、キーを離した時に配列controlStatusをfalseにさせ、Timerをストップさせる必要があります。

 

というわけで「mainForm_KeyUp」の登場です。mainFormのイベントから追加します。
このイベントはKeyDownと真逆で、キーを離した時に実行されます。

配列controlStatusの要素全てがfalseの時にタイマー停止しています。
即ち、DASARRを終了させています。

 

【実装前】

 

【実装後】

DAS・ARR、無事に実装できました!
動きがスムーズになり、ぷよぷよテトリスに近い操作感になりました。いや~満足満足。


次回は更に本家へ近づけるべく、保留していた「ソフトドロップ」の実装をします。

#13 ソフトドロップ編へ続く。

こんにちは、あんみんどうふです。 今回はソフトドロップの実装です。というよりは、ミノを設置した時の"待機時間"を実装します。これにより回転入れの際に意図しない置きミスの発生率が下がります。 前回の記事はこちら。 https...