iT邦幫忙

2025 iThome 鐵人賽

DAY 12
1

大家好~ 這裡是鐵匠史密斯~
我發覺在世界地圖、方向的定義上,似乎有不一致,混淆的地方
日後挑戰玩30天鐵人賽後,會把不懂的,釐清的事情再回來更新
但是,大致上的方向是沒錯的,我們就繼續走下去吧!

Day 11 介紹了如何解析 screen -> screen 有幾行 -> AOV就要切幾等分
今日,我們來討論光如何前進
我們會分兩步驟解析

奠定基礎

讓我們回憶昨日(Day 10) 的圖:
https://ithelp.ithome.com.tw/upload/images/20250813/20157653bAEiwQGcZg.png
我們從第一道光(AOV最左邊的光)開始解析
我們需要定義:

  • 光與強壁的距離 fDistanceToWall
  • 是否有碰到牆壁 bHitWall
  • 光的單位向量 fEyeX 以及 fEyeY
        
// Track distance from player to the wall
float fDistanceToWall{ 0.0f };
bool bHitWall{ false }; // Whether we hit a wall
// Unit vector of the ray direction so that we can take one step on that direction to see if we hit a wall
float fEyeX{ sinf(fRayAngle) };
float fEyeY{ cosf(fRayAngle) };

簡單來說,光的單位向量,即可用昨日( Day 10 )的出射光角度 fRayAngle 來定義。
以目前的定義來看,光的 x 分量為 sin(fRayAngle)y 分量為 cos(fRayAngle) ,我們用下圖來表示:
https://ithelp.ithome.com.tw/upload/images/20250812/20157653HmEQDNt9UD.png
既然我們所需要的變數都定義好了,那我們可以讓光出發了!

光如何出發?

既然我們知道光的方向(單位向量) (fEyex, fEyeY),那我們可以讓光出發了
因為我們有光的單位向量之 x 分量 fEyeX 以及單位向量之 y 分量 fEyeY
那我們可以讓光沿著方向走 0.1單位,如圖所示:
https://ithelp.ithome.com.tw/upload/images/20250813/20157653XctTTf0B3m.png
簡單來說,光每走一步,我們就要監測它的位置是否碰到牆壁
所以,要先記錄光每走一步的位置

// If we didn't hit the wall, we can take a step in the ray direction
fDistanceToWall += 0.1f;

// because wall's boundaries are at integer coordinates(dot index), so we use intger casting to get the coordinates of the wall
int nTestX{ (int)(fPlayerX + fEyeX * fDistanceToWall) };
int nTestY{ (int)(fPlayerY + fEyeY * fDistanceToWall) };            

光當前的位置 = 光的起始位置 + 位移 = x + △x
https://ithelp.ithome.com.tw/upload/images/20250813/20157653xU5r7zr4yR.png

今日總結

  • 使用 fRayAngle 計算光的單位向量 (fEyeX, fEyeY),決定光的前進方向
  • 光每次前進固定距離(例如 0.1 單位)
  • 每前進一步,就根據新位置檢查是否碰到牆壁

明日我們會繼續探討光如何前進,以及何時停止,也許會分成三天來講
再多走幾步,我們就能看到 Ray Casting 的輪廓成形了。


上一篇
Day 11 | Ray Casting : 從第一道光開始解析
下一篇
Day 13 | Ray Casting : 光如何前進? Part 2
系列文
用 C++ 實作簡易第一人稱視角遊戲:從入門到理解 Ray Casting30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言