トップページ > 過去ログ > 記事閲覧
クォータビューのマップについて
名前:お茶。 日時: 2010/05/02 15:46

はじめまして。 最近、S-RPG(戦略・戦術SLG)を作ろうと思い立ったのですが、いきなりつまずいたので質問させて下さい。 現在、戦闘画面のマップを作成しています。 クォータービュー(FFTやFEのような感じ)のものを作ろうと考えています。 つまり、マップチップは菱形になりますよね? すると、どういう処理を行えばよいのでしょうか? オセロを作ったときは二次元配列を使って正方形のマスを作りましたがそれを応用するのでしょうか? また、視点変更(左右にに90°づつ)も実装するつもりなんですが、2Dの知識で可能でしょうか? 出来るのであれば方法を教えて下さい。 3Dだと計算が難しくて理解ができません・・・orz どの関数を使えばいいのか、どのように使うのか等を教えて頂けると幸いです。

Page: 1 |

Re: クォータビューのマップについて ( No.1 )
名前:sy(サイ) 日時:2010/05/02 20:48

>現在、戦闘画面のマップを作成しています。 >クォータービュー(FFTやFEのような感じ)のものを作ろうと考えています。 >つまり、マップチップは菱形になりますよね? >すると、どういう処理を行えばよいのでしょうか? >オセロを作ったときは二次元配列を使って正方形のマスを作りましたがそれを応用するのでしょうか? 基本的には2次元配列に高さ情報を含めておいて、ひし形、柱上のチップを奥から並べて行く感じでしょうか…。 手前のマップで見えないところは描画をキャンセルしたり、意外と複雑かもですね。 結局は見た目だけなので、45度見た目が回転しててもゲーム情報は同じです。 わざわざ、見た目と同じようなデータ構造は必要ないわけです。 2Dですと、どうしても「奥行をどうするか?」と言うレンダリングの概念も必要になってきますね。 2Dの場合、描く順番をウマくやればよいのですが…。 手前のチップにキャラが隠れる・・とかやるので結構苦労しそうな気がします。。 マップを描きながらキャラも描くことに 2Dでやる場合なら、FFTAのマップが参考になりそうです。 FFTAは視点回転出来ない仕様でした。 >また、視点変更(左右にに90°づつ)も実装するつもりなんですが、2Dの知識で可能でしょうか? >出来るのであれば方法を教えて下さい。 >3Dだと計算が難しくて理解ができません・・・orz 出来ると思いますが、圧倒的に3Dの方が実装が楽になる気がします。 90度づつ回転してもどのようにチップを表示するかにかかるので。 >どの関数を使えばいいのか、どのように使うのか等を教えて頂けると幸いです。 2D画像の表示はDrawGraphで出来ますし、音の再生ならPlayMusicですよ。 SRPGに特化した関数はなく、システム自体は自分で作成するところです。 ●余談 ここからは、余計なお世話かもですが。 まずあなたはどのように実現しようと思ったのかを教えて頂けると答えやすいです。 どうやったら良いか?と言う質問では答える側の方が作る部分が多くなります。 「これ作って」と言ってるのも同じでしょう。 立体で作るようですが、平面上のマップでゲームを作った経験がおありでしょうか? FFTのようなSRPGの概念をバラしていくと以下のような事が実現できないと完成は遠いと思われます。 RPGが作れなければならない。 ┗シナリオ、メッセージウインドウ処理、ステータス画面処理等の基本的なシステムの構築。 戦争シミュレーションのゲームが作れなければならない。 ┣バトルシステムの構築(平面:草や木によって移動範囲が狭まったり) ┗戦闘AI(RPGと違い、移動の戦略を含む) 高さ情報をどのようなデータ構造で実装するか考えなければならない。 ┣視点回転するなら3D画面の方が構築が楽。(マップは箱状、キャラは板ポリゴン) ┗戦争シミュレーションの移動範囲の計算時に高さをどれだけ登れるかと言う情報も必要。 ザックリですが・・・。
Re: クォータビューのマップについて ( No.2 )
名前:いっち 日時:2010/05/04 23:38

2Dによる擬似的なクォータービューの簡単なサンプルソースを作ってみました。 ポイントは内部的な配列の座標とクォータビュー上の座標をうまく対応させることです。 我ながら酷いやっつけ具合ですが、参考になれば幸いです。 sy(サイ)さんもおっしゃっていますが、キャラクターや地形等が重なる場合は描画順序を計算する必要があります。 視点変更や、奥行き等のディテールを考えた場合は3Dによる実装のほうが良いかもしれません。 //-- サンプルソース (test1.bmpを仕様) --// #include "DxLib.h" const int ARRAY_X_MAX = 10; const int ARRAY_Y_MAX = 5; const int QUARTER_W = 32; const int QUARTER_H = 16; const int QUARTER_SCREEN_X = 0; const int QUARTER_SCREEN_Y = 0; const int QUARTER_SCREEN_W = 640; const int QUARTER_SCREEN_H = 480; const int QUARTER_X_MAX = (QUARTER_SCREEN_W / QUARTER_W); const int QUARTER_Y_MAX = (QUARTER_SCREEN_H / QUARTER_H); // 仮想配列の座標からクォータービューの座標に変換 inline int GetXA2Q( int ax, int ay ) { return ax + ay + 1; } inline int GetYA2Q( int ax, int ay ) { return (ARRAY_X_MAX - GetXA2Q( ax, 0 )) + 1 + ay; } // クォータービューの座標からスクリーンの座標に変換 inline int GetXQ2V( int qx ) { return qx * QUARTER_W + QUARTER_SCREEN_X; } inline int GetYQ2V( int qy ) { return qy * QUARTER_H + QUARTER_SCREEN_Y; } // 仮想配列の座標からスクリーンの座標に変換 inline int GetXA2V( int ax, int ay ) { return GetXQ2V( GetXA2Q( ax, ay ) ); } inline int GetYA2V( int ax, int ay ) { return GetYQ2V( GetYA2Q( ax, ay ) ); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ); if ( DxLib_Init( ) == -1 ) return -1; SetDrawScreen( DX_SCREEN_BACK ); int StrColor = GetColor( 255, 0, 0 ); int LineColor = GetColor( 255, 255, 255 ); int DotColor = GetColor( 0, 255, 0 ); int CharX, CharY, CharW, CharH; int HandleChar = LoadGraph( "test1.bmp" ); GetGraphSize( HandleChar, &CharW, &CharH ); CharH = (int)(CharH * (((float)QUARTER_W) / CharW)); // キャラの描画サイズを適当に補正 CharW = QUARTER_W / 2; CharX = CharY = 0; int KeyStateNew = 0, KeyStateOld = 0; while ( ProcessMessage( ) == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { KeyStateNew = GetJoypadInputState( DX_INPUT_KEY_PAD1 ); if ( KeyStateNew != KeyStateOld ) { if ( KeyStateNew & PAD_INPUT_UP ) CharY--; if ( KeyStateNew & PAD_INPUT_DOWN ) CharY++; if ( KeyStateNew & PAD_INPUT_LEFT ) CharX--; if ( KeyStateNew & PAD_INPUT_RIGHT ) CharX++; KeyStateOld = KeyStateNew; } if ( CharY < 0 ) CharY = 0; if ( CharY >= ARRAY_Y_MAX ) CharY = ARRAY_Y_MAX - 1; if ( CharX < 0 ) CharX = 0; if ( CharX >= ARRAY_X_MAX ) CharX = ARRAY_X_MAX - 1; ClearDrawScreen( ); // クォータービューの全座標に点を描画 for ( int x = 0; x < QUARTER_X_MAX; x++ ) for ( int y = 0; y < QUARTER_Y_MAX; y++ ) DrawPixel( GetXQ2V( x ), GetYQ2V( y ), DotColor ); // マス目を描画 for ( int x = 0; x < ARRAY_X_MAX + 1; x++ ) DrawLine( GetXQ2V( GetXA2Q( x, 0 ) - 1 ), GetYQ2V( GetYA2Q( x, 0 ) ), GetXQ2V( GetXA2Q( x, ARRAY_Y_MAX ) - 1 ), GetYQ2V( GetYA2Q( x, ARRAY_Y_MAX ) ), LineColor ); for ( int y = 0; y < ARRAY_Y_MAX + 1; y++ ) DrawLine( GetXQ2V( GetXA2Q( 0, y ) - 1 ), GetYQ2V( GetYA2Q( 0, y ) ), GetXQ2V( GetXA2Q( ARRAY_X_MAX, y ) - 1 ), GetYQ2V( GetYA2Q( ARRAY_X_MAX, y ) ), LineColor ); // キャラ描画 DrawExtendGraph( GetXA2V( CharX, CharY ) - CharW, GetYA2V( CharX, CharY ) - CharH, GetXA2V( CharX, CharY ) + CharW, GetYA2V( CharX, CharY ) + 0, HandleChar, TRUE ); DrawFormatString( 0, 0, StrColor, "配列上の座標 X = %d, Y = %d", CharX, CharY ); DrawFormatString( 0, 20, StrColor, "クォータービュー上の座標 X = %d, Y = %d", GetXA2Q( CharX, CharY ), GetYA2Q( CharX, CharY ) ); ScreenFlip( ); } DxLib_End( ); return 0; } ※どうしても納得いかなかったのでソースのみ若干修正しました。マナー違反だとは思いますがご容赦下さい。
Re: クォータビューのマップについて ( No.3 )
名前:お茶。 日時:2010/05/03 00:08

