遊戲編程

係電子遊戲製作嘅一部份，指為電子遊戲做軟件工程嘅工作：通常一隻遊戲嘅製作組喺做完設計－度好嗮隻遊戲嘅規則應該係點－之後，就要開始做程式編寫，編制隻遊戲嘅程式，途中用到電腦圖像同人工智能等嘅技術，而大型多人網上遊戲等嘅編程仲會考製作組對網絡編程同數據庫等技術嘅認識。雖然遊戲編程咁專業，但都有啲人為興趣而做遊戲編程，而且仲有成功案例。

一個電子遊戲程式嘅根基係遊戲迴圈：隻遊戲嘅程式係一個迴圈，要係噉重複做同一樣嘅工作－呢樣工作就係攞「玩家透過手掣等架生俾嘅輸入」以及「隻遊戲喺上一刻嘅狀態」等嘅資訊，再按呢啲資訊同隻遊戲嘅法則，計遊戲世界下一刻嘅狀態應該係點。即係話一隻電子遊戲大致上可以想像成噉樣嘅虛擬碼：

while game is running
    process inputs
    update game world
    generate outputs
  loop

以上呢段碼就噉睇落好簡單，但查實佢包含多個複雜嘅子系統：輸入可以包括鍵盤、踎士、同手掣等，而控制系統嘅設計可以高深得好交關；更新個遊戲世界即係要攞玩家嘅輸入加埋個世界前一刻嘅狀態，用一大堆碼計出下一刻嘅狀態應該係點，例如如果玩家撳咗「向前」，玩家控制嘅角色位置就要向住佢面向嘅方向改變，而改變幅度由個角色嘅移動速度決定；跟手個程式仲要有計，將個新狀態顯示俾喺個熒光幕上面，等個用家有得睇。喺現實應用裏面，上述嘅程式閒閒地可以有幾萬行碼。

程式結構 

一個遊戲程式結構大致如下：喺一隻遊戲嘅程式啟動嗰陣，個程式要初始化－設定好嗮隻遊戲嘅參數嘅數值、講好嗮要用乜資源等等。初始化咗之後，個程式就要進入遊戲迴圈－喺程式編寫上，迴圈係一類控制流程機制，能夠令一段程式碼只要某啲條件唔達到，就會一路係噉重複行，而相對喺冇迴圈嗰陣，段碼會逐句逐句行，行一次就算。好似係以下呢段食鬼嘅虛擬碼噉，就用咗個 while 迴圈：

move_speed = ...
  number_of_ghost = ...
  ... 用若干行 declaration 設定遊戲柞參數嘅數值

while player.lives > 0 當玩家有多過 0 條命嗰陣一路做...
     // Process Inputs；睇讀取輸入
     JoystickData j = grab raw data from joystick 由手掣嗰度探測玩家撳咗乜掣

// Update Game World；睇遊戲邏輯同人工智能
     update player.position based on j 基於玩家撳嘅掣，更新玩家角色嘅位置
     foreach Ghost g in world for 每一隻鬼
        if player collides with g 如果玩家撞到嗰隻鬼
           kill either player or g 玩家就死
        else
           update AI for g based on player.position 基於隻鬼嘅人工智能，更新佢嘅位置
        end
     loop
     // 喺現實應用上，以上嘅各個動作通常會每個做一個子程式。

...

// Generate outputs；睇遊戲外觀
     draw graphics 喺熒光幕上面畫相應嘅影像
     update audio ... 同埋整聲效
  loop

讀取輸入 

一個遊戲程式嘅首要任務係要曉讀取玩家俾嘅輸入：一隻遊戲定義係一種能夠俾玩家有操控權嘅媒體－相對於戲或者文學等淨係向觀眾單向噉傳意念嘅媒體；所以隻遊戲要有某啲方法知玩家想做啲乜；喺傳統嘅家用遊戲機當中，玩家會有個手掣攞喺手，個手掣有若干個掣俾佢撳，每當佢撳一個掣嗰時，個掣就會有電傳返去部機嗰度，於是喺是但一個時間點，部機都可以靠探測由手掣嚟嘅訊號，知玩家撳咗邊幾個掣。

