iT邦幫忙

2025 iThome 鐵人賽

DAY 21
1

來了~這裡是鐵匠史密斯~
我們既然已經讓玩家可以穩定地在不同的設備下進行方向的旋轉,那接下來我們來讓
牆壁的顏色深淺變得更生動 -> 渲染牆壁!
我們要做的目標如圖(來源為: Wiki-德軍總部3D):
https://ithelp.ithome.com.tw/upload/images/20250821/20157653mvlyOxGtUo.png
由上圖我們可以知道: 玩家離牆壁越遠,牆壁的顏色越深,反之亦然。
我們要做一樣的事情~

使用的渲染字元

目前我們渲染的code為:

// Decide the height of the wall by distance to the wall
int nCeiling = (float)(nScreenHeight / 2.0) - nScreenHeight / ((float)fDistanceToWall);
int nFloor = (float)(nScreenHeight / 2.0) + nScreenHeight / ((float)fDistanceToWall); // nFloor = nScreenHeight - nCeiling;

for (int y = 0; y < nScreenHeight; y++)
{
    if (y < nCeiling) // If the pixel is above the nCeiling -> should be ceiling
    {
        screen[y * nScreenWidth + x] = ' '; // Set to space
    }
    else if (y > nCeiling && y <= nFloor) // If the pixel is between the nCeiling and nFloor -> should be wall
    {
        screen[y * nScreenWidth + x] = '#'; // Set to wall character
    }
    else // If the pixel is below the nFloor -> should be floor
    {
        screen[y * nScreenWidth + x] = ' '; // Set to floor character
    }
}

我們隨著距離 fDistanceToWall 決定牆壁占用 screen 的比例
再來我們還要決定牆壁的顏色深淺
當然,邏輯也由 fDistanceWall 的大小做決定

首先,我們要先決定渲染的素材(字元)是什麼~
來直接看看Reference of Extended ASCII Table for Code page 437 列出的字元
我們直接使用 Light shade, Medium shade, Dark shade 以及 Full Dark shade字元
https://ithelp.ithome.com.tw/upload/images/20250821/20157653Ib2Sr7A2gM.png
點擊任一字元並在該頁點擊charater連結,即可以看到每個字元的詳細資訊:
https://ithelp.ithome.com.tw/upload/images/20250821/20157653hwVdQDnwsT.png
我們可以把UTF-16選項的16進位數字給複製到我們的code內,為什麼呢?
因為我們要使用 short int 整數來表示字元

short nShade = ' ';

並以 fDepth 為基礎,來判斷當下距離 fDistanceToWall 適合渲染成哪一種字元(以 short 整數 nSahde 表示)

if (fDistanceToWall <= fDepth / 4.0f) // Get very close to wall -> will be full-shaded
    nShade = 0x2588;
else if (fDistanceToWall <= fDepth / 3.0f)
    nShade = 0x2593;
else if (fDistanceToWall <= fDepth / 2.0f)
    nShade = 0x2592;
else if (fDistanceToWall <= fDepth) // Get far to wall -> will be light-shaded
    nShade = 0x2591;
else
    nShade = ' '; // So far, far way -> will see nothing

這裡 short 只是「拿來存 Unicode 碼位的整數容器」
後面寫進 wchar_t* screen 時,主控台的寬字元輸出函式會把它當作 UTF‑16 code unit 來顯示。

今日總結

  • 牆壁距離 → 深淺字元
  • Unicode(UTF-16) 配合 short 表示不同字元

原本牆壁都只有使用 # 來表示,
明天我們會把判斷的邏輯放到主程式內,跑跑看是什麼樣子
我們繼續走下去~

Reference

  1. Wiki-德軍總部3D
  2. Reference of Extended ASCII Table for Code page 437

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

尚未有邦友留言

立即登入留言