Maison  >  Article  >  Java  >  Comment puis-je ajouter différentes tailles de hauteur aux murs dans un projet Java « labyrinthe de fenêtres » à l'aide de l'algorithme de lancer de rayons ?

Comment puis-je ajouter différentes tailles de hauteur aux murs dans un projet Java « labyrinthe de fenêtres » à l'aide de l'algorithme de lancer de rayons ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-06 01:32:02134parcourir

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

Casting de rayons avec différentes tailles de hauteur

Problème

Dans un projet Java "labyrinthe de fenêtres" utilisant l'algorithme de lancer de rayons, tous les murs ont le même taille. Le but est de créer une version avec différentes tailles de hauteur.

Solution

1. Ajouter des informations sur la hauteur à la carte :

Ajoutez une troisième valeur à chaque cellule de la carte pour représenter la hauteur du mur dans cette cellule. Par exemple, pmap[y][x] = (couleur, distance, hauteur).

2. Mettre à jour l'algorithme de diffusion de rayons :

  • Vérifier la valeur Z pour la détection des coups : Lors de la vérification des coups, incluez les valeurs de hauteur pour déterminer si le rayon a heurté un mur de la bonne hauteur.
  • Calculer la hauteur projetée : Calculez la hauteur projetée du mur en fonction de la distance entre le rayon et le point de frappe et l'angle de vue.
  • Ajuster le rendu :

    • Rendu à hauteur variable : Utilisez la hauteur projetée pour ajuster le rendu de la ligne de balayage du mur, créant ainsi un effet 3D.
    • Rendu du dessus : Vérifiez les impacts sur les faces arrière des murs et restituez la couleur du dessus de la dernière coordonnée y rendue à la coordonnée actuelle.

3. Considérez la saisie avec la molette de la souris :

Autoriser les utilisateurs à ajuster la hauteur des murs (en mode éditeur de carte) à l'aide de la molette de la souris.

Extraits de code détaillés : Ici est un extrait de la fonction castRayInX révisée :

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

Notes supplémentaires :

  • Mettez à jour la fonction castRayInY de la même manière.
  • Pour détecter les faces arrière des murs, ajoutez simplement une autre condition de pente :

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

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn