HSP初心者が<ゆうなま>っぽいゲームを作る

■ このスレッドは過去ログ倉庫に格納されています
2012/04/28(土) 10:37:31.70ID:4Teh0eDo
HSP初心者の俺がゆうなまっぽいゲームを作ろうと思う

魔物をどうやって生み出すかは考え中
2013/10/05(土) 16:31:01.60ID:pQSHmq99
さて、ゲームの概要と基本的な流れについては、これぐらいにして、
次の段階として、ゲームシステムの基礎部分の検討に移りたいと思います。

手始めに、ゲームの主要な舞台となる地下迷路のマップデータの持ち方を
考えてみます。
既に述べた通り、地下迷路には最初から散らしてある養分や、ゲームが進むと
散らされる魔分を含む土で充填されており、プレイヤーがつるはしで掘れるように
なっています。この仕様から単純に、
int youbun[Width][Height];
int mabun[Width][Height];
bool digged[Width][Height];
のような感じの2次元配列が必要であると考えられます。
2013/10/07(月) 09:54:38.05ID:kL3YAyNm
期待age
56名前は開発中のものです。
垢版 |
2013/10/07(月) 09:56:11.85ID:bkgfHQWg
晒しage
2013/10/07(月) 10:14:33.68ID:OihFMSOT
kakiage
2013/10/07(月) 10:43:38.28ID:HiWWBNmC
からあげ
2013/10/07(月) 15:34:19.34ID:OihFMSOT
蛸age
2013/10/07(月) 23:10:51.21ID:QVbcD2sp
なまを作ると言ってるのにどうして揚げたがるんだ
2013/10/08(火) 04:19:56.29ID:iXH+/mAO
だって生を授かるには、生で「大切なもの」を a g e なきゃいけない
2013/10/16(水) 22:58:34.93ID:CLPttDcX
>>53のつづき)

掘削可能であることが確認できたら、そのマスを掘削済み状態に更新します。
それはつまり、depth[x][y]を-1以外の値にするという意味ですが、具体的にいくつにするかというと、
「周囲の掘削済みマスのdepth値に1を足したもの」を入れていきます。

プログラムで書く場合は、例えば以下のような書き方ができます。
void dig(int x,int y){
  int min=Width*Height;
  int d;
  d=depth[x-1][y]; if(d!=-1 && d<min) min=d;
  d=depth[x+1][y]; if(d!=-1 && d<min) min=d;
  d=depth[x][y-1]; if(d!=-1 && d<min) min=d;
  d=depth[x][y+1]; if(d!=-1 && d<min) min=d;
  depth[x][y]=min+1;
}
2013/10/20(日) 06:40:55.90ID:0tYNwsQx
その一方で、diggedフラグについては、例えばyoubunかmabunの想定外の値(例えば255)を
マジックナンバーとすることで、独立の配列を持つことを省略する方法もあります。

例えば、掘削後のマスのyoubunを255とするなら、
bool isDigged(int x,int y){
return youbun[x][y]==255;
}
のような書き方が可能です。

この応用で、ちょっと工夫を凝らすため、bool型ではなくshort型の2次元配列を
持つ方法を提案します。変数名はdepthとし、未掘削マジックナンバーを -1とすると、

short depth[Width][Height];
bool isDigged(int x,int y){
return depth[x][y]!=-1;
}

のような実装になります。depth配列の全要素をゲーム開始時に-1で初期化しますが、
勇者の侵入口のみ0にしておきます。

なぜこのようにするかは、この後で説明します。
2013/10/20(日) 21:52:54.39ID:khuaVB1t
>>63
>>52
2013/10/28(月) 21:36:05.34ID:vuaiF4qS
(>>62のつづき)
このようなルールでdepth配列を構築すると、掘削済みの任意の地点から地上に至るまでの
比較的上りやすい経路を簡単に一意に探すことができるようになります。
参照しているマス周囲の掘削済みマスのうち、
depth値の一番小さいほうへ繰り返し移動すればよいのです。

ただし、この方法で得られるルートは必ずしも最短にはなりません。
典型的な例外としては、枝分かれさせた2本の迷路が奥のほうで貫通し、
再び合流したときに発生します。

この問題を解決するには、掘削メソッドにさらに一工夫加えます。
2013/10/28(月) 21:38:19.18ID:vuaiF4qS
繰り返しになりますが、depth値の配列は、
「周囲4方向の掘削済みセルのdepth値の最小値に1を加えたもの」
というルールで統一しようとしています。

貫通するように穴を掘ったとき、最後に掘ったところのdepth値は
上の処理によって適切な値に設定されることが期待できます。

問題が発生するのは、そのセルに隣接するセルのうち、
今掘って設定したdepth値よりも大きい値を持つセルです。
少なくともこの隣接セルについては、今掘ったところのdepth値+1になるはずです。

そこで、そのように更新してやると、今度はその隣接セルのさらに周囲の
セルのうち、より大きいdepth値のセルが……、という具合に問題が波及します。
2013/11/05(火) 21:54:19.01ID:X4wPsGV1
こういう問題を処理するときには、再帰的アルゴリズムというのを使うとうまくいきます。

注目しているセルのdepth値が、隣接していて更新されたセルのdepth値よりも大きいとき、
そのセルのdepth値は、隣接depth値に1を加えたものに更新しますが、
それに引き続き、注目したセルに隣接するセルに対して、更新後のdepth値を通知します。
void Cmapdata::Rdig(int x,int y,short min){
  if(isInside(x,y) && isDigged(x,y) && depth[x][y]>min){
    depth[x][y]= ++min;
    Rdig(x-1,y,min);
    Rdig(x+1,y,min);
    Rdig(x,y-1,min);
    Rdig(x,y+1,min);
  }
}

未掘削であったり、通知されたdepth値よりもともと小さいセルでは、値の更新もされませんし、
再帰呼び出しも行われませんので、影響範囲だけ更新したら、このアルゴリズムは完結します。
なおこの関数は、上記のdig関数の最後に(掘削セルのdepth値をセットしてから)呼び出して使います。
2014/06/24(火) 09:50:46.15ID:JIvkZz2v
『俺は屍をこえてゆく』が面白かった。

ファーストプレイのとき、おみくじで、ショップで売ってる
一番いい武器(10万円ぐらいするやつ)を引き当てて、
無双っぽい状況だったんだけど、別のデータを上書きしちゃった><
69名前は開発中のものです。
垢版 |
2017/01/31(火) 21:05:30.44ID:qOnOHCqG
age
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況