返答ありがとうございます。 自分もいくつか返答・質問させていただきます。 >>sy(サイ)さん >見た目と同じようなデータ構造は必要ないわけです なるほどです。 ということは、描画する際にクォータービューでの座標に変換するという方向で良いのでしょうか? >3Dの方が実装が楽 自分も一度3Dを考えたのですが、どこまで3Dなのかが解らず断念しました・・・。 この場合、ステージは3D、キャラクターは2Dというようにすべきなのでしょうか? また、マップエディタも作る予定なのですが、3Dのマップエディタってとても難しいような気がします。 自分には大学で扱われるような数学の知識はありません。それでも、3Dの実装は可能なのでしょうか? >あなたはどのように実現しようと思ったのかを教えて頂けると答えやすい ご指摘ありがとうございます。 自分の意図を伝えるのにはこちらからも情報を渡さなければいけませんでしたね。気を付けるようにします。 >平面上のマップでゲームを作った経験がおありでしょうか とても単純なSTGを作ったことがあるだけです。マップや戦闘システムなどの知識は全くといっていいほどありません。だからこそ勉強しようとおもいましてSRPGを作ろうと思ったのです。 >いっちさん >2Dによる擬似的なクォータービューの簡単なサンプルソースを作ってみました ありがとうございます。どんなにネットを探しても見つからなかったので困っておりました。 とても分かりやすく、参考にしやすくてとても助かります。 >視点変更や、奥行き等のディテールを考えた場合は3Dによる実装のほうが良いかもしれません。 やはり3Dにすべきなのでしょうか? ちらっと見てみたのですが、座標が五つ出てきていて、さらに行列?やら座標変換?やら聞いたことのない言葉がたくさん出てきてこんがらがってしまいました。 それでも可能なのでしょうか?
Re: クォータビューのマップについて ( No.4 )
名前:sy(サイ) 日時:2010/05/03 00:55

>>3Dの方が実装が楽 FFTの場合キャラクターは2Dで、板ポリとか呼ばれる平面の四角形ポリゴンを使っています。 具体的にはビルボードと言う方法で、DXライブラリがサポートしてくれているので何も難しい事はないと思います。 マップは3Dです。立方体のポリゴンをメタセコイアでちょちょいと作成して並べるだけでもマップになると思います。 >マップエディタも作る予定なのですが、3Dのマップエディタってとても難しいような気がします。 3Dの場合でも、実は難しくないです。 データの持たせ方によっては簡単に作れると思います。 適当にでこぼこの地形を立方体ポリゴンを並べて作るとします。 しかし、ゲームに必要な情報は「高さ」「地形」だけなので、例えば10×10の広さのマップなら、 map[10][10][2] = { { {高さ情報,地形情報},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} }, { {●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} }, { {●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} }, { {●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} }, { {●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} }, { {●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} }, { {●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} }, { {●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} }, { {●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} }, { {●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●},{●,●} } }; これを箱を並べたマップに合わせて作成するのです。 もちろんエディタでもこの情報の持ち方ならさほど難しい事はしないと思います。 もちろんさらに情報を追加したい場合は最後の添え字が増えるだけです。 {高さ情報,地形情報,トラップ番号,イベント番号} 3Dの表示に関してもカメラやライトなどの処理はDXライブラリがサポートしています。 算術的な関数も多数あるので一度3D関連の関数をのぞいてみては? 関数の使い方で躓いたらここですぐに聞けると思います。 ちなみにアマチュアゲームなら高校数学で十分で、 考え方さえ分かれば計算は全部PCがやってくれます。
Re: クォータビューのマップについて ( No.5 )
名前:いっち 日時:2010/05/03 01:53

> やはり3Dにすべきなのでしょうか? 2Dにしても3Dにしても、それぞれに難しい部分と簡単な部分があるので一概には言えません。 お茶。さんがお持ちのコンセプトを実現できるのであれば、2Dでも3Dでも構わないと思います。 (スレッドを読む範囲ではどちらでも出来ると思います) 3Dではカメラを自由に移動できると言っても、キャラクタをすべてモデリングしないと カメラの角度によってはやはりおかしな描画結果になる(特にアニメーションする場合)と思います。 ですので、キャラクタをビルボード等で表現する場合は、 やはりある程度角度を固定することになる(視線の平行移動やズームは可)のではないかと思います。 > ちらっと見てみたのですが、座標が五つ出てきていて、さらに行列?やら座標変換?やら聞いたことのない言葉がたくさん出てきてこんがらがってしまいました。 私もベクトルや行列が苦手なのでお気持ちは良くわかりますし、同じように戸惑いました。 ただ、球面上のカメラ移動ぐらいであれば、サンプルやリファレンスをよく読めば、 時間はかかるかもしれませんが十分理解可能だと思います。 使用する数学的な知識もほとんど高校範囲内(外積は範囲外かも)で済むはずです。
Re: クォータビューのマップについて ( No.6 )
名前:お茶。 日時:2010/05/03 02:04

お早い返答ありがとうございます。 >3Dの場合でも、実は難しくないです 複雑な計算はDXライブラリとPCが処理してくれるのですね。 少し安心しました。 説明聞いてたらなんだかやれそうな気が出てきました。 折角ですので、3Dに挑戦してみたいと思います。 右も左も分からない状態で手探りで作って行くことになりますが、 めげず焦らずがんばりたいと思います。 詳しい説明とアドバイス、ありがとうございました!
Re: クォータビューのマップについて ( No.7 )
名前:いっち 日時:2010/05/04 23:41

座標変換で書き忘れましたが、(No.2)のソースでも単純で一方通行ですが座標変換を行っています。 内部的な配列の座標→クォータービュー上の座標→スクリーン座標に変換しています。(GetXA2QやGetXQ2Vがそれです) 3Dの座標変換も基本的には同じようなものです。 ※どうしても納得いかなかったので(No2)のソースを若干修正しました。

Page: 1 |