Skip to content

Commit ddb7e5c

Browse files
committed
2 parents ede92dc + 5814bac commit ddb7e5c

16 files changed

+1853
-291
lines changed

01.1-Architecture, Performance, and Games.md

+199
Large diffs are not rendered by default.

02.5-Singleton.md

+445-59
Large diffs are not rendered by default.

03-Sequencing Patterns.md

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,20 @@
1-
Sequencing Patterns
1+
序列模式
22
============================
3+
4+
Videogames are exciting in large part because they take us somewhere else. For a few minutes (or, let’s be honest with ourselves, much longer), we become inhabitants of a virtual world. Creating these worlds is one of the supreme delights of being a game programmer.
5+
6+
视频游戏很大程度会让我们兴奋是因为它们把我们带到了其他地方。在几分钟(或者,坦率讲,时间更长)里,我们成为了虚拟世界的人。创建这些世界是作为游戏程序员的最高乐趣之一。
7+
8+
One aspect that most of these game worlds feature is time — the artificial world lives and breathes at its own cadence. As world builders, we must invent time and craft the gears that drive our game’s great clock
9+
10+
从一方面来讲,大多数游戏世界的特征便是时间--虚拟世界按照自己的节奏运行着。作为世界的建造者,我们必须创造时间和打磨用来驱动游戏巨大时钟的齿轮。(译者注:这里作者用了比喻来说明问题)
11+
12+
The patterns in this section are tools for doing just that. A Game Loop is the central axle that the clock spins on. Objects hear its ticking through Update Methods. We can hide the computer’s sequential nature behind a facade of snapshots of moments in time using Double Buffering so that the world appears to update simultaneously.
13+
14+
在本节中的模式便是用来做那样工作的工具。[游戏循环](03.2-Game Loop.md)是时钟旋转的中心轴,对象通过[更新方法](03.3-Update Method.md)来聆听它的滴答声。我们可以通过[双缓冲](03.1-Double Buffer.md)来及时的将计算机的连续性隐藏在时刻快照之后,从而使得游戏世界能够同步更新。
15+
16+
# 本章模式
17+
18+
- [双缓冲](03.1-Double Buffer.md)
19+
- [游戏循环](03.2-Game Loop.md)
20+
- [更新方法](03.3-Update Method.md)

04.3-Type Object.md

+87
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,91 @@
261261

262262

263263

