パスワードを忘れた? アカウント作成
16387875 journal
日記

yumeの日記: RogueLikeゲームを作るぞ 1 2

日記 by yume

RogueLikeを作り始めた。最終的な完成像もなんとなく頭の中にあり、全体的にはそこそこ強くベルリン解釈に則する、いわゆるRogueLikeゲームにする予定。特徴としては、アイテム(武器・防具・消費アイテム)に関する考え方が異なることと、ダンジョンの生成システムがちょびっと異なることである。

ただ、チーム内では他の企画も始まっており、途中でこっちの企画が停止する期間が出るのは必至なので、備忘録的に書いていく。運よくスイスイ進めばすんなりリリースできるかも。

--

さて、Unityでは表示と衝突判定を同じGameObjectに定義する(キャラのビジュアルと衝突判定をワンセットにするとか)のが一般的だが、今回作るものには複雑な衝突判定は必要ない。
まぁ別に計算量的に不安があるわけでもないし、それほど大量のオブジェクトを置くわけでもないので、Unityの衝突判定をそのまま使った実装でもいいとは思うんだけど、というかはじめはそう書いてたんだけど、なんとなく分離した方がいいんじゃないのという気になってきたので分離した。さっそくめんどくさいことをしてるな。

RogueLikeの構成要素を考えて順に実装していこう。
まずはダンジョン(地形)とキャラクターである。
ダンジョンを表すクラス。Dungeon
これはDungeonTileという構造体の配列クラスである。
ダンジョンはshort型の二次元配列で作れるかな、とはじめは思っていたが、ダンジョンアセットをJsonで保存・読み込みする場合、配列は1次元の形の方が都合がよかったのでこのような形にした。
DungeonTileは、Vector2Int(2つのintの組み合わせの構造体)とTileの種類を表すTileTypeから成る。これ構造体じゃなくてクラスの方がよかったかな?
さしあたって、これでDungeonを握っているクラスは地形を把握できる。

キャラクターの方はちょっと厄介だ。
ターンごとにアクションを行う存在なので、キャラクターはActorと呼ぶ。
Actorはだいたい以下の要素からなる。
・ステータス(HPとか)を持つ。HPが尽きると死ぬ。
・ポジション(ダンジョン上での座標)を持つ。
・陣営を持つ。プレイヤーかエネミーか。
実体はこんな感じ。
ごちゃっとしているが差し当たって実装したい部分は実装した。
これはプレイヤーもエネミーも種類を問わず共通で使えるパーツになる。と思う。

プレイヤーやエネミーの種類を分けるのは、本質的にはAI(プレイヤーの場合は人間の脳)ということになるので、ActorBrainという概念を作り、Actor実体やActorの描写をBrain側が操作するという形をとる。
例えば、Playerの場合はこんな感じ

自分のターンが回ってきたら、DoTurnAction()が呼び出される。Brainは自分のAIに応じたアクションを決定し、ModelとViewにそれぞれ命令を送る。例えば「上に歩く」ならModelはPositionを上に1つずらし、Viewも同様に座標をずらしながらアニメーションを再生するといった感じ。

現在の実装では、ある地点に進めるかどうか、などもBrain側が判断している。まぁ壁抜けできるステータスもありうるし、AIはステータスに応じて壁を無視するか決める必要はあるだろう。同一座標に複数のActorが存在するパターは……絶対禁止ということにしてよさそうだが保留。

ターンシステムは、これらのActorBrainをまとめたコレクションクラスを用意し、そのコレクションを元に順番にDoTurnAction()を呼び出すことで実装する。

あとは具体的なダンジョンをどこで編集するかだが、これは一旦Unityエディター上で簡単にJsonを書き出す仕組み「DungeonEditor」を作った。エディターのタイルの状態からDungeonAssetクラスを作り、それをJson化して保存しておく。
実際のレベルはこのJsonを読み込んでダンジョンやActorを展開する。
画面上の表現は、さしあたってActorはSpriteRenderer、ダンジョンはTileMapで行う。

あとは、敵のダミーとしてランダムに歩くBrainを作って、そこまででこのくらいが実装できた。

あと経路探索に関する実装が必要で、valantonini氏がAスター経路探索アルゴリズムを公開されていたので、こちらをベースに使う。いくつか今のプログラムで使えるように、橋渡しのコードをちょっと書いたらもう使えた。
DungeonPathFinerクラスは、元のプログラムが地形をshort[,]型で扱っているので、Dungeonクラスをshort[,]に変換したり、いただいた経路情報を都合のよいVector2Int[]型にしたりしている。

こんな感じになる。紫色のやつが経路探索して近づいてくるエネミーだ。

といったところで今日は終わり。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

アレゲは一日にしてならず -- アレゲ研究家

読み込み中...