学習を目的としてKotlinでテトリスのようなものを作る ➂


前回はブロックの落下と移動を実装しました。


今回実装する機能はブロックの動きの制限とブロックの積み上げです。


動きを制限する


今のままだとブロックがフィールドの枠を超えてしまうので、動きをフィールド内に収まるようにします。
GraphicクラスのupdateBlockPos関数を以下のようにします。
まずブロックの位置を更新して、FieldクラスのchckBlockPosで位置の有効性を確認します。
向こうの場合は位置を戻します。


そしてFieldクラスに以下の関数を追加します。
すべての四角形の位置を確認し、ひとつでもフィールドに収まらないものがあればCANTMOVEを返します。
ブロックの位置が正しいかどうかの判断はFieldクラスにやってもらうことにしました。
ブロックの位置からインデックスを取得しそのインデックスの有効性を確認します。


Const.ktに以下のパラメーターを追加します。


後々のことを考える必要はあると思いますがひとまずこうしておきます。
実行するとこんな感じになります。



ブロックの積み上げ


フィールドの一番下に到達したら、フィールドにブロックを追加していきます。

Fieldクラスに以下のメンバ変数を追加します。
これは後で作成するSquareクラスをマスの数だけ格納しておく配列です。


そしてFieldクラスのcheckBlockPos関数を以下のようにします。
y座標に関しての処理を追加しました。
図形のy座標とインデックスを求めますがそのインデックスが0未満の場合判定はしません。

x座標から計算したxインデックスとy座標から計算したyインデックスから、
先ほど定義した配列のインデックスを計算します。
インデックスの値が配列の大きさ以上か、インデックスの値が指す配列の要素がnullでない場合はそのブロックの位置は無効と判定します。


そしてGraphicクラスのupdateBlockPos関数を以下のようにします。
下に移動できない場合はフィールドにブロックを追加します。
そしてmakeBlockが新しいブロックを生成します。


Fieldクラスに以下のメソッドを追加します。
addBlockは上に挙げたGraphicクラスから呼ばれるメソッドです。
フィールドにブロックを追加します。
FieldクラスのblkOnFieldにインデックスを指定してSquareクラスのインスタンスを格納します。
Squareクラスのコンストラクタ引数にはRectとPaintのインスタンスを渡します。

drawBlkOnFieldはフィールドに追加したブロックを表示するメソッドです。


GraphicクラスのdrawFieldを以下のように修正します。
FieldクラスのdrawBlkOnFieldを呼び出します。


実行するとこのようになります。


だんだんと形になってきました。
今度はブロックを消す処理を追加する必要があります。
次回その処理を追加したいと思います。