1

説明

やあみんな、

わかりましたので、私は過去数日間これを理解しようとしてきましたが、真剣に何も残っていません。なぜ私はここにいるのですか.

私は 2D ゲームを作成する初期段階にあります。タイルのグリッドを表示する開発者モード用の「インベントリ」を作成しました (画像の下部に見られるように)。

これらのタイルをマップ グリッドに配置すると、後でマップをロードするためにテキスト ファイルに char として保存されます。

すべてが正常に機能します。ただし、他のパス タイル (青い枠線) に囲まれているときにマップ上にパス タイル (赤い枠線) を配置すると、正しい側面のタイルに変更されるようにしたいと思います。

これが私のTilemap.javaです。

 public class TileMap {

private Tile[][] tiles;

public TileMap(int width, int height) {
    tiles = new Tile[width][height];
}

public int getWidth() {
    return tiles.length;
}

public int getHeight() {
    return tiles[0].length;
}

public Tile getTile(int x, int y) {
    if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
        return new VoidTile();
    } else {
        return tiles[x][y];
    }
}

public void setTile(int x, int y, Tile tile) {
    if (x >= 0 && y >= 0) {
        tiles[x][y] = tile;
    }
}

}

わかりましたので、メイン ゲーム クラスには TileMap マップがあります。

すぐに配置されるタイルの上下左右のタイルをそのようにチェックして、 mouseClicked(MouseEvent e) メソッドに配置するときにタイルを更新しようとしています。

    public void mouseClicked(MouseEvent e) {
    Inventory.click(e);

    if (e.getButton() == 1) {
        tempTile = Inventory.getSelectedTile();
        System.out.println("Selected Tile is " + tempTile);
    } else if (e.getButton() == 3) {
        
        boolean u = map.getTile(mouseGridX, mouseGridY - 1).connectsToPath;
        boolean d = map.getTile(mouseGridX, mouseGridY + 1).connectsToPath;
        boolean l = map.getTile(mouseGridX - 1, mouseGridY).connectsToPath;
        boolean r = map.getTile(mouseGridX + 1, mouseGridY).connectsToPath;
        boolean ul = map.getTile(mouseGridX - 1, mouseGridY - 1).connectsToPath;
        boolean ur = map.getTile(mouseGridX + 1, mouseGridY - 1).connectsToPath;   
        boolean dl = map.getTile(mouseGridX - 1, mouseGridY + 1).connectsToPath; 
        boolean dr = map.getTile(mouseGridX + 1, mouseGridY + 1).connectsToPath;   
             
                    if (!u && !l && !d && !r) {
                       map.setTile(mouseGridX, mouseGridY new PathTile(5));
                    }
            }
  }

これは、グリッド ベースのスプライト シートを使用する PathTile.java コンストラクターです。getSprite(GridX,GridY)

    public PathTile(int tile) {
    this.tile = tile;
    connectsToPath = true;
    
    switch (tile) {
    case 1:
        this.image = Sprite.getSprite(1, 1);
        break;
    case 2:
        this.image = Sprite.getSprite(2, 1);
        break;
    case 3:
        this.image = Sprite.getSprite(3, 1);
        break;
    case 4:
        this.image = Sprite.getSprite(1, 2);
        break;
    case 5:
        this.image = Sprite.getSprite(2, 2);
        break;
    case 6:
        this.image = Sprite.getSprite(3, 2);
        break;
    case 7:
        this.image = Sprite.getSprite(1, 3);
        break;
    case 8:
        this.image = Sprite.getSprite(2, 3);
        break;
    case 9:
        this.image = Sprite.getSprite(3, 3);
        break;
    case 10:
        this.image = Sprite.getSprite(4, 2);
        break;
    case 11:
        this.image = Sprite.getSprite(5, 2);
        break;
    case 12:
        this.image = Sprite.getSprite(4, 3);
        break;
    case 13:
        this.image = Sprite.getSprite(5, 3);
        break;
    }
}

notchのLudum Dare Game「MiniCraft」をベースにしています。ただし、メソッドでそれを実装する効率的な方法を理解できないようです。

私の計算が正しければ (おそらく正しくないでしょう)、65,535 の結果が考えられるということではないでしょうか? (4 * 4 * 4 * 4 * 4 * 4 * 4 * 4)??

私はプログラミングが大好きですが、それだけではありません笑...

誰かがアルゴリズムを理解するのを手伝ってくれますか、少なくとも正しい方向に向けてくれますか?

それは本当に大きな質問だと思いますが、すべての助けをいただければ幸いです!

セーブ。

