マップの切り替え処理

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
s-rush

マップの切り替え処理

#1

投稿記事 by s-rush » 16年前

いつもお世話になっています。
今RPGのゲームを作っているのですが、マップの切り替え処理に
つまずいているので質問させていただきに来ました。

RPGのゲーム(とは限らないとは思いますが)ではマップ⇔ダンジョンのマップ切り替えがよくあると思います。
フィールドマップを表す配列とは別に
int dungeon_map[3][5][5]={
    {0,0,0,0,0
     0,2,1,1,0
     0,1,1,1,0
     0,1,1,1,0
     0,4,0,0,0},

    {0,0,0,0,0
     0,3,1,1,0
     0,1,1,1,0
     0,1,1,2,0
     0,0,0,0,0},

    {0,0,0,0,0
     0,1,1,1,0
     0,1,1,1,0
     0,1,1,3,0
     0,0,0,0,0},
}
0:通行不可 1:通行可 2:上の階へ 3:下の階へ 4:フィールドマップへ
というマップデータとして、マップの切り替えが起こった時の処理に悩んでいます。

マップが切り替わったとき、自キャラの座標をどこかに格納しておけば、
マップが切り替わった後(特にマップ⇔ダンジョン)の描画する自キャラの位置を特定できると思うのですが、
今困っているのは、自キャラを操作するプログラムなんです。

現段階での自キャラのあたり判定のプログラムはこうです。
int can_or_cannot(int x,int y,int muki){//進めるかを判定する
    if(muki==0){//上向きなら
	if(field_map1[y/32-1][x/32]==0 || (field_map1[y/32-1][x/32]==2 && ch.st!=3)){//進めるか判定
            return 1;//エラー
        }
    }
    if(muki==1){//左向きなら
        if(field_map1[y/32][x/32-1]==0 || (field_map1[y/32][x/32-1]==2 && ch.st!=3)){
            return 1;
        }
    }
    if(muki==2){//下向きなら
        if(field_map1[y/32+1][x/32]==0 || (field_map1[y/32+1][x/32]==2 && ch.st!=3)){
            return 1;
        }
    }
    if(muki==3){//右向きなら
        if(field_map1[y/32][x/32+1]==0 || (field_map1[y/32][x/32+1]==2 && ch.st!=3)){
            return 1;
        }
    }
    return 0;//正常
}
見ての通り、フィールドマップの時にしか対応できないプログラムなんです。
これをダンジョンのような別のマップ上でも対応できるにはどのようにしたらいいでしょうか?
switch文で、場合分けするのもコードが無駄に長くなりそうですし・・・
なにか良い案はないでしょうか?

開発環境はVC++2008 EEです。

kazuoni

Re:マップの切り替え処理

#2

投稿記事 by kazuoni » 16年前

マップの大きさが絶対に一緒
っということであれば、引数にマップデータを
渡せば解決できそうですが。

dic

Re:マップの切り替え処理

#3

投稿記事 by dic » 16年前

フィールドマップとダンジョンマップの違いが分からないので
なんとも言えないですが

s-rush

Re:マップの切り替え処理

#4

投稿記事 by s-rush » 16年前

フィールドマップとダンジョンマップの大きさは違うので、引数にマップデータを渡せなさそうです。
まだ全体のマップデータはできていませんが、
・フィールドマップは1000×1000
・ダンジョンマップは500×500
・建物の中50×50
くらいになると思います。

Justy

Re:マップの切り替え処理

#5

投稿記事 by Justy » 16年前


>引数にマップデータを渡せなさそうです

 少し考え方を変えて、2次元配列ではなく普通に一次元配列で扱えばできますよ。

 ただ、マップデータへのアクセスは二次元配列の時はコンパイラが自動で
計算してくれましたが、一次元配列の場合は自分で計算しないと
いけなくなりますので、マップの縦横のサイズも一緒に渡してあげるといいでしょう。

 下の方に適当なサンプルを乗っけておきます。


 ところで、フィールドマップが 1000x1000ということですが、
これのデータはソースコード上に記述する予定なのでしょうか?


