ホームページ  >  記事  >  Java  >  レイ キャスティング アルゴリズムを使用して、Java の「窓の迷路」プロジェクトの壁に異なる高さのサイズを追加するにはどうすればよいですか?

レイ キャスティング アルゴリズムを使用して、Java の「窓の迷路」プロジェクトの壁に異なる高さのサイズを追加するにはどうすればよいですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-06 01:32:02142ブラウズ

How can I add different height sizes to walls in a Java

高さサイズが異なるレイ キャスティング

問題

レイ キャスティング アルゴリズムを使用した Java の「窓の迷路」プロジェクトでは、すべての壁に同じ高さのサイズ。目標は、高さのサイズが異なるバージョンを作成することです。

解決策

1.マップに高さ情報を追加します:

マップ内の各セルに 3 番目の値を追加して、そのセルの壁の高さを表します。たとえば、pmap[y][x] = (色、距離、高さ).

2。レイキャスティング アルゴリズムの更新:

  • ヒット検出の Z 値の確認: ヒットをチェックするときに、レイが壁に当たったかどうかを判断するために高さの値を含めます。正しい高さです。
  • 投影高さを計算します: 光線からヒット ポイントまでの距離と視野角に基づいて、壁の投影高さを計算します。
  • レンダリングの調整:

    • 可変高さのレンダリング: 投影された高さを使用して壁のスキャンライン レンダリングを調整し、3D 効果を作成します。
    • 上面レンダリング: 壁の背面のヒットを確認し、最後にレンダリングされた y 座標から現在の y 座標まで上面の色をレンダリングします。

3.マウス ホイール入力を検討してください:

ユーザーがマウス ホイールを使用して壁の高さを (マップ エディター モードで) 調整できるようにします。

詳細なコード スニペット: こここれは、改訂された CastRayInX 関数のスニペットです:

    // Check for hits on front or back wall based on direction
    boolean hit = false;
    Color c = null;
    int z = 0;
    if (slope > 0) {
        int firstX = ((eye.getX() / SQUARE_SIZE) + 1) * SQUARE_SIZE;
        for (int x = firstX; x < map[0].length * SQUARE_SIZE; x += SQUARE_SIZE) {
            int y = (int) (slope * (x - eye.getX()) + eye.getY());
            if (isOutside(x, y, Color.MAGENTA, this.showRayCastingX))
                break;
            c = colorAt(x, y);
            z = heightAt(x, y);
            if (c == null)
                c = colorAt(x, y - 1);
            if (c == null)
                c = colorAt(x - 1, y);
            if (c == null)
                c = colorAt(x - 1, y - 1);
            if (c != null) {
                int DX = x - eye.getX();
                double DY = y - eye.getY();
                hit = true;
                break;
            }
        }
        if (!hit && slope != Double.POSITIVE_INFINITY) // check back wall
            for (int x = firstX; x >= 0; x -= SQUARE_SIZE) {
                int y = (int) (slope * (x - eye.getX()) + eye.getY());
                if (isOutside(x, y, Color.MAGENTA, this.showRayCastingX))
                    break;
                c = colorAt(x, y);
                z = heightAt(x, y);
                if (c == null)
                    c = colorAt(x, y - 1);
                if (c == null)
                    c = colorAt(x - 1, y);
                if (c == null)
                    c = colorAt(x - 1, y - 1);
                if (c != null) {
                    int DX = x - eye.getX();
                    double DY = y - eye.getY();
                    hit = true;
                    break;
                }
            }
    } else {
        int firstX = ((eye.getX() / SQUARE_SIZE)) * SQUARE_SIZE;
        for (int x = firstX; x >= 0; x -= SQUARE_SIZE) {
            int y = (int) (slope * (x - eye.getX()) + eye.getY());
            if (isOutside(x, y, Color.MAGENTA, this.showRayCastingX))
                break;
            Color c = colorAt(x, y);
            int z = heightAt(x, y);
            if (c == null)
                c = colorAt(x, y - 1);
            if (c == null)
                c = colorAt(x - 1, y);
            if (c == null)
                c = colorAt(x - 1, y - 1);
            if (c != null) {
                int DX = x - eye.getX();
                double DY = y - eye.getY();
                hit = true;
                break;
            }
        }
        if (!hit && slope != Double.POSITIVE_INFINITY) // check back wall
            for (int x = firstX; x < map[0].length * SQUARE_SIZE; x += SQUARE_SIZE) {
                int y = (int) (slope * (x - eye.getX()) + eye.getY());
                if (isOutside(x, y, Color.MAGENTA, this.showRayCastingX))
                    break;
                Color c = colorAt(x, y);
                int z = heightAt(x, y);
                if (c == null)
                    c = colorAt(x, y - 1);
                if (c == null)
                    c = colorAt(x - 1, y);
                if (c == null)
                    c = colorAt(x - 1, y - 1);
                if (c != null) {
                    int DX = x - eye.getX();
                    double DY = y - eye.getY();
                    hit = true;
                    break;
                }
            }
    }

    // If hit, compute projected height and adjust rendering
    if (hit) {
        h = (int) (this.screenDistance / distance * z);
        int hw = (int) (this.screenDistance / distance * WALL_HEIGHT); // WALL_HEIGHT value is 300px at default
        int y0 = (hw + vh) / 2;
        int y1 = (vh - h) / 2;
        graphics.drawLine(xOnScreen, y0, xOnScreen, y1);
    }

追加メモ:

  • 同様の方法で CastRayInY 関数を更新します。
  • 壁の背面を検出するには、別の傾斜条件を追加するだけです:

    } else if (slope > 0 && slope < Double.POSITIVE_INFINITY) {...} // back face

    以上がレイ キャスティング アルゴリズムを使用して、Java の「窓の迷路」プロジェクトの壁に異なる高さのサイズを追加するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。