読者です 読者をやめる 読者になる 読者になる

「クォータービューの2Dゲームでクリックしたとこへ歩かせる」の巻

追記された前置き(2014/01/09)

先日、方々のサイトを見て回っていたら、このページについてご意見が予想以上に多く見つけてびっくりしてしまいました。(いいね!も、きびしいご意見も、両方)
この記事を書いた当時は、そんなに読まれはしないだろうと思っていました。
殴り書き状態で残しておくのも迷惑に思えてきましたので、全面的に「まじめに」書きなおしました。ヘタクソな文章ですが、まだ見ぬ良2Dクォータービューゲーの踏み台に、少しでもなれれば幸いです。

本文はここから。

 けいおん!!のOP、好きです。こんにちわ。
 あなたさまはいかがお過ごしですか。
 また懲りずに動画撮りましたよー。しゃべってますよー。緊張しすぎて「一番のキモ」を多用してますよー。
 今回は

  • プレイヤーがクリックした場所へキャラクターを歩かせた。
  • 歩く速度が遅かったので速めた。

 というところがポイントです。
 3コマのアニメーションのせいか、移動速度と歩数の調整がうまくできない・・・。


クォータービュー故のアタリ判定の難しさ

 「クリックしたところへキャラクターを歩かせる」ためにはクリックしたのがどのマスかを判定する必要があります。
 ファミコン版のドラゴンクエストのように正方形がならんだゲームの場合を考えてみましょう。このとき、クリックしたマスは座標の大小比較などで判定できます。

 次にクォータービューの場合です。画像データは正方形ですが、ゲーム上ではひし形ですね。なので同じ方法は適用できません。ひし形の外でもクリックしたことになってしまうからです。

 正しく判定させるには、座標系を変換しなければなりません。
 これをジオメトリ変換といいます。今日では3Dデータを画面の2D上へ落とし込む処理をそう言いますが、2D同士でも座標系が異なればジオメトリ(=幾何学的)変換といいます。

画面に描画する

 まず用語の定義を確認しましょう。一般的な用語と違っていたらごめんなさい。
 プログラム内部に持っているゲームの座標系をワールド座標とします。具体的には2次元配列の添字です。
 実際に出力される画面上の座標系(通常画面の左上が原点)をスクリーン座標とします。
 タイル上に敷き詰めるマップの画像をマップチップとします。マップチップの大きさはヨコ80ドット、タテ40ドットです。

  • ワールド座標(x,y)
  • スクリーン座標(X,Y)
  • マップチップ(width=80, height=40)


 で説明します。今回の動画で紹介したプログラムを基準にしますので悪しからず。
 ワールド座標からスクリーン座標への変換は、次の式で求めます。


 X = \frac{80}{2}(x + y)
 Y = \frac{40}{2}(x - y)


 xが大きくなれば画面上は右下へ、yが大きくなれば右上へ向ってマップチップを描画します。

クリックされた座標からワールド座標を求める

 (X,Y)から(x,y)は上の式を連立方程式として解けば求めれます。
 上の式では割り算が邪魔なので、取ると次の式になります。



\left\{
X = 40(x + y) \\
Y = 20(x - y)


 これを解きます。
 まず両方をそれぞれ展開。


X=40x-40y
2Y=40x-40y


 まずyを求めます。


40x=2Y+40y
X=(2Y+40y)+40y
X=2Y+80y
X-80y=2Y
-80y=2Y-X
80y=-2Y+X
y=\frac{X - 2Y}{80}


 次はx


40y=40x-2Y
X=40x+40x-2Y
-80x=-2Y-X
80x=X+2Y

x=\frac{X+2Y}{80}


 よって


x = \frac{X + 2Y}{80}
y = \frac{X - 2Y}{80}


 これでクリックされた位置から元の2次元配列の座標が求められます。

クォータービューでゲーム作ってる人へ

 自分がネットで調べた限りで、この問題で悩んでる人を多く見ましたので「俺はこうしましたよ」的な情報を書いてみました。ちょっとでもご参考になれればうれしいです・・・。
 ゲームが完成したらぜひ遊ばせて下さい。