参考例)
[color=#e0f0ff" size="-1" face="monospace]
// マップデータ
static const int dungeon_map1[/url]=
{
0,0,0,
0,2,1,
0,1,1,
0,1,1,
0,4,0,
};
static const int dungeon_map2[/url]=
{
0,0,0,0,0,
0,2,1,1,0,
};
static const int dungeon_map3[/url]=
{
0,0,0,0,0,
0,1,1,1,0,
0,1,1,1,0,
0,1,1,3,0,
0,0,0,0,0,
};

// マップ構造体
struct Map
{
int x_size;
int y_size;
const int *data;
};

// 複数のサイズの異なるマップを1つにまとめる
static const Map maps[/url] =
{
{ 3, 5, dungeon_map1 },
{ 5, 2, dungeon_map2 },
{ 5, 5, dungeon_map3 },
};

// 位置からマップデータへのオフセットを取得
static int get_map_offset_position(const Map *map, int x, int y)
{
if(!map || x < 0 || y < 0 || x >= map->x_size || y >= map->y_size)
return -1;
return y * map->x_size + x;
}

// マップの位置からマップデータを取得
static int get_map_data(const Map *map, int x, int y)
{
int offset = get_map_offset_position(map, x, y);
if(offset < 0) return -1;
return map->data[offset];
}

int can_or_cannot(const Map *map, int x, int y,int muki)
{
int xx = x / 32, yy = y / 32;
int data;
switch(muki)
{
case 0:
y -= 1;
break;
case 1:
x -= 1;
break;
case 2:
y += 1;
break;
case 3:
x += 1;
break;
}

data = get_map_data(map, xx, yy);
if(data < 0) return -1;

if(data==0 || (data==2 && ch.st!=3))
return 1;
return 0;
}
[/color]

kazuoni

Re:マップの切り替え処理

#6

投稿記事 by kazuoni » 16年前

dicさんのおっしゃるように、
フィールドマップとダンジョンマップの違いが
よくわからないのではっきりしたことが言えません。
両者に格納されているデータに相互性はないっぽいですよね^^;
階段はフィールドにはありませんもんね^^;

両者ともに0は通行不可であり、それ以外は可とかならば
簡単にできると思いますが。

一つ疑問なのですが、
次に進むと上の階に行く(field_map1[y/32-1][x/32]==2)だったら進めない
っというのは必須ですか?

例えばですが・・・
まず、static int floor_checkというを変数を用意します。
これは現在のダンジョンを出る(上の階や下の階へ)たびにfloor_checkに0を代入します。
また、そのフロアで一歩踏み出したら1になるようにします。
そして、can_or_cannot()を呼び出す前に
if(field_map1[y/32-1][x/32]==2 && floor_check==1)
に合致したら、
・ダンジョンデータの入れ替え
・floor_check=0(もしフラグが立ったままだと一階まで一気に下っ(上っ)ていってしまいます。)
をすればダンジョンの移動は実現できそうです。

分かりにくくてすいません。
結局いいたいことはフィールドデータ、ダンジョンデータ
両者共通の歩行にしたいならば、条件をゆるくしないと厳しいです。
なので、階段の処理を除けば少しは実現に近づくかなと思いました。

(field_map1[y/32][x/32+1]==2
ch.st!=3(これは何か分からないので・・・ノータッチ)

をなくすとうまくいきそうだ!っとぐだぐだ↑で説明してました^^;

わかりづらい・・・

kazuoni

Re:マップの切り替え処理

#7

投稿記事 by kazuoni » 16年前

すみません。。
たしかにJustyさんのおっしゃるように、
マップデータのサイズは必須ですね^^;

s-rush

Re:マップの切り替え処理

#8

投稿記事 by s-rush » 16年前

一応ダンジョンマップと銘打ってはいますが、
ダンジョンだけではなく、建物の中とか・・・
とりあえずフィールドマップ以外のマップへの切り替え、
その移動先のマップ上での移動処理をどうするのかに悩んでいます。

フィールドマップとの違いは、全体の大きさが違う(小さくなる)こと以外に、
階段の処理?だけで、ほかの処理系には何も変わることはないです。
(0は通行不可、1は通行可のような条件)
建物の中では階段やワープみたいなもので、さらにマップの切り替えが生じるくらいです。

で、field_map1[y/32-1][x/32]==0というような条件の書き方にしてしまうと、
移動先での条件に当てはまらないので、悩んでいました^^;

と、もっと詳しく移動先のマップの処理等を書くべきでした。

>>(field_map1[y/32][x/32+1]==2
>>ch.st!=3(これは何か分からないので・・・ノータッチ)
これはスルーしてもらって構いません^^;
海辺での移動条件なので・・・

>Justyさん
サンプルコードありがとうございます。
今必死に解析している途中です。

POK

Re:マップの切り替え処理

#9

投稿記事 by POK » 16年前

マップの切りかえってそんなに難しいもんですかね?

やそ

Re:マップの切り替え処理

#10

投稿記事 by やそ » 16年前

POKさん>
 マップの切替自体はたいして難しくないはず。
 トピ主がゲーム製作に慣れていないだけでは?

s-rush

Re:マップの切り替え処理

#11

投稿記事 by s-rush » 16年前

>>トピ主がゲーム製作に慣れていないだけでは?
おっしゃる通りゲーム作りは初めてなので慣れていないです^^;

マップの切り替え自体はできそうなんですが、
マップ切り替え後の、キャラの移動処理に・・・

一応アイデアはあるのですが、メモリの無駄遣いになりそうなので^^;

一つ疑問なんですが、大規模なゲーム(市販のゲームみたいなもの)では
どれくらいのメモリを使用されているのでしょうか?

Justy

Re:マップの切り替え処理

#12

投稿記事 by Justy » 16年前


>一つ疑問なんですが、大規模なゲーム(市販のゲームみたいなもの)では
>どれくらいのメモリを使用されているのでしょうか?

 具体的にどれくらいというのはハードやソフトによってまちまちなので
一概にはいえません。

 PCのゲームなら動作推奨環境のメモリの項目が多少は参考になるかと思います。
(もちろん、その数字分使っている、というわけではないですよ)

 コンシューマ系のゲームの場合、(モノにもよりますが)ある程度のクオリティがある
ゲームなら使用可能メモリに対して6~8割以上は使われているでしょう。
(というか、ぎりぎりで動いていることも多いです)

 ちなみに使用しているメモリの多くは3Dモデル・テクスチャ、コリジョンデータで
占められていることが多いようです。



>一応アイデアはあるのですが、メモリの無駄遣いになりそうなので

 それは何十、何百MB以上消費するアイデアなのでしょうか?
 もしそうでなければ、とりあえずやってみてはどうでしょうか?

 反対に大量に消費するようであれば、何かが間違っていると考えられるので、
その時は改めて情報を整理した上で質問するのがいいかと思います。

s-rush

Re:マップの切り替え処理

#13

投稿記事 by s-rush » 16年前

>>それは何十、何百MB以上消費するアイデアなのでしょうか?
たぶんそこまでは無駄な消費ではないかと・・・

フィールドマップやダンジョン、建物内のマップとは別に
実際に描画するための配列を作ってあげて、
マップの切り替えが生じたとき、その描画するための配列に
マップデータを入れ込んであげればいいのでは?
と勝手に思い込んだので^^;

なので、最大のマップの大きさに合わせてしまうので、
建物内のようなそんなに大きくはないものにとっては無駄が多くなってしまうのでは
と思ったんです。

こういうゲームでのメモリの使用量も分からなかったので、
できるだけメモリの消費量を抑えれたらと考えていましたので、
マップの切り替え処理のアイデアを教えていただきに来ました。

メモリの消費量が少ないにこしたことはないと思いますが・・・


ちなみに、配列データを入れ込む(コピー)にはmemcpyを使うんでしょうか?

Justy

Re:マップの切り替え処理

#14

投稿記事 by Justy » 16年前


>マップの切り替えが生じたとき、その描画するための配列
>建物内のようなそんなに大きくはないものにとっては無駄が多くなってしまうのでは
>と思ったんです

 あー、なるほど。
 関数にマップの情報を引き渡さずに処理するなら、その方が楽ですね。

 無駄といえば無駄ですが、数あるマップのうち最大のマップ分のサイズが
1個増えたくらい(1000x1000*sizeof(int) = 3.8MBくらい?)なら
たいしたことはないでしょう。
(どっちかというと、全てのマップがメモリに常駐している方がよほど……)

 どうしても気になるなら、can_or_cannot関数などで参照するマップデータは
配列ではなく、適切なサイズ分 mallocしたポインタにしてコピーすればいいかと。



>配列データを入れ込む(コピー)にはmemcpyを使うんでしょうか

 ただの intの配列なら、それで構いません

s-rush

Re:マップの切り替え処理

#15

投稿記事 by s-rush » 16年前

>適切なサイズ分 mallocしたポインタにしてコピーすればいいかと
ちょうどmallocは大学にて勉強中なので、
ちゃんと理解するためにもこの方法で頑張ってみたいと思います。

>ただの intの配列なら、それで構いません
intというよりもshortとcharの2つの(2次元)配列を使用しているのですが、
char型の配列は大丈夫なんでしょうか?

Justy

Re:マップの切り替え処理

#16

投稿記事 by Justy » 16年前


>intというよりもshortとcharの2つの(2次元)配列を使用しているのですが、
>char型の配列は大丈夫なんでしょうか?

 コピー時のサイズを間違えなければ、大丈夫です。

s-rush

Re:マップの切り替え処理

#17

投稿記事 by s-rush » 16年前

Justyさん、kazuoniさん、dicさん、
ご回答ありがとうございました。


無駄の多いプログラムですが、何とか完成することができました。
不慣れなことをやっているので、またお聞きするかもしれませんが、
その時はまたよろしくお願いします。


いろいろと調べて見て思ったのですが、RPGのプログラミングを紹介しているサイトって
あまり見かけないですよね?
シューティングゲームならよく見かけるのですが・・・

kazuoni

Re:マップの切り替え処理

#18

投稿記事 by kazuoni » 16年前

自分の作品が出来上がったら、arrayさんのように、
支館RPG版を作ろうかと思っていたのですが、
最近はC++でプログラミングをしようと計画中なんで
ちょっと支えられそうにない気が・・・。。
C++でよいなら考えますが。。

・・・まずC++を自由に扱えるようになってからの話ですけど^^;

Justy

Re:マップの切り替え処理

#19

投稿記事 by Justy » 16年前


>いろいろと調べて見て思ったのですが、RPGのプログラミングを紹介しているサイトって
>あまり見かけないですよね?
>シューティングゲームならよく見かけるのですが・

 STGは作りやすいんですよね。
 ざっくり言ってしまえば、プレイヤー置いて敵置いて弾出してあたり判定つけたら
大筋は終わりです。

 しかし、RPGだとシステムとして作らなければならない部分が多く、
そんな簡単にはいかないわけで。

 単純に考えても、フィールドパート、バトルパートと2つの大きなパートがあって、
フィールド側には移動、アイテム管理、シナリオ・イベント(時系列進行管理)、
街・ダンジョンなどのマップ、ギミック、NPC制御、成長、ショップ、エンカウント、
各種エフェクトなどがあり、バトルの方もフィールドほどではないかもしれませんが
似たような状態です。

 話がややこしくなるのが、それらの要素が密接に絡み合っていることで、
特にシナリオ・イベント……時系列にそった進行管理は、様々なパートに影響を及ぼします。

 データもコード量も結構な量になりがちなので、それらをサポートする為に
何種類ものツールが別途必要になるでしょう。


 とまぁ、ここまで本格的なものはともかく、要素を絞ってピンポイントで説明していけば
講座を作ることもできるのかなとは思いますが、もし龍神録の館のように
コンセプトを確かにした上で、ユーザーが拡張できる余地をいれる、とかやり始めると……。

 要するに RPGのプログラムを紹介するのは大変だ、ってことですね。

s-rush

Re:マップの切り替え処理

#20

投稿記事 by s-rush » 16年前

>>kazuoniさん
私もC++の勉強をしようかどうか悩んでます^^;
でも、C++でのプログラミングは何のメリットがあるのかわからないんですが・・・
やっぱりクラスやオブジェクト指向があるのが魅力的なんですかね?

>>Justyさん
おっしゃる通りイベントや移動、バトルといったシステム管理が難しいです。
特に、イベントの処理をどうすればいいかいろいろと考えています。
(今はマップの切り替え処理をしていますが)

いろいろ試行錯誤を重ねて頑張っていきたいと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る