Rumah  >  Artikel  >  Java  >  Bagaimanakah saya boleh mengubah suai algoritma raycasting di Jawa untuk mencipta dinding dengan ketinggian yang berbeza dalam "maze tingkap"?

Bagaimanakah saya boleh mengubah suai algoritma raycasting di Jawa untuk mencipta dinding dengan ketinggian yang berbeza dalam "maze tingkap"?

DDD
DDDasal
2024-11-06 16:19:02673semak imbas

How can I modify the raycasting algorithm in Java to create walls of different heights in a

Raycasting dengan saiz ketinggian yang berbeza

Saya mempunyai projek java yang membuat "maze tingkap" dan menggunakan algoritma tuangan sinar. Berikut ialah tangkapan skrin:

seperti yang anda lihat semua dinding mempunyai saiz ketinggian yang sama. Saya ingin melakukan perkara yang sama tetapi dengan saiz ketinggian yang berbeza

private void castRay(int xOnScreen,double sudut,double direction) {

R rx = castRayInX(angle,direction);
R ry = castRayInY(angle,direction);
// In case of out-of-space rays
if (rx.getDistance()==Double.MAX_VALUE && ry.getDistance()==Double.MAX_VALUE) {
    graphics.setColor(BACKGROUND);
    graphics.drawLine(xOnScreen,0,xOnScreen,this.image.getHeight());
    return;
}
double distance = rx.getDistance();
double normal = rx.getNormal();
Color c = rx.getColor();
double coef = Math.cos((angle+direction+Math.PI)-normal);
Plot collision = rx.getPlot();

if (ry.getDistance()<rx.getDistance()) {
    distance = ry.getDistance();
    normal = ry.getNormal();
    c = ry.getColor();
    coef = Math.cos((angle+direction+Math.PI)-normal);
    collision = ry.getPlot();
}

coef = Math.abs(coef);
int factor = map.length*SQUARE_SIZE;
double d = (double)(distance+factor)/factor;
coef *= 1/(d*d);
Color c2 = new Color((int)(c.getRed()*coef),(int)(c.getGreen()*coef),(int)(c.getBlue()*coef));
graphics.setColor(c2);

// graphics.setColor(c); // tiada pencahayaan

distance *= Math.cos(angle); // lens correction
int h = (int)(this.screenDistance/distance*WALL_HEIGHT); // perspective height
int vh = this.image.getHeight();
graphics.drawLine(xOnScreen,(vh-h)/2,xOnScreen,(vh+h)/2);
drawEye(direction,collision);

}

pribadi R castRayInX(double angleRay,double direction) {

double angle = angleRay+direction;
double x1 = eye.getX()+SQUARE_SIZE*Math.cos(angle);
double y1 = eye.getY()+SQUARE_SIZE*Math.sin(angle);
double slope = (y1-eye.getY())/(x1-eye.getX());
if (Math.cos(angle)==0) {
    if (Math.sin(angle)>0)
        return new R(Double.MAX_VALUE,3*Math.PI/2,BACKGROUND,null);
    else
        return new R(Double.MAX_VALUE,Math.PI/2,BACKGROUND,null);
}
if (Math.cos(angle)>0) {
    int firstX = ((eye.getX()/SQUARE_SIZE)+1)*SQUARE_SIZE;
    R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
    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);
        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();
            return new R(Math.sqrt(DX*DX+DY*DY),Math.PI,c,new Plot((int)x,(int)y, WALL_HEIGHT));
        }
    }
    return r;
} else {
    int firstX = ((eye.getX()/SQUARE_SIZE))*SQUARE_SIZE;
    R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
    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);
        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();
            return new R(Math.sqrt(DX*DX+DY*DY),0,c,new Plot((int)x,(int)y, WALL_HEIGHT));
        }
    }
    return r;           
}

}
private R castRayInY(double angleRay ,dua arah) {
// System.out.println("cast ray 2 Y " angleRay " " arah);

double angle = angleRay+direction;
double x1 = eye.getX()+SQUARE_SIZE*Math.cos(angle);
double y1 = eye.getY()+SQUARE_SIZE*Math.sin(angle);

// System.out.println(mata " " x1 " " y1);

double slope = (y1-eye.getY())/(x1-eye.getX());
if (Math.sin(angle)==0) {
    if (Math.cos(angle)>0)
        return new R(Double.MAX_VALUE,Math.PI,BACKGROUND,null);
    else
        return new R(Double.MAX_VALUE,0,BACKGROUND,null);
}
if (Math.sin(angle)>0) {
    int firstY = ((eye.getY()/SQUARE_SIZE)+1)*SQUARE_SIZE;
    R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
    for (int y = firstY; y<map.length*SQUARE_SIZE; y += SQUARE_SIZE) {
        int x = (int)((y-eye.getY())/slope)+eye.getX();
        if (isOutside(x,y,Color.CYAN,this.showRayCastingY)) break;
        Color c = colorAt(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) {
            double DX = x-eye.getX();
            int DY = y-eye.getY();
            return new R(Math.sqrt(DX*DX+DY*DY),3*Math.PI/2,c,new Plot((int)x,(int)y, WALL_HEIGHT));
            }
        }
        return r;
    } else {
        int firstY = ((eye.getY()/SQUARE_SIZE))*SQUARE_SIZE;
        R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null);
        for (int y = firstY; y>=0; y -= SQUARE_SIZE) {
            int x = (int)((y-eye.getY())/slope)+eye.getX();
            if (isOutside(x,y,Color.CYAN,this.showRayCastingY)) break;
            Color c = colorAt(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) {
                double DX = x-eye.getX();
                int DY = y-eye.getY();
                return new R(Math.sqrt(DX*DX+DY*DY),Math.PI/2,c,new Plot((int)x,(int)y, WALL_HEIGHT));
            }
        }
        return r;           
    }
}

Rclass saya mempunyai Plot (x, y, z) buat masa ini saya gunakan WALL_HEIGHT warna, jarak dan normal untuk cahaya. Buat masa ini ini berfungsi tetapi saya ingin menambah

yang baharu

Atas ialah kandungan terperinci Bagaimanakah saya boleh mengubah suai algoritma raycasting di Jawa untuk mencipta dinding dengan ketinggian yang berbeza dalam "maze tingkap"?. 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