Heim  >  Artikel  >  Java  >  Wie kann ich Wänden in einem Java-„Windows-Labyrinth“-Projekt mithilfe des Ray-Casting-Algorithmus unterschiedliche Höhengrößen hinzufügen?

Wie kann ich Wänden in einem Java-„Windows-Labyrinth“-Projekt mithilfe des Ray-Casting-Algorithmus unterschiedliche Höhengrößen hinzufügen?

Barbara Streisand
Barbara StreisandOriginal
2024-11-06 01:32:02134Durchsuche

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

Ray Casting mit unterschiedlicher Höhengröße

Problem

In einem Java-„Windows-Labyrinth“-Projekt, das den Ray-Casting-Algorithmus verwendet, haben alle Wände das gleiche Höhengröße. Ziel ist es, eine Version mit unterschiedlichen Höhengrößen zu erstellen.

Lösung

1. Höheninformationen zur Karte hinzufügen:

Fügen Sie zu jeder Zelle in der Karte einen dritten Wert hinzu, um die Höhe der Wand in dieser Zelle darzustellen. Zum Beispiel pmap[y][x] = (Farbe, Abstand, Höhe).

2. Aktualisieren Sie den Ray-Casting-Algorithmus:

  • Überprüfen Sie den Z-Wert für die Treffererkennung: Beziehen Sie bei der Trefferprüfung die Höhenwerte ein, um festzustellen, ob der Strahl eine Wand getroffen hat die richtige Höhe.
  • Projizierte Höhe berechnen: Berechnen Sie die projizierte Höhe der Wand basierend auf dem Abstand vom Strahl zum Trefferpunkt und zum Betrachtungswinkel.
  • Rendering anpassen:

    • Variable Höhen-Rendering:Verwenden die projizierte Höhe, um das Scanline-Rendering für die Wand anzupassen und so einen 3D-Effekt zu erzeugen.
    • Oberseite Rendern:Überprüfen Sie die Rückseiten der Wände auf Treffer und rendern Sie die Farbe der Oberseite von der zuletzt gerenderten Y-Koordinate zur aktuellen.

3. Erwägen Sie die Mausrad-Eingabe:

Benutzer können die Höhe von Wänden (im Karteneditor-Modus) mithilfe des Mausrads anpassen.

Detaillierte Codeausschnitte: Hier ist ein Ausschnitt aus der überarbeiteten castRayInX-Funktion:

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

Zusätzlich Hinweise:

  • Aktualisieren Sie die castRayInY-Funktion auf ähnliche Weise.
  • Um Rückseiten von Wänden zu erkennen, fügen Sie einfach eine weitere Neigungsbedingung hinzu:

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

    Das obige ist der detaillierte Inhalt vonWie kann ich Wänden in einem Java-„Windows-Labyrinth“-Projekt mithilfe des Ray-Casting-Algorithmus unterschiedliche Höhengrößen hinzufügen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn