>  기사  >  Java  >  광선 캐스팅 알고리즘을 사용하여 Java "창문 미로" 프로젝트의 벽에 다양한 높이 크기를 어떻게 추가할 수 있습니까?

광선 캐스팅 알고리즘을 사용하여 Java "창문 미로" 프로젝트의 벽에 다양한 높이 크기를 어떻게 추가할 수 있습니까?

Barbara Streisand
Barbara Streisand원래의
2024-11-06 01:32:02134검색

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

높이 크기가 다른 레이 캐스팅

문제

레이 캐스팅 알고리즘을 사용하는 Java "windows' maze" 프로젝트에서는 모든 벽에 같은 키 크기. 다양한 높이 크기의 버전을 만드는 것이 목표입니다.

해결책

1. 지도에 높이 정보 추가:

지도의 각 셀에 세 번째 값을 추가하여 해당 셀의 벽 높이를 나타냅니다. 예를 들어 pmap[y][x] = (색상, 거리, 높이).

2. 광선 캐스팅 알고리즘 업데이트:

  • 적중 감지를 위한 Z 값 확인: 적중을 확인할 때 높이 값을 포함하여 광선이 벽에 부딪혔는지 확인합니다. 올바른 높이.
  • 투영 높이 계산: 광선에서 히트 포인트까지의 거리와 시야각을 기준으로 벽의 투사 높이를 계산합니다.
  • 렌더링 조정:

    • 가변 높이 렌더링: 투영된 높이를 사용하여 벽의 스캔라인 렌더링을 조정하여 3D 효과를 만듭니다.
    • 상부 렌더링: 벽 뒷면의 히트를 확인하고 마지막으로 렌더링된 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.