喺軟件上，遊戲機內部對輸入嘅處理可以大致上想像成類似噉嘅 Arduino碼：

const int UpButton = 12; /* 用一個變數代表個「上」掣有冇俾人撳 */
const int DownButton = 11; /* 另一個變數代表個「下」掣有冇俾人撳 */

void setup(){ 
   Serial.begin(9600);
   pinMode(UpButton, INPUT);
   pinMode(UpButton, INPUT);
} 

void loop(){ /* 程式迴圈 */
   if(digitalRead(UpButton) == HIGH){ /* 如果個「上」掣有訊號... */
	Serial.println("Up:");
	delay(100);
   }
   if(digitalRead(DownButton) == HIGH){ /* 如果個「下」掣有訊號... */
	Serial.println("Down:");
	delay(100);
   }
}

一個遊戲程式要編成當感應到「上」掣有訊號嗰時，將個角色向前移動，移動幅度取決於個角色嘅速度－於是玩家就可以透過撳手掣上嘅掣，控制遊戲世界入面嘅嘢。其他平台嘅遊戲通常唔會用手掣，不過原理基本上一樣：好似係電腦遊戲當中，玩家會用踎士同鍵盤俾輸入；而呢啲輸入架生都係會傳電訊號俾部電腦嘅主機。

指令詮釋器 

喺現實世界，出得街賣嘅遊戲多數有指令詮釋器：指令詮釋器係喺遊戲收到嘅輸入同世界更新之間嘅詮釋機制；例如係一隻賽車遊戲當中，喺玩家撳咗個「X」掣嗰陣，個遊戲程式要將呢個指令翻譯成「個玩家想加速」，跟住再按呢份資訊將玩家架車嘅加速度作出相應嘅改變。呢個過程就噉睇好似冇必要，但查實相當有用：有咗呢種機制，遊戲製作組就可以整個模組出嚟，俾玩家設定「X」掣對應邊個指令、「Y」掣對應邊個指令... 呀噉－等玩家有得將個遊戲操作方案個人化。

例如喺冇指令詮釋器之下，一隻射擊遊戲嘅原始碼會有噉嘅嘢：

void InputHandler::handleInput()
{
  if (isPressed(BUTTON_X)) jump(); // 如果撳咗 X 掣，角色要跳。
  else if (isPressed(BUTTON_Y)) fireGun(); // 如果撳咗 Y 掣，角色會開槍。
  else if (isPressed(BUTTON_A)) swapWeapon(); // 如此類推
  else if (isPressed(BUTTON_B)) lurchIneffectively();
}

而喺有指令詮釋器下，段碼會變成噉：

void InputHandler::handleInput()
{
  if (isPressed(BUTTON_X)) buttonX_->execute(); // 如果撳咗 X 掣，做 X 掣相應嘅功能；
  else if (isPressed(BUTTON_Y)) buttonY_->execute(); // 如此類推
  else if (isPressed(BUTTON_A)) buttonA_->execute();
  else if (isPressed(BUTTON_B)) buttonB_->execute();
}

呢段碼會配合好似噉嘅碼：

class Command // 定義一個 class，代表指令
{
public:
  virtual ~Command() {}
  virtual void execute() = 0;
};

class JumpCommand : public Command // 定義「跳」嘅指令
{
public:
  virtual void execute() { jump(); }
};

class FireCommand : public Command // 定義「開槍」嘅指令
{
public:
  virtual void execute() { fireGun(); }
};
... 如此類推 ...

class InputHandler // 定義一個 class 
{
public:
  void handleInput();

private:
  Command* buttonX_; // 每個掣都係一個 pointer，point 去某個指令。
  Command* buttonY_;
  Command* buttonA_;
  Command* buttonB_;
};

喺冇指令詮釋器嘅情況當中，如果有個玩家比較鍾意用 X 掣代表「開槍」，A 掣代表「跳」，而唔用隻遊戲預設嗰個控制方案，佢都冇方法改個控制方案；但喺有指令詮釋器嘅情況下，製作組可以喺遊戲當中加個模組，俾玩家揀要唔要跟預設個控制方案，而如果佢唔要，佢想揀邊個掣代表邊個指令－指令詮釋器嘅存在令玩家有得將控制方案個人化。

