スプーキーズのちょっとTech。

SPOOKIES社内のより技工的な、専門的なブログページです。

擬似3Dダンジョンの作ってみよう!

擬似3Dダンジョンとは


擬似3Dダンジョンと聞いてなんぞやと思う人もいるでしょう。

ずばり、2D上で3Dっぽく見せるダンジョンということになります。

擬似3Dダンジョンを使った作品で有名な物を二つご紹介

  • ウィザードリィ
    • 言わずと知れた名作RPG
    • 1981年にAppleⅡ用に世間へ羽ばたく
    • 魔物の画像を表示したコマンド式戦闘システムを確立、多くのゲームに影響を与えた
  • 世界中の迷宮
    • ウィザードリィを意識して作られた現代版ウィザードリィ
    • 音楽が良い

未プレイの方にはおすすめのゲームです!

自己紹介


さて、本題に入る前に少しだけ自己紹介。

情報系大学の3年生のロックです。

名前の由来は溢れ出るロックンロール精神でしょうか。

気がついたらロックと呼ばれていました(不思議ですね)

そんな私ですが、普段は大学サークルでゲームを作っていたりします。

大学1,2年の間はしっかりと作品を完成させることが出来ずに積もり積もっていくガラクタ生産工場長でした。

しかし、最近少しずつ作品を完成させることが出来るようになってきました。

ガラクタからコードをひっぱてきたりすることもあるので、続けて来たからこそ今があると実感する今日この頃です。

前置き


今回の開発環境は以下の通りです。

  • Visual Studio 2015
  • C/C++
  • DXlib

Windowsでの開発となります。

主な実装機能


では、本題に入りましょう。

擬似3Dダンジョンを作るにあたって、今回実装する機能を紹介しておきます。

  1. ミニマップの表示
    • マップと現在位置とゴールの3種類を表示します
  2. 自由に歩ける
    • キーボードの矢印キーで自由に動けるようにします
  3. 視界の表示
    • 擬似3Dの描画をするための準備
  4. 擬似3Dの描画
    • 肝心要。主題
  5. ゴールを作る
    • 一応のゴール

目標としては擬似3Dの描画が出来れば達成とします。

それでは、一つずつ見ていきましょう。

処理の流れ


1. ミニマップの表示

ミニマップとは言っていますが、がっつりマップですね。

今回は擬似3Dとして最終的に描画してしまうので、全体マップというものが見れないことになってしまいます。

そこでこのミニマップを実装します。

< 実装方法 >

二次元配列を用意して、数字で埋めましょう。

  0:なし 1:壁 2:ゴール 3:初期位置

マップの大きさは12*12ぐらいにしておきましょうか。

最後に、数字に合わせて描画すれば完成(今回は色で表現)

  0:灰色 1:白 2:赤

初期位置に関しては描画しなくて良いでしょう。

代わりにプレイヤーの位置は表示することにします。

  プレイヤー:青

2. 自由に歩ける

プレイヤーも動けた方が良いですよね。

< 実装方法 >

Dxlib にキーボード入力を取得出来る関数があるので、それを用いればばっちりです。

  ↑:前へ進む ←→:旋回 ↓:後ろを向く

今回はマス目移動。

プレイヤーは位置と向きを持つことになります。

3. 視界の表示

突然出てきた視界という単語。

今回は3マス分の視界にしましょう。

左奥 中央奥 右奥
左中 中央中 右中
左前  私  右前

3*3のマスを調べて、壁があるのかないのかを判定出来れば良いです。

「私(プレイヤー)」の場所は調べなくても良いので、8マス調べることになります。

これが上下左右の4方向あることも踏まえて実装を考えます。

< 実装方法 >

プレイヤーの位置とプレイヤーの向きを基準にして、マス目を調べる

調べた結果は視界用の3*3の二次元配列に格納(プレイヤーの位置には 0 とか入れておきましょ)

視界用配列から、視界を取得して扱います。

せっかくなので、ミニマップと同様の手順で、視界も表示しておくことにします。

4. 擬似3Dの描画

ようやく来ました。

と言っても、ここまで順番にやってきたら、処理としてはすることがありません。

視界用配列を値を元にして、ぺたぺた画面に画像なり図形なりを貼り付けていく作業になります。

画像を用意するのは大変なので、図形を用います。

< 実装方法 >

Dxlib に四角形を描画する関数があるので、それを用いる。

左奥、中央奥、右奥、左中、中央中、右中、左前、右前、の8つそれぞれに四角形を描画する。

5. ゴールを作る

マップを作ったときに実はゴールが出来ています。

あとはそれを取得するだけです。

< 実装方法 >

プレイヤー位置のマップ情報を取得して、ゴールならゴールする

成果物


f:id:ishiyamacocoa:20170622235041p:plain 右上:ミニマップ   ミニマップの下:視界   左:擬似3D描画

f:id:ishiyamacocoa:20170623011253p:plain ゴールしました。

おまけ


触れていませんでしたが、通路も描画しています。

中央、中央奥にかけて、真っ暗じゃない床を描画しておくと、方向感覚が狂いにくいです(ないとわかりづらい)

これでウィザードリィも作れるぞーと思っていますが、特に作る予定はない。

知的好奇心だけで実装しちゃうお茶目なロックでした。

ありがとうございました。

以下に拙いですが、ソースコードを載せておきます。

  • Dungeon3D.cpp
  • Dungeon3D.h

の二つです。

改めて、ありがとうございました。

Dungeon3D.cpp


gist08766e3ec20e70c56dd91de28944df00