編集:これはノッチがこの問題を解決する方法です。彼は私のようなグリッド スプライト シートを使用します。ただし、意図したスプライトを取得するために、x 座標と y 座標があり、これに 32 (グリッド ボックスのサイズ) を掛けます。

    boolean u = !level.getTile(x, y - 1).connectsToGrass;
    boolean d = !level.getTile(x, y + 1).connectsToGrass;
    boolean l = !level.getTile(x - 1, y).connectsToGrass;
    boolean r = !level.getTile(x + 1, y).connectsToGrass;

    if (!u && !l) {
        screen.render(x * 16 + 0, y * 16 + 0, 0, col, 0);
    } else
        screen.render(x * 16 + 0, y * 16 + 0, (l ? 11 : 12) + (u ? 0 : 1) * 32, transitionColor, 0);

    if (!u && !r) {
        screen.render(x * 16 + 8, y * 16 + 0, 1, col, 0);
    } else
        screen.render(x * 16 + 8, y * 16 + 0, (r ? 13 : 12) + (u ? 0 : 1) * 32, transitionColor, 0);

    if (!d && !l) {
        screen.render(x * 16 + 0, y * 16 + 8, 2, col, 0);
    } else
        screen.render(x * 16 + 0, y * 16 + 8, (l ? 11 : 12) + (d ? 2 : 1) * 32, transitionColor, 0);
    if (!d && !r) {
        screen.render(x * 16 + 8, y * 16 + 8, 3, col, 0);
    } else
        screen.render(x * 16 + 8, y * 16 + 8, (r ? 13 : 12) + (d ? 2 : 1) * 32, transitionColor, 0);
}

ご覧のとおり、彼は (boolean ? true : false) メソッドを使用して、スプライトに追加する必要な数を受け取ります。

私が抱えている問題は、同様のアルゴリズムを使用して、使用する必要があるスプライトを特定する方法を考え出すことです。

これが私が求めているものです。他の誰かがこの問題をどのように克服したかを見て、私は幸せです.

ありがとう

4

1 に答える 1

4

4 方向の 16 ケースのバージョン (視覚化が容易で、書き出すのがはるかに短い) について回答しますが、アイデアは 8 方向のケースにも適用されます。私が正しく読んでいれば、必要な位置をu、l、d、rに基づいて把握できるように、スプライトをレイアウトする方法を理解したいと考えています。

ここには基本的に 4 ビットの数値があります。各ビットは一方向の接続性に対応します。したがって、スプライトを生成できます。

ULDR 
0000: No connections
0001: Right side connected
0010: Down connected
0011: Down and right connected
0100: Left connected
0101: Left and right connected
0110: Left and down connected
0111: Left, right, and down connected
...
1111: Up, left, down and right all connected.

この順序で、スプライト ストリップ (スプライトの 1 次元ストリップ) を実行できます。Sprite[0] = 0000, Sprite[1] = 0001, .... Sprite[15] = 1111. 次に、スプ​​ライトを取得するには、次を探します。

index = (up ? 0x8 : 0) | (left ? 0x4 : 0) | (down ? 0x2 : 0) | (right ? 0x1 : 0); 
s = sprite.getSprite(index, 0); 

さて、何らかの理由で 2D スプライトが必要な場合 (たとえば、2^nx 2^n などのサイズにする必要があるテクスチャとして行われている場合 - 私はグラフィックスの専門家ではありませんが、わかりません)、これを行うことができます。お気に入り:

x_index = (up ? 0x2 : 0) | (left ? 0x1 : 0);
y_index = (right ? 0x2 : 0) | (down ? 0x1 :0); 
s = sprite.getSprite(x_index, y_index); 

どちらの場合も、パターンに合わせてスプライトを配置するだけです。私は最初のもののために上記の順序をリストしました. 2 次元のスプライトの場合、基本的に対応するスプライト レイアウトがあります。

   DR
UL      00   01   10   11 
   00 0000 0001 0010 0011
   01 0100 0101 0110 0111
   10 1000 1001 1010 1011 
   11 1100 1101 1110 1111 

ここでも、ビットはそれぞれ ULDR への接続に対応しています。上記のようにスプライトをレイアウトし、上記のアルゴリズムを使用すると、動作するはずです (X と Y を台無しにして反転させない限り、私は時々そうします :)

ここで、8 次元のケースを使用する場合、4 ではなく 8 ビットであることを除いて、考え方は同じです。

UL U UR LR DL D DR

しかし、すべてを8ビットの数値に拡張するだけの問題です: UUUL LR RDDD 0000 0001 0010 0011 0100 0101 0110 0111 1000 ... LR 0000 0001 0010 . . .

それが理にかなっていることを願っています(そして、私が正しい質問に答えていることを願っています)。

于 2012-12-29T00:50:05.027 に答える