치춘짱베리굿나이스
[Rank 4] Cub3D - Raycasting 구현 ② 반복문의 동작 본문
반복문의 동작
주의할 점
- Lodev는 y가 아래에서 위로 증가하는 좌표계를 사용하였는데, 레이캐스팅 구현 시에 이 부분을 신경쓰지 않으면 이동 방향이나 회전 방향이 반대가 된다
- 각 벡터의 용도를 확실히 알고 구현해야 플레이어의 현재 상태에서 어떤 방향 또는 값을 갖는지 명확하게 알고 디버깅할 수 있으므로 코드를 작성하기 전 각 변수의 의미를 확실히 알고 가는 것을 추천함
- 위의 이미지 또한 어떻게 구현하는가에 따라 틀릴 수 있다
1. stepX, stepY 설정
if (rayDirX < 0)
stepX = -1;
else
stepX = 1;
if (rayDirY < 0)
stepY = -1;
else
stepY = 1;
- 현재 광선의 방향에 따라
stepX
와stepY
를 설정한다 - 광선의 방향은
rayDirX
와rayDirY
에 의해 결정된다
2. sideDistX, sideDistY 정해주기
- 증명은 그림의 직각삼각형 닮음비를 이용한 증명을 참고
if (rayDirX < 0)
sideDistX = (posX - mapX) * deltaDistX;
else
sideDistX = (mapX + 1 - posX) * deltaDistX;
}
if (rayDirY < 0)
sideDistY = (posY - mapY) * deltaDistY;
else
sideDistY = (mapY + 1 - posY) * deltaDistY;
}
3. DDA 알고리즘 진행
- 광선을 직선으로 이동시켜 벽을 찾기 위해 사용하는 알고리즘
hit
가 0일 동안 (while (!hit)
) DDA 알고리즘의 과정을 반복하여 벽을 찾아내고 반복문을 중단한다
1. sideDistX와 sideDistY를 비교
if (sideDistX < sideDistY)
{
sideDistX += deltaDistX;
mapX += stepX;
side = WALL_X; // 0
}
else
{
sideDistY += deltaDistY;
mapY += stepY;
side = WALL_Y; // 1
}
- 기본 원리는 매번
sideDistX
와sideDistY
를 비교하여,sideDistX
가 더 작을 경우sideDistX
에deltaDistX
를 더한다mapX
에stepX
를 더한다- x축에 수직인 면 (x면) 에 닿았으므로
side
를 0으로 설정한다
sideDistY
가 더 작을 경우sideDistY
에deltaDistY
를 더한다mapY
에stepY
를 더한다- y축에 수직인 면 (y면) 에 닿았으므로
side
를 1로 설정한다
sideDistX
,sideDistY
를 계산하며 광선이 어떤 벽에 부딪혔는지 구하는 예시이다- 간단하게 설명하면, 다음 x좌표까지 이동했을 때의 광선의 거리와 다음 y좌표까지 이동했을 때의 광선의 거리 중 짧은 것을 선택하여 미리 구한 delta값만큼 더하여 광선을 이동시킨다
2. 구한 좌표 (mapX, mapY) 를 토대로 월드맵 체크
if (mapArr[mapY][mapX] == '1')
hit = 1
hit = 0
pos
(시작점) 부터sideDistX
만큼 이동한 광선과sideDistY
만큼 이동한 광선이 모두 벽과 부딪혔을 경우, 지도의 이차원 배열상 좌표 (mapX
,mapY
) 가 1 (벽) 일 것이므로 이 좌표에 해당하는 벽에 부딪혔다고 판정하고 반복문을 중단한다
'42 > 42s Cursus' 카테고리의 다른 글
[Rank 4] Cub3D - Raycasting 구현 ④ 화면에 벽 그리기 (0) | 2022.04.01 |
---|---|
[Rank 4] Cub3D - Raycasting 구현 ③ 광선 이동거리 계산 및 보정 (0) | 2022.04.01 |
[Rank 4] Cub3D - Raycasting 구현 ① 변수 설명 (0) | 2022.03.31 |
[Rank 4] Cub3D - Raycasting 기초 (2) | 2022.03.31 |
[Rank 4] Cub3D (0) | 2022.03.31 |
Comments