遊戲邏輯 

遊戲邏輯指隻遊戲入面有乜物件、每件物件包含乜變數、以及物件同物件之間點互動，遊戲邏輯亦都界定咗個遊戲程式要點樣對玩家嘅輸入俾反應。用返上面嗰段食鬼碼為例，隻遊戲嘅遊戲邏輯包含咗初始化當中嗰柞定義咗嘅變數同物件，以及個遊戲迴圈入面嘅「process input」同「update game world」當中所包含嘅「隻遊戲點運作」嘅法則。遊戲邏輯係電子遊戲設計要度好嘅嘢。為一隻遊戲編定遊戲邏輯嗰陣要考慮嘅嘢包括咗：
數據結構：一隻遊戲會包含大量嘅物件同相應變數，例如一隻一般嘅射擊遊戲會有若干把唔同嘅槍俾玩家揀，每把係一件物件，而佢哋分別喺「彈匣大細」同「每槍造成幾多傷害」等嘅變數上都有異；編寫一個遊戲程式需要思考數據結構要點處理－個程式內部要用乜方法儲起各變數同物件嘅數據。
基於事件架構係一種軟件畫則上嘅範式。喺遊戲編程上，基於事件架構將一隻遊戲軟件視為一柞事件嘅集合體。一件事件係指一次系統狀態嘅改變，而喺好多遊戲嘅程式當中都有事件管理系統：事件管理系統界定每種事件係乜同涉及乜數據；而喺做更新遊戲狀態嗰時，遊戲世界入面每件物件同每個子系統會睇吓發生緊嘅事件當中邊啲係同佢相關嘅，再按遊戲法則決定要點俾反應。

遊戲物理 

遊戲物理指個遊戲世界嘅物理：除咗互動式小說等少數遊戲類型之外，電子遊戲多數都會有個空間俾玩家控制某啲嘢喺入面郁動，所以一隻遊戲嘅世界多數要有物理法則主宰啲嘢應該點郁，而喺「更新遊戲世界狀態」嘅過程當中，個遊戲程式要按照遊戲嘅物理法則同玩家輸入計返個世界嘅狀態應該點變，例如一隻用牛頓力學嘅賽車遊戲，喺玩家撳咗「踩油」嘅掣嗰陣，要改變架車嘅加速度數值，而架車相應嘅速度同位置等變數亦要跟牛頓力學裏面嘅法則作出相應嘅改變。

例如以下呢段用 C 寫嘅碼可以攞嚟模擬喺牛頓第二定律之下郁動嘅物體，喺動作遊戲當中基本上實會用到：

double t = 0.0;
float dt = 1.0f;

float velocity = 0.0f;
float position = 0.0f;
float force = 10.0f;
float mass = 1.0f;
// 設一大柞變數，包括咗時間點、時間間隔、速度、位置、件物體受嘅力、同件物體嘅質量。

while ( t <= 10.0 ) // 重複噉計若干次，計到時間點係 10 為止。
{
    position = position + velocity * dt;
    velocity = velocity + ( force / mass ) * dt; // 用牛頓第二定律計吓件物體受嘅力同佢嘅質量會點影響佢嘅速度。
    t += dt;
}

呢段嘢會俾嘅輸出如下，佢列嗮佢模擬嗰件物體喺每個時間點  嘅位置同速度出嚟：

t=0:    position = 0      velocity = 0
t=1:    position = 0      velocity = 10
t=2:    position = 10     velocity = 20
t=3:    position = 30     velocity = 30
t=4:    position = 60     velocity = 40
t=5:    position = 100    velocity = 50
t=6:    position = 150    velocity = 60
t=7:    position = 210    velocity = 70
t=8:    position = 280    velocity = 80
t=9:    position = 360    velocity = 90
t=10:   position = 450    velocity = 100

人工智能 

