Rumah  >  Artikel  >  Java  >  Bagaimanakah saya boleh menambah saiz ketinggian yang berbeza pada dinding dalam projek "maze tingkap" Java menggunakan algoritma pemutus sinar?

Bagaimanakah saya boleh menambah saiz ketinggian yang berbeza pada dinding dalam projek "maze tingkap" Java menggunakan algoritma pemutus sinar?

Barbara Streisand
Barbara Streisandasal
2024-11-06 01:32:02134semak imbas

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

Bahan Sinar dengan Saiz Ketinggian Berbeza

Masalah

Dalam projek "windows' maze" Java menggunakan algoritma tuangan sinar, semua dinding mempunyai saiz ketinggian yang sama. Matlamatnya ialah untuk mencipta versi dengan saiz ketinggian yang berbeza.

Penyelesaian

1. Tambah Maklumat Ketinggian pada Peta:

Tambahkan nilai ketiga pada setiap sel dalam peta untuk mewakili ketinggian dinding dalam sel itu. Contohnya, pmap[y][x] = (warna, jarak, ketinggian).

2. Kemas kini Algoritma Pancaran Sinar:

  • Semak Nilai Z untuk Pengesanan Hit: Semasa menyemak hentaman, sertakan nilai ketinggian untuk menentukan sama ada sinar itu mengenai dinding ketinggian yang betul.
  • Hitung Unjuran Tinggi: Kira ketinggian unjuran dinding berdasarkan jarak dari sinar ke titik pukulan dan sudut tontonan.
  • Laraskan Rendering:

    • Rendering Ketinggian Boleh Ubah: Gunakan ketinggian yang diunjurkan untuk melaraskan pemaparan garis imbasan untuk dinding, mencipta 3D kesan.
    • Rendering Bahagian Atas: Semak hentaman pada bahagian belakang dinding dan jadikan warna bahagian atas dari koordinat y yang terakhir diberikan kepada yang semasa.

3. Pertimbangkan Input Roda Tetikus:

Benarkan pengguna melaraskan ketinggian dinding (dalam mod editor peta) menggunakan roda tetikus.

Coretan Kod Terperinci: Di sini ialah coretan daripada castRayInX yang disemak semula fungsi:

    // 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);
    }

Nota Tambahan:

  • Kemas kini fungsi castRayInY dengan cara yang sama.
  • Untuk mengesan kembali muka dinding, cuma tambah cerun lain syarat:

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

    Atas ialah kandungan terperinci Bagaimanakah saya boleh menambah saiz ketinggian yang berbeza pada dinding dalam projek "maze tingkap" Java menggunakan algoritma pemutus sinar?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn