1

取り組んでいるゲームがあります。テキストベースのRPGアドベンチャーゲームです。単純なテキスト コマンドを使用して、プレイヤーが世界をナビゲートできるようにしたいと考えています。世界が「地域」または配列に分割されるように設定しました。各領域は、カスタム データ型 Location であり、2 次元配列で構成されます。プレイヤーの位置を追跡するために 2 つの変数を使用します。これは、実際には「地域」グリッド上のスポット位置の 2 つのインデックス値です。プレーヤーが「北」、「南」、「東」、「西」などの方向コマンドを入力すると、これらの値が増減してプレーヤーが「移動」します。移行ゾーンに到達すると、別の「地域」に移動します。私はすべての地域を保持する配列を持つことができると考えていました。移行ゾーンは、マスター配列のインデックスを上げたり下げたりして、次のゾーンに「移行」するだけです。もちろん、トランジション スペースには、次のリージョンのグリッド上でプレイヤーが最終的に到達する場所を格納する値を持たせます。この「マスター配列」を作成して領域配列を保持する方法を考えていました。私が十分に説明していないことがあるかどうか尋ねてください。前もって感謝します。

struct Location
{
    int type, destX, destY;
    // 1 = battlefield
    //  areas where random encounters will at some future date occur
    // 2 = town
    //  areas where hopefully the foolhardy adventurer will be able to speak
    // to merchants and towns folk
    // 3 = dungeon
    //  areas with long travel times and the promise of an end boss
    //  but more importantly really awesome loot
    // 4 = transition points
    //
    string name, desc;
};

これが私がそれを想像した方法です。

EgForest

[][][]
[][][]
[][][]
^
トランジション ゾーンは、格納された値 destX と destY を使用して、プレーヤーを次の「地域」の目的地に移動します

SRavine

このスポットは目的地です
V
[][ ][][][][][][]
[][][][][][]
[][]
[][][][]

4

3 に答える 3

0

すべての行列を 1 つの大きな 1 次元配列に減らすことができます。各領域について、配列内のオフセット、および幅と高さを知っています。リージョン内のナビゲーションは単純で、1東/西は +/- region_width、南/北は +/- です。領域の境界を横断するとき、それを防ぐため、または別の領域にジャンプするために、特別なコードが必要です。

世界を一連の行列からグラフに変えることを提案します。グラフ内の場所には、少なくとも 4 つ (場合によってはそれ以上) の出口スロットがあります。スロットには、方向の識別子 (n、s、e、w 以外に、「上」、「下」、「ドア」、「階段」など、任意のものがあります)、暗黙的 (スロットで知られている) のいずれかがあります。 ) または明示的 (スロットと共に格納)、およびこのスロットがつながる場所の識別子。この識別子は、「1 つの大きな 1D 配列」内の位置のインデックスである可能性があります。このアプローチの欠点は、簿記が増えることです。利点は、自分の世界をより自由に作成できることです。グラフは特別な場合に輝きます。出口が 4 つ以上ある場合や、一方通行の通路がある場合や、下水道のように北に行くと思っていたのに西につながっている場合など、気が遠くなるような場所がある場合もあります。

于 2012-07-26T09:33:21.013 に答える
0

質問の見出しに関しては、これは C++ で 2 次元配列の 1 次元配列を作成することです。

std::vector<std::vector<std::vector<Entity>>> v;

これは、各サブ配列が互いに独立したサイズを持つことができる多次元です。

C++ にも固定サイズの配列 (1 次元も) があることに注意してください。

std::array<std::array<std::array<int,16>,16,16>> 
         array_16_of_array_16_of_array_16_of_int;

一般に、直接配列よりも標準コンテナーを優先します。これにより、アルゴリズム (algorithmヘッダーなど) とヘルパー メソッド ( .size()) の世界が開かれます。

残念ながら、C++ には組み込みの多次元コンテナーはありませんが、一部のライブラリーはそれらを提供しており、独自に作成することもできます。基本的な実装は次のようになります。

template <typename T>
class surface {
public:
    typedef size_t size_type;

    surface(size_type w, size_type h) : width_(w), height_(h), data_(w*h) {}

    size_type width()  const { return width_;  }
    size_type height() const { return height_; }
    size_type size()   const { return width_*height_; }

    // These are for when you need to loop over all elements
    // without interest in coordinates.
    T  operator[] (size_type i) const { return data_[i]; }
    T& operator[] (size_type i)       { return data_[i]; }

    T  operator() (size_type x, size_type y) const { return data_[y*width_+x]; }
    T& operator() (size_type x, size_type y)       { return data_[y*width_+x]; }

    T at(size_type i) const {
        if (i>=size()) throw std::out_of_range(....);
        return (*this)[i];
    }
    T& at(size_type i) {
        if (i>=size()) throw std::out_of_range(....);
        return (*this)[i];
    }
    T at(size_type x, size_type y) const {
        if (x>=width_ || y>=height_) throw std::out_of_range(....);
        return (*this)(x,y);
    }
    T& at(size_type x, size_type y) {
        if (x>=width_ || y>=height_) throw std::out_of_range(....);
        return (*this)(x,y);
    }

private:
    size_type width_, height_;
    std::vector<T> data_;
};

...

surface<Foo> x(256,256);

x(16,12) = Foo();
x[16+12*256] = Foo();

配列のサイズとアクセス順序に応じて、他のインデクサー (Morton/Z-Order インデックスなど) を使用できます。

template <typename T, typename Indexer=LinearIndexer>
...
    T  operator() (size_type x, size_type y) const { return data_[Indexer()(x,y)]; }

...

surface<int, Morton> foo(102400, 102400);

また、コンテナーをテンプレート化して、ディスクから/へのジャストインタイム ロード/保存が可能なコンテナーなどの特殊なケースを考慮に入れることもできます。

于 2012-07-26T08:18:44.970 に答える
0

3次元配列が答えです。

int world[4][5][6];

4 は領域の量、5 と 6 は 2D 配列です。領域に可変サイズが必要な場合は、ポインタを使用して必要な量を割り当てます。

于 2012-07-26T08:18:57.997 に答える