遊戲編程會用到人工智能嘅技術：好多遊戲嘅關卡入面都會有敵人俾玩家打，啲敵人要曉唔淨只係企喺度，仲要識探測玩家嘅位置，並且攻擊玩家，以及對玩家嘅攻擊作出迴避等等－即係話要令遊戲角色作出有智能嘅行為，而「令機械展示智能」正正就係人工智能嘅定義。

一般嘅電子遊戲人工智能有以下嘅部份：
刺激詮釋器：刺激詮釋器會話俾一個人工智能程式知個遊戲狀態係點；一般嚟講，每個個體敵人都會有個獨立嘅人工智能，每個智能會透過刺激詮釋器得到佢哋應該得到嘅資訊，跟住個程式要有方法表示「foreach 敵人，嗰個敵人手上有乜資訊」。
決策系統：每一個人工智能都要按手上嘅資訊同自己嘅目的，計出跟住要採取乜嘢行動；例如一個敵人見到玩家，知道玩家嘅位置，而佢目的係要行埋玩家度攻擊佢，佢個人工智能程式就要有個方法教佢點樣用「玩家嘅位置」同「自己嘅位置」計出「自己應該向乜方向移動」。
舉例說明，喺遊戲 AI 上，其中一樣最基本嘅嘢係教 AI 追敵人，例如遊戲敵人追蹤玩家，嘗試接近同攻擊玩家角色。以下係教一個 AI 追蹤一件物件嘅演算法：

class KinematicSeek:
  // Declare 個演算法控制緊邊個角色同要追嘅目標
    character, target
  // Declare 個角色嘅最大速度
    maxSpeed

def getSteering():
    // 整個 output 嘅結構
    steering = new KinematicSteeringOutput()
    // 攞個 steering 嘅方向
    steering.velocity = target.position - character.position // 如果將呢個數變成隨機，可以用嚟教個 AI 隨機行嚟行去。
    if steering.velocity.length() < radius: // 如果同目標之間嘅距離細過某個特定數值，就唔使郁。
      return none
    // 計出個 exact 嘅速度
    steering.velocity.normalize()
    steering.velocity *= maxSpeed
    // 轉向要郁嘅方向
    character.orientation = getNewOrientation(character.orientation,steering.velocity)
    // 將個 steering 俾做 output
    steering.rotation = 0
    return steering

順帶一提，將 target.position - character.position 改做 character.position - target.position 就可以令段演算法變成教個 AI 避開一件物件。再進一步嘅演算法仲會教埋個 AI 離目標有返咁上下近就要剎掣、將方向對準、以及將自己嘅速度變成同目標一致等等嘅功能。

遊戲外觀 

遊戲外觀係一柞將遊戲邏輯向觀察者展現嘅子系統：一隻遊戲需要俾玩家決定要作出乜行動，而為咗俾玩家知要做決策，個程式實要以某啲方式，呈現遊戲世界嘅狀態俾玩家知；喺廿一世紀嘅應用當中，遊戲世界通常會用有吸引力嘅電腦圖像再加埋適當嘅聲音嚟呈現。喺攞咗玩家輸入，又計好遊戲世界嘅新狀態之後，個遊戲程式要做嘅嘢就係度好「個熒光幕要顯示乜圖像」以及「啲音響喇叭要出乜嘢聲」－負責做呢個工序嘅遊戲程式部份就係遊戲外觀系統。

影像 

顯示影像嘅方法要睇隻遊戲係用二維定三維影像嘅做法：
二維圖像會用精靈圖結合埋一齊整景。舉個例子說明，喺一隻二維嘅《超級瑪利奧》遊戲入面，個遊戲程式會記住主角嘅精靈圖同埋啲怪獸嘅精靈圖，而個主角瑪利奧嘅精靈圖又會包含咗佢企喺度嗰陣嘅樣、佢行路嗰陣嘅樣、同埋佢跳嗰陣嘅樣等等。喺每一個時間點，個程式都會按「個主角同每隻怪獸喺邊個位置，喺度做緊乜」等嘅資訊，揀應該用邊幾幅精靈圖，並且按照每件物件嘅位置，將呢啲精靈圖同個背景合拼埋一齊，最後形成一個畫面，最後個程式要將呢個畫面傳去個熒光幕嗰度，等個熒光幕將個畫面顯示出嚟。
三維圖像會用到三維模型。一個三維模型係一個用數字呈現嘅三維物體，而整一幅三維嘅電腦圖像過程要用彩現嘅方法：想做彩現嘅人會首先整一個景檔案出嚟，呢個檔案會包含多種資訊，包括「個景入面用咗啲乜嘢立體模型」、「每個立體模型喺邊個位置」、「光源喺邊」、「個鏡頭擺喺邊個位置」、同埋「幾何變換」呀噉，描述個景係點嘅；然後部電腦會將呢個檔案入面嘅數據傳去一個彩現程式嗰度，等個程式做一大柞人手做唔嚟嘅運算，計出個鏡頭會睇到嘅影像應該係點樣嘅，並且將個鏡頭所睇到嘅影像俾出嚟做輸出。
無論二維定三維圖像，一個電子遊戲程式會係噉做「基於遊戲狀態更新影像」嘅工作，而且一秒內做閒閒地做幾廿次－由人眼嚟睇就好似係識郁嘅影像噉。

用虛擬碼表達大致上會係噉：

make the background the color it should be // 將背景設做應有嘅色水。

for each object // for each 物件，用精靈圖或者三維模型畫佢出嚟。
      take that object's position
      take that object's sprite/3D model
      draw it

聲音 

電子遊戲程式會內有若干個聲檔案，喺某啲事件發生嗰陣，個程式要按「玩家角色離發聲物件幾遠」等嘅資訊，傳訊號去音響喇叭嗰度，教個喇叭出乜嘢聲。電子遊戲涉及三大種聲音：
音樂：個遊戲程式一日喺某個狀態就要一路循環播嘅聲，會用到 while 迴圈。音樂對於營造一隻遊戲嘅氣氛嚟講不可或缺。
聲效：指喺某啲事件發生嗰時一次性嘅聲，例如係一隻賽車遊戲入面，每當有兩架車相撞，個遊戲程式要叫個喇叭播出相應嗰個聲檔案嘅內容。
講嘢：係三種聲入面最難搞嗰種；因為喺多數情況下，個遊戲程式唔淨只要叫喇叭播出個聲檔案，仲要確保啲聲同講緊嘢嗰個角色嘅三維模型嘅嘴唇嘅郁動同步。有啲遊戲程式會索性有個數據庫，儲住「人類嘴唇喺發每種聲嗰時係乜樣」嘅資訊，再喺要播講嘢聲嗰陣，即場由啲聲計出個角色嘅三維模型嘅嘴唇要係乜樣。

喺每一個時間點 ，個遊戲程式要考慮有邊幾個聲檔案喺度播緊，再按「呢個聲檔案處於邊個時間點」以及「呢個聲源離玩家角色幾遠」等嘅資訊，計出佢喺嗰個時間點會造成乜嘢聲，再將呢啲資訊傳去音響喇叭嗰度。

編程架生 

常用嚟做遊戲編程嘅程式語言同架生有以下呢啲：
組合語言
C
C++
C#
Java
Lua
DirectX
Direct3D
OpenGL

文獻 
Lengyel, E. (2001). Mathematics for 3D game programming and computer graphics. Charles River Media, Inc..
McShaffry, M. (2014). Game coding complete. Nelson Education.

遊戲設計
電子遊戲設計
電子遊戲製作
遊戲物理
電腦編程
網絡編程
遊戲模組
程序生成
物件生成
遊戲引擎
遊戲描述語言
打機用語

攷

拎 
GameDev.net, a leading resource for game development.
International Game Developers Association (IGDA).
Game Development for Software Engineers, a short 5 day short course offered by MIT with guidance from the mentors of the award-winning MIT Game Lab.
One ex-game programmer's experience in the game development industry.
Game industry veteran Tom Sloper's advice on game programming.
2D Game Development wiki.
Game Development Wiki -GDwiki.

遊戲製作