264+
--- TODO
265+
#### 类型能否改变? ####
266+
267+
现在,我们假定一旦对象创建完成,就与其类型对象进行绑定,并不再改变。并不是一定要这样
268+
269+
。我们可以允许一个对象随时间改变类型。
270+
271+
回头看我们的例子。当一个怪物死的时候,设计师告诉我们他们希望尸体能够变成会动的僵尸。
272+
273+
我们可以通过重新产生一个带有僵尸品种的新怪,但另一个更简单的选择是获取现有的怪物并把
274+
275+
它的品种修改成僵尸。
276+
277+
- 如果类型不变:
278+
- 无论编码还是理解起来都更简单。在概念层面上,“类型”是大多数人都不希望改变
279+
280+
的东西。这么做符合这条假定。
281+
- 易于调试。如果我们在跟踪一个让怪物陷入奇怪状态的Bug时,能够直观地确定正在看
282+
283+
的品种肯定是怪物始终不变的品种,这件事就相对简单了。
284+
- 如果类型改变:
285+
- 更少的对象创建。在我们的例子里,如果类型不能改变,我们不得不在CPU循环中创建
286+
287+
新的僵尸怪物,把原怪物中需要保留的属性逐个拷贝过来,随后删除它。如果我们能改变类型,
288+
289+
所有的工作就是个简单的赋值。
290+
- 做假定时要更加小心。对象和其类型之间存在相对紧的耦合。例如,一个品种可能假
291+
292+
定怪物的当前血量永远不会超过初始血量。
293+
如果我们允许改变品种,我们需要确保现有对象能符合新类型的要求。当我们修改类型
294+
295+
时,我们可能会需要执行一些验证代码来保证对象现在的状态对新类型来说有意义。
296+
297+
####支持何种类型的派生?####
298+
299+
- 没有派生:
300+
- 更简单。简单是最好的选择。如果你没有成堆的需要共享的类型对象,何必自找麻烦
301+
302+
呢?
303+
- 可能会导致重复劳动。我曾见过给设计师用的不支持派生的编辑系统。当你有50中精
304+
305+
灵,必须去50个地方把它们的血量修改成相同的数字非常无趣。
306+
- 单继承:
307+
- 仍然相对简单。更容易实现,但是,更重要的是,它很容易理解。如果非技术用户使
308+
309+
用这个系统,会动的部分越少,就越好。很多编程语言只支持单继承是有原因的。它看起来是强
310+
311+
大和简单之间的不错的平衡点。
312+
- 属性查找更慢。要获得类型对象中的特定数据,我们需要在派生链中找到其类型,才
313+
314+
能最终确定它的值。如果我们在编写性能苛刻的代码,我们可能不想在这里浪费时间。
315+
- 多重派生:
316+
- 绝大多数的数据重复都能被避免。通过一个好的多继承系统,用户能够创建一个几乎
317+
318+
没有冗余的继承体系。比如做调整数值这件事,我们可以避免大量的复制粘贴。
319+
- 复杂。很不幸的是,它的优点更多停留在理论上而不是实践上。多重派生很难理解或
320+
321+
说明。
322+
如果我们的僵尸龙类型从僵尸和龙派生,哪些属性从僵尸获得,哪些从龙获得呢?为了
323+
324+
使用这个系统,用户必须理解派生图如何遍历并要有预见性地射击一个聪明的体系。
325+
我所见到的大多数现代C++编码标准倾向于禁用多重派生,Java和C#则完全不支持。这承
326+
327+
认了一件不幸的事情:太难让它正确地工作以至于干脆不要用它。虽然它值得考虑,但是你很少
328+
329+
会希望在游戏的类型对象中使用多继承。常言道,越简单越好。
330+
331+
###参考###
332+
333+
- 这个模式引出的高级问题是如何在不同对象之间共享数据。另一个从另一个角度引出这个问题
334+
335+
的模式是[原型]()
336+
337+
- 类型对象与[享元]()很接近。它们都让你在实例间共享数据。享元模式倾向于节约内存,并且
338+
339+
共享的数据可能不会以实际的“类型”呈现。类型对象模式的重点在于组织性和灵活性。
340+
341+
- 这个模式与[状态]()模式也有很多相似性。它们都把对象的部分定义交给另一个代理对象实现
342+
343+
。在类型对象中,我们通常代理的对象是:
344+
宽泛地描述对象的恒定数据。在状态中,我们代理的是对象现在是什么样的,即:描述对象当前
345+
346+
配置的临时数据。
347+
348+
当我们讨论到可改变类型对象的时候,你会发现此时的类型对象兼任了状态的任务。
349+
350+
264351

05-Decoupling Patterns.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
Decoupling Patterns
1+
解耦模式
22
============================
33

4-
^title Decoupling Patterns
5-
64
Once you get the hang of a programming language, writing code to do what you
75
want is actually pretty easy. What's hard is writing code that's easy to adapt
86
when your requirements *change*. Rarely do we have the luxury of a perfect
97
feature set before we've fired up our editor.
108

9+
当你掌握了一门编程语言,你会发现写代码来实现某个你想要实现的功能是件相当容易的事情。难的是写出在此基础上容易添加或更改功能的代码,因为我们几乎没有可能不更改程序的功能或者特性。
10+
1111
A powerful tool we have for making change easier is *decoupling*. When we say
1212
two pieces of code are "decoupled", we mean a change in one usually doesn't
1313
require a change in the other. When you change some feature in your game, the
@@ -19,8 +19,10 @@ Queues](event-queue.html) decouple two objects communicating with each other,
1919
both statically and *in time*. [Service Locators](service-locator.html) let
2020
code access a facility without being bound to the code that provides it.
2121

22-
## The Patterns
22+
[组件](05.1-Component.md)将游戏的不同方面互相分离开却仍然具备它们的特性。[事件队列](05.2-Event Queue.md)能够静态而且及时的将两个对象通信分离开。[服务定位器](05.3-Service Locator.md)让代码能够访问到设备却不需要被绑定到提供服务的代码上。
23+
24+
## 本章模式
2325

24-
* [Component](component.html)
25-
* [Event Queue](event-queue.html)
26-
* [Service Locator](service-locator.html)
26+
* [组件](05.1-Component.md)
27+
* [事件队列](05.2-Event Queue.md)
28+
* [服务定位器](05.3-Service Locator.md)

0 commit comments

Comments
 (0)