はじめに
Vue3の勉強としてある程度複雑なロジックを含むフロントエンドの実装をしてみたいと思いテトリスを作成しました。
開発過程でクラスや、UI、処理内容などを整理するための簡単な設計からcomposition APIとクラスを使った状態管理や画面描画を実装したため、その時考えていた事を忘れないよう記事におこしていきたいと思います。
アプリURL
(バグみたいなテトリミノが出現しますが仕様です)
今回の記事はREADMEに記載してある概要に補足を加えたものですが、次回以降は設計に対してどのようにコードを書いたか、難しかったり迷ったりした部分を重点的に記事にしていきたいと思います。
今回の内容
- テトリスの簡単な設計をまとめる
- テトリスの主なロジックを図を使ってまとめる
使用技術
- Vue3(Composition API, Typescript)
- Vite(モジュールバンドラ)
- Vuetify3(デザインFW)
- vue-router
UI・外観
テトリスの機能を実装したページについて外観とパーツの名前をまとめました。
現状は特に捻りもなく普通のテトリスを作成しようと思います。
アプリケーション構成
クラスを使ってロジック部分の役割分担を行い、テトリスに関する複雑化しやすい処理はカプセル化してクラスに閉じて定義したいと思います。
最終的にクラスはVueのコンポーネントでインスタンス化して、Vue側で各クラスメソッドを利用しユーザー操作を実現、クラスフィールドをリアクティブ化し描画に利用していきたいです。
Vueファイルにロジックの詳細を持たせず、難しい部分はクラスに定義したい。
クラス
全体図
主な登場人物
- テトリミノ(クラス)
- テトリミノマネージャー(クラス)
- フィールド(クラス)
- プレイページ(Vueコンポーネント)
- テトリミノボックス(Vueコンポーネント)
各クラスやVueコンポーネントの役割については実装内容と合わせて後々記載したいと思います。
テトリスの主ロジック
テトリスの中でメインの処理となり複雑化し易いもについて図を作成して整理しました。
詳細は記載しませんがこのようにテトリスを実装していこうという大枠になります。
- フィールドとテトリミノの描画、テトリミノの移動、回転
テトリミノクラスは自分がフィールド上のどの位置にいるか、またタイルはどういった配置にあるかという情報を持たせ、これらの情報をフィールドクラスに渡しフィールド上へテトリミノを配置します。
テトリミノの状態の変化(回転、移動)はテトリミノクラスのクラスフィールドを自身のクラスメソッドで更新する事により実装できるのですっきりすると考えました。
- 堆積したテトリミノをフィールドに保持する
フィールドクラスは、堆積したテトリミノを保持する記録用のフィールドと、記録用フィールドに落下中のテトリミノを配置した描画用のフィールドの2つをインスタンス化して使用する事を考えました。
描画用フィールドはVueコンポーネント内でリアクティブ化しテトリミノの状態が変化(回転、移動)に応じて画面上に再描画を行う実装を考えました。
- テトリミノの移動や回転時に壁や堆積タイルとの衝突を判定する
移動や回転を行った際、テトリミノが壁や堆積したテトリミノに衝突するかどうかの判定では、堆積したテトリミノ情報を持つ記録用フィールドに、描画予定のテトリミノ情報(フィールド上位置とタイル配置を持つ)を渡すことで、フィールド上に描画可能かを判定する事ができると考えました。
その他、下記のようなユースケースを実現するために各種クラスメソッドやクラスフィールドを定義しました。
- テトリミノ出現
- テトリミノストック
- 出現予定テトリミノ表示
- テトリミノ落下・堆積
- 列消滅
- ゲームオーバー
- 落下スピード操作
まとめ
今回は簡単に概要のみまとめましたが次はコードベースで要点をまとめて記事にしたいです。