iT邦幫忙

2025 iThome 鐵人賽

DAY 23
1

大家好~ 這裡是鐵匠史密斯
昨日我們已經完成了牆壁的渲染
接下來,我們就直接完成角色的前進與後退

前進? 後退? 都是依靠 fPlayerA

前陣子,我們使用 QE 按鍵完成視角的轉動,也就是改變 fPlayerA 的值
fPlayerA決定了玩家的方向,玩家的前進、後退、轉動的動作都由該變數決定
還記得下面這張圖嗎?
https://ithelp.ithome.com.tw/upload/images/20250823/20157653Fpdg1asbw8.png
我們在探討 fAOV 中每一道光線時,可以知道每一道光線的角度 fRayAngle
光線的角度,也代表了**光線的方向,也就是單位向量,其: **

  • 水平分量 x = fEyeX = sinf(fRayAngle)
  • 垂直分量 y = fEyeY = cosf(fRayAngle)

既然我們可以求出光線的單位向量,那玩家方向的單位向量也是可以以同樣的概念來計算,
上圖:
https://ithelp.ithome.com.tw/upload/images/20250823/201576532GIPtbnBsw.png
在計算機圖學的座標系中,我們假設玩家向逆時針轉動了 30 [degree],可以得知:
玩家的單位向量中:

  • 水平分量 x = sinf(fPlayerA)
  • 垂直分量 y = cosf(fPlayerA)
    代表了這時候的玩家是朝著 +x+y 前進
    反之亦然,如果是後退的話,就是大小相同、方向相反
  • 水平分量 x = -sinf(fPlayerA)
  • 垂直分量 y = -cosf(fPlayerA)
    代表了這時候的玩家是朝著 -x-y也就是單位向量的反方向後退
    簡單的位移公式 x' = x + △x,我們就可以改變玩家的位置了:
if (GetAsyncKeyState((unsigned short)'W') & 0x8000)
    fPlayerX += sinf(fPlayerA) * fElaspedTime * 5;
    fPlayerY += cosf(fPlayerA) * fElaspedTime * 5;

if (GetAsyncKeyState((unsigned short)'S') & 0x8000)
    fPlayerX -= sinf(fPlayerA) * fElaspedTime * 5;
    fPlayerY -= cosf(fPlayerA) * fElaspedTime * 5;

與轉動玩家方向的概念相同,都是使用 GetAsyncKeyState() 幫我們完成偵測按鍵的功能,
前進/後退是使用 W/S 來進行操控,
當然,也可以在後面乘上常數 5 ,來使玩家的移動速度加快(依需求調整)~
這樣的話,就可以使玩家前進/後退啦~

https://ithelp.ithome.com.tw/upload/images/20250823/20157653K3Fjpofsbe.png

今日總結

  • 前進/後退/轉動 都是由 fPlayerA 玩家的方向來決定
  • 參考光在計算機圖學座標系的方向計算方式,來計算玩家的方向
  • W/S 進行前進/後退的動作

到這裡,我們的角色已經可以「原地轉頭」+「向前走」+「往後退」了,
明日周末來第二次總結一下吧~ 鐵人賽快要完成了~
但是這個專案還會一直優化下去,
一起走下去~


上一篇
Day22 | Ray Casting: 渲染牆壁 - Part 2
下一篇
Day 24 | Ray Casting 中場總結:從光線到角色的移動
系列文
用 C++ 實作簡易第一人稱視角遊戲:從入門到理解 Ray Casting30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言