游戲開(kāi)發(fā)一直是熱門(mén)的領(lǐng)域,掌握良好的游戲編程模式是開(kāi)發(fā)人員的應(yīng)備技能。本書(shū)細(xì)致地講解了游戲開(kāi)發(fā)需要用到的各種編程模式,并提供了豐富的示例。
全書(shū)共分20章,通過(guò)三大部分內(nèi)容全面介紹了與游戲編程模式相關(guān)的各類(lèi)知識(shí)點(diǎn)。首部分介紹了基礎(chǔ)知識(shí)和框架;第二部分深入探索設(shè)計(jì)模式,并介紹了模式與游戲開(kāi)發(fā)之間的關(guān)聯(lián);第三部分介紹了13種有效的游戲設(shè)計(jì)模式。
本書(shū)提供了豐富的代碼示例,通過(guò)理論和代碼示例相結(jié)合的方式幫助讀者更好地學(xué)習(xí)。無(wú)論是游戲領(lǐng)域的設(shè)計(jì)人員、開(kāi)發(fā)人員,還是想要進(jìn)入游戲開(kāi)發(fā)領(lǐng)域的學(xué)生和普通程序員,都可以閱讀本書(shū)。
Robert Nystrom是一位擁有2 0 年以上職業(yè)編程經(jīng)驗(yàn)的開(kāi)發(fā)者,而他在其中大概一半的時(shí)間從事游戲開(kāi)發(fā)。在藝電(El e c t r o n i c Arts)的8年時(shí)間里,他曾參與勁爆美式足球(Madden)系列這樣龐大的項(xiàng)目,也曾投身于亨利·海茨沃斯大冒險(xiǎn)(Henry Hatsworth in the Puzzling Adventure)這樣稍小規(guī)模的游戲開(kāi)發(fā)之中。他所開(kāi)發(fā)的游戲遍及PC、GameCube、PS2、XBox、X360以及DS平臺(tái)。但他引以為傲的,是為開(kāi)發(fā)者們提供了開(kāi)發(fā)工具和共享庫(kù)。他熱衷于尋求易用的、漂亮的代碼來(lái)延伸和增強(qiáng)開(kāi)發(fā)者們的創(chuàng)造力。Robert與他的妻子和兩個(gè)女兒定居于西雅圖,在那里你很有可能會(huì)見(jiàn)到他正在為朋友們下廚,或者在為他們上啤酒。
第1篇 概述
第1章 架構(gòu),性能和游戲 3
1.1 什么是軟件架構(gòu) 3
1.1.1 什么是好的軟件架構(gòu) 3
1.1.2 你如何做出改變 4
1.1.3 我們?nèi)绾螐慕怦钪惺芤妗?
1.2 有什么代價(jià) 5
1.3 性能和速度 6
1.4 壞代碼中的好代碼 7
1.5 尋求平衡 8
1.6 簡(jiǎn)單性 9
1.7 準(zhǔn)備出發(fā) 9
第2篇 再探設(shè)計(jì)模式
第2章 命令模式 13
2.1 配置輸入 14
2.2 關(guān)于角色的說(shuō)明 16
2.3 撤銷(xiāo)和重做 18
2.4 類(lèi)風(fēng)格化還是函數(shù)風(fēng)格化 21
2.5 參考 22
第3章 享元模式 23
3.1 森林之樹(shù) 23
3.2 一千個(gè)實(shí)例 25
3.3 享元模式 26
3.4 扎根之地 26
3.5 性能表現(xiàn)如何 30
3.6 參考 31
第4章 觀察者模式 33
4.1 解鎖成就 33
4.2 這一切是怎么工作的 34
4.2.1 觀察者 35
4.2.2 被觀察者 35
4.2.3 可被觀察的物理模塊 37
4.3 它太慢了 38
4.4 太多的動(dòng)態(tài)內(nèi)存分配 39
4.4.1 鏈?zhǔn)接^察者 39
4.4.2 鏈表節(jié)點(diǎn)池 42
4.5 余下的問(wèn)題 43
4.5.1 銷(xiāo)毀被觀察者和觀察者 43
4.5.2 不用擔(dān)心,我們有GC 44
4.5.3 接下來(lái)呢 44
4.6 觀察者模式的現(xiàn)狀 45
4.7 觀察者模式的未來(lái) 46
第5章 原型模式 47
5.1 原型設(shè)計(jì)模式 47
5.1.1 原型模式效果如何 50
5.1.2 生成器函數(shù) 51
5.1.3 模板 51
5.1.4 頭等公民類(lèi)型(First-class types) 52
5.2 原型語(yǔ)言范式 52
5.2.1 Self 語(yǔ)言 53
5.2.2 結(jié)果如何 54
5.2.3 JavaScript如何 55
5.3 原型數(shù)據(jù)建!57
第6章 單例模式 61
6.1 單例模式 61
6.1.1 確保一個(gè)類(lèi)只有一個(gè)實(shí)例 61
6.1.2 提供一個(gè)全局指針以訪問(wèn)唯一實(shí)例 62
6.2 使用情境 63
6.3 后悔使用單例的原因 65
6.3.1 它是一個(gè)全局變量 65
6.3.2 它是個(gè)畫(huà)蛇添足的解決方案 66
6.3.3 延遲初始化剝離了你的控制 67
6.4 那么我們?cè)撛趺醋觥?8
6.4.1 看你究竟是否需要類(lèi) 68
6.4.2 將類(lèi)限制為單一實(shí)例 70
6.4.3 為實(shí)例提供便捷的訪問(wèn)方式 71
6.5 剩下的問(wèn)題 73
第7章 狀態(tài)模式 75
7.1 我們?cè)?jīng)相遇過(guò) 75
7.2 救星:有限狀態(tài)機(jī) 78
7.3 枚舉和分支 79
7.4 狀態(tài)模式 82
7.4.1 一個(gè)狀態(tài)接口 82
7.4.2 為每一個(gè)狀態(tài)定義一個(gè)類(lèi) 83
7.4.3 狀態(tài)委托 84
7.5 狀態(tài)對(duì)象應(yīng)該放在哪里呢 84
7.5.1 靜態(tài)狀態(tài) 84
7.5.2 實(shí)例化狀態(tài) 85
7.6 進(jìn)入狀態(tài)和退出狀態(tài)的行為 86
7.7 有什么收獲嗎 88
7.8 并發(fā)狀態(tài)機(jī) 88
7.9 層次狀態(tài)機(jī) 89
7.10 下推自動(dòng)機(jī) 91
7.11 現(xiàn)在知道它們有多有用了吧 92
第3篇 序列型模式
第8章 雙緩沖 95
8.1 動(dòng)機(jī) 95
8.1.1 計(jì)算機(jī)圖形系統(tǒng)是如何工作的(概述) 95
8.1.2 第一幕,第一場(chǎng) 96
8.1.3 回到圖形上 97
8.2 模式 98
8.3 使用情境 98
8.4 注意事項(xiàng) 98
8.4.1 交換本身需要時(shí)間 98
8.4.2 我們必須有兩份緩沖區(qū) 99
8.5 示例代碼 99
8.5.1 并非只針對(duì)圖形 102
8.5.2 人工非智能 102
8.5.3 緩存這些巴掌 106
8.6 設(shè)計(jì)決策 107
8.6.1 緩沖區(qū)如何交換 107
8.6.2 緩沖區(qū)的粒度如何 109
8.7 參考 110
第9章 游戲循環(huán) 111
9.1 動(dòng)機(jī) 111
9.1.1 CPU探秘 111
9.1.2 事件循環(huán) 112
9.1.3 時(shí)間之外的世界 113
9.1.4 秒的長(zhǎng)短 113
9.2 模式 114
9.3 使用情境 114
9.4 使用須知 114
9.5 示例代碼 115
9.5.1 跑,能跑多快就跑多快 115
9.5.2 小睡一會(huì)兒 115
9.5.3 小改動(dòng),大進(jìn)步 116
9.5.4 把時(shí)間追回來(lái) 118
9.5.5 留在兩幀之間 119
9.6 設(shè)計(jì)決策 120
9.6.1 誰(shuí)來(lái)控制游戲循環(huán),你還是平臺(tái) 121
9.6.2 你如何解決能量耗損 121
9.6.3 如何控制游戲速度 122
9.7 參考 123
第10章 更新方法 125
10.1 動(dòng)機(jī) 125
10.2 模式 127
10.3 使用情境 128
10.4 使用須知 128
10.4.1 將代碼劃分至單幀之中使其變得更加復(fù)雜 128
10.4.2 你需要在每幀結(jié)束前存儲(chǔ)游戲狀態(tài)以便下一幀繼續(xù) 128
10.4.3 所有對(duì)象都在每幀進(jìn)行模擬,但并非真正同步 129
10.4.4 在更新期間修改對(duì)象列表時(shí)必須謹(jǐn)慎 129
10.5 示例代碼 130
10.5.1 子類(lèi)化實(shí)體 132
10.5.2 定義實(shí)體 132
10.5.3 逝去的時(shí)間 135
10.6 設(shè)計(jì)決策 136
10.6.1 update方法依存于何類(lèi)中 136
10.6.2 那些未被利用的對(duì)象該如何處理 137
10.7 參考 137
第4篇 行為型模式
第11章 字節(jié)碼 141
11.1 動(dòng)機(jī) 141
11.1.1 魔法大戰(zhàn) 141
11.1.2 先數(shù)據(jù)后編碼 142
11.1.3 解釋器模式 142
11.1.4 虛擬機(jī)器碼 145
11.2 字節(jié)碼模式 145
11.3 使用情境 145
11.4 使用須知 146
11.4.1 你需要個(gè)前端界面 146
11.4.2 你會(huì)想念調(diào)試器的 147
11.5 示例 147
11.5.1 法術(shù)API 147
11.5.2 法術(shù)指令集 148
11.5.3 棧機(jī) 149
11.5.4 組合就能得到行為 153
11.5.5 一個(gè)虛擬機(jī) 155
11.5.6 語(yǔ)法轉(zhuǎn)換工具 155
11.6 設(shè)計(jì)決策 157
11.6.1 指令如何訪問(wèn)堆棧 157
11.6.2 應(yīng)該有哪些指令 158
11.6.3 值應(yīng)當(dāng)如何表示 158
11.6.4 如何生成字節(jié)碼 161
11.7 參考 162
第12章 子類(lèi)沙盒 163
12.1 動(dòng)機(jī) 163
12.2 沙盒模式 165
12.3 使用情境 165
12.4 使用須知 165
12.5 示例 166
12.6 設(shè)計(jì)決策 168
12.6.1 需要提供什么操作 168
12.6.2 是直接提供函數(shù),還是由包含它們的對(duì)象提供 169
12.6.3 基類(lèi)如何獲取其所需的狀態(tài) 170
12.7 參考 173
第13章 類(lèi)型對(duì)象 175
13.1 動(dòng)機(jī) 175
13.1.1 經(jīng)典的面向?qū)ο蠓桨浮?75
13.1.2 一個(gè)類(lèi)的類(lèi) 177
13.2 類(lèi)型對(duì)象模式 178
13.3 使用情境 179
13.4 使用須知 179
13.4.1 類(lèi)型對(duì)象必須手動(dòng)跟蹤 179
13.4.2 為每個(gè)類(lèi)型定義行為更困難 179
13.5 示例 180
13.5.1 構(gòu)造函數(shù):讓類(lèi)型對(duì)象更加像類(lèi)型 181
13.5.2 通過(guò)繼承共享數(shù)據(jù) 183
13.6 設(shè)計(jì)決策 185
13.6.1 類(lèi)型對(duì)象應(yīng)該封裝還是暴露 186
13.6.2 持有類(lèi)型對(duì)象如何創(chuàng)建 187
13.6.3 類(lèi)型能否改變 187
13.6.4 支持何種類(lèi)型的派生 188
13.7 參考 189
第5篇 解耦型模式
第14章 組件模式 193
14.1 動(dòng)機(jī) 193
14.1.1 難題 194
14.1.2 解決難題 194
14.1.3 寬松的末端 194
14.1.4 捆綁在一起 195
14.2 模式 196
14.3 使用情境 196
14.4 注意事項(xiàng) 196
14.5 示例代碼 197
14.5.1 一個(gè)龐大的類(lèi) 197
14.5.2 分割域 198
14.5.3 分割其余部分 200
14.5.4 重構(gòu)Bjorn 202
14.5.5 刪掉Bjorn 204
14.6 設(shè)計(jì)決策 206
14.6.1 對(duì)象如何獲得組件 206
14.6.2 組件之間如何傳遞信息 207
14.7 參考 210
第15章 事件隊(duì)列 211
15.1 動(dòng)機(jī) 211
15.1.1 用戶(hù)圖形界面的事件循環(huán) 211
15.1.2 中心事件總線 212
15.1.3 說(shuō)些什么好呢 213
15.2 事件隊(duì)列模式 215
15.3 使用情境 215
15.4 使用須知 215
15.4.1 中心事件隊(duì)列是個(gè)全局變量 216
15.4.2 游戲世界的狀態(tài)任你掌控 216
15.4.3 你會(huì)在反饋系統(tǒng)循環(huán)中繞圈子 216
15.5 示例代碼 217
15.5.1 環(huán)狀緩沖區(qū) 219
15.5.2 匯總請(qǐng)求 222
15.5.3 跨越線程 223
15.6 設(shè)計(jì)決策 224
15.6.1 入隊(duì)的是什么 224
15.6.2 誰(shuí)能從隊(duì)列中讀取 224
15.6.3 誰(shuí)可以寫(xiě)入隊(duì)列 225
15.6.4 隊(duì)列中對(duì)象的生命周期是什么 226
15.7 參考 227
第16章 服務(wù)定位器 229
16.1 動(dòng)機(jī) 229
16.2 服務(wù)定位器模式 230
16.3 使用情境 230
16.4 使用須知 231
16.4.1 服務(wù)必須被定位 231
16.4.2 服務(wù)不知道被誰(shuí)定位 231
16.5 示例代碼 231
16.5.1 服務(wù) 231
16.5.2 服務(wù)提供器 232
16.5.3 簡(jiǎn)單的定位器 232
16.5.4 空服務(wù) 233
16.5.5 日志裝飾器 235
16.6 設(shè)計(jì)決策 236
16.6.1 服務(wù)是如何被定位的 236
16.6.2 當(dāng)服務(wù)不能被定位時(shí)發(fā)生了什么 239
16.6.3 服務(wù)的作用域多大 240
16.7 其他參考 241
第6篇 優(yōu)化型模式
第17章 數(shù)據(jù)局部性 245
17.1 動(dòng)機(jī) 245
17.1.1 數(shù)據(jù)倉(cāng)庫(kù) 246
17.1.2 CPU的托盤(pán) 247
17.1.3 等下,數(shù)據(jù)即性能 248
17.2 數(shù)據(jù)局部性模式 249
17.3 使用情境 249
17.4 使用須知 250
17.5 示例代碼 250
17.5.1 連續(xù)的數(shù)組 251
17.5.2 包裝數(shù)據(jù) 255
17.5.3 熱/冷分解 258
17.6 設(shè)計(jì)決策 260
17.6.1 你如何處理多態(tài) 260
17.6.2 游戲?qū)嶓w是如何定義的 261
17.7 參考 263
第18章 臟標(biāo)記模式 265
18.1 動(dòng)機(jī) 265
18.1.1 局部變換和世界變換 266
18.1.2 緩存世界變換 267
18.1.3 延時(shí)重算 268
18.2 臟標(biāo)記模式 269
18.3 使用情境 269
18.4 使用須知 270
18.4.1 延時(shí)太長(zhǎng)會(huì)有代價(jià) 270
18.4.2 必須保證每次狀態(tài)改動(dòng)時(shí)都設(shè)置臟標(biāo)記 271
18.4.3 必須在內(nèi)存中保存上次的衍生數(shù)據(jù) 271
18.5 示例代碼 271
18.5.1 未優(yōu)化的遍歷 272
18.5.2 讓我們“臟”起來(lái) 273
18.6 設(shè)計(jì)抉擇 275
18.6.1 何時(shí)清除臟標(biāo)記 275
18.6.2 臟標(biāo)記追蹤的粒度多大 276
18.7 參考 276
第19章 對(duì)象池 277
19.1 動(dòng)機(jī) 277
19.1.1 碎片化的害處 277
19.1.2 二者兼顧 278
19.2 對(duì)象池模式 278
19.3 使用情境 279
19.4 使用須知 279
19.4.1 對(duì)象池可能在閑置的對(duì)象上浪費(fèi)內(nèi)存 279
19.4.2 任意時(shí)刻處于存活狀態(tài)的對(duì)象數(shù)目恒定 279
19.4.3 每個(gè)對(duì)象的內(nèi)存大小是固定的 280
19.4.4 重用對(duì)象不會(huì)被自動(dòng)清理 281
19.4.5 未使用的對(duì)象將占用內(nèi)存 281
19.5 示例代碼 281
19.6 設(shè)計(jì)決策 287
19.6.1 對(duì)象是否被加入對(duì)象池 287
19.6.2 誰(shuí)來(lái)初始化那些被重用的對(duì)象 288
19.7 參考 290
第20章 空間分區(qū) 291
20.1 動(dòng)機(jī) 291
20.1.1 戰(zhàn)場(chǎng)上的部隊(duì) 291
20.1.2 繪制戰(zhàn)線 292
20.2 空間分區(qū)模式 293
20.3 使用情境 293
20.4 使用須知 293
20.5 示例代碼 293
20.5.1 一張方格紙 294
20.5.2 相連單位的網(wǎng)格 294
20.5.3 進(jìn)入戰(zhàn)場(chǎng) 296
20.5.4 刀光劍影的戰(zhàn)斗 297
20.5.5 沖鋒陷陣 298
20.5.6 近在咫尺,短兵相接 299
20.6 設(shè)計(jì)決策 302
20.6.1 分區(qū)是層級(jí)的還是扁平的 302
20.6.2 分區(qū)依賴(lài)于對(duì)象集合嗎 302
20.6.3 對(duì)象只存儲(chǔ)在分區(qū)中嗎 304
20.7 參考 305