游戏编程模式

1.

转载:点击打开链接

Component Pattern 组件模式

Intent 意义

Allow a single entity to span multiple domains without coupling the domains to each other 
允许一个单一的实体跨越多个不同域而不会导致耦合。

The Pattern 模式描述

A single entity spans multiple domains. To keep the domains isolated, the code for each is placed in its own component class. The entity is reduced to a simple container of components. 
单一实体横跨了多个域。为了能够保持域之间相互隔离,每个域的代码都独立地放在自己的组件类中。实体本身则可以简化为这些组件的容器。

When to Use It 使用情形

Components are most commonly found within the core class that defines the entities in a game, but they may be useful in other places as well. This pattern can be put to good use when any of these are true:

  • You have a class that touches multiple domains which you want to keep decoupled from each other.
  • A class is getting massive and hard to work with.
  • You want to be able to define a variety of objects that share different capabilities, but using inheritance doesn’t let you pick the parts you want to reuse precisely enough.

组件最常见于游戏中定义实体的核心类,但是它们也能够用在别的地方。当如下条件成立时,组件模式就能够发挥它的作用:

  • 你有一个涉及多个域的类,但是你希望这些域保持相互解耦。
  • 一个类越来越庞大,越来越难以开发。
  • 你希望定义许多共享不同能力的对象,但采用继承的办法却无法令你精确地重用代码。

Tips

Unity引擎的主要设计正是围绕组件模型来进行的。

总结:由于一个类很庞大,而且有的子类不需要基类中的一些方法

2.事件队列模式


Event Queue Pattern 事件队列模式

Intent 意义

Decouple when a message or event is sent from when it is processed. 
对消息或事件的发送与受理进行时间上的解耦。

The Pattern 模式描述

A queue stores a series of notifications or requests in first-in, first-out order. Sending a notification enqueues the request and returns. The request processor then processes items from the queue at a later time. Requests can be handled directly or routed to interested parties. This decouples the sender from the receiver both statically and in time.

事件队列是一个按照先进先出顺序存储一系列通知或者请求的队列。发出通知时系统会将该请求置入队列并返回,请求处理器随后从事件队列中获取并处理这些请求。请求可由处理器直接处理或转交给对其感兴趣的模块。这一模式对消息的发送者与受理者进行了解耦,使消息的处理变得动态且非实时。

When to Use It 使用情形

If you only want to decouple who receives a message from its sender, patterns like Observer and Command will take care of this with less complexity. You only need a queue when you want to decouple something in time.

I mention this in nearly every chapter, but it’s worth emphasizing. Complexity slows you down, so treat simplicity as a precious resource.

I think of it in terms of pushing and pulling. You have some code A that wants another chunk B to do some work. The natural way for A to initiate that is by pushing the request to B.

Meanwhile, the natural way for B to process that request is by pulling it in at a convenient time in its run cycle. When you have a push model on one end and a pull model on the other, you need a buffer between them. That’s what a queue provides that simpler decoupling patterns don’t.

Queues give control to the code that pulls from it — the receiver can delay processing, aggregate requests, or discard them entirely. But queues do this by taking control away from the sender. All the sender can do is throw a request on the queue and hope for the best. This makes queues a poor fit when the sender needs a response.

如果你只是想解耦接收者和发送者,像观察者模式和命令模式都可以用较小的复杂度来进行处理。在需要解耦某些实时的内容时才建议使用事件队列。

不妨用推和拉来的情形来考虑。有一块代码A需要另一块代码B去做些事情。对A自然的处理方式是将请求推给B。

同时,对B自然的处理方式是在B方便时将请求拉入。当一端有推模型另一端有拉模型时,你就需要在它们间放一个缓冲的区域。 这就是队列比简单的解耦模式多出来的那一部分。

队列给了代码对拉取的控制权——接收者可以延迟处理,合并或者忽视请求。发送者能做的就是向队列发送请求然后就完事了,并不能决定什么时候发送的请求会受到处理。而当发送者需要一些回复反馈时,队列模式就不是一个好的选择。

Tips

Unity引擎的主要设计正是围绕组件模型来进行的。



2.游戏循环模式

    

Game Loop Pattern 游戏循环模式

Intent 意义

Decouple the progression of game time from user input and processor speed. 
游戏循环模式,实现游戏运行过程中对用户输入处理和时间处理的解耦。

The Pattern 模式描述

A game loop runs continuously during gameplay. Each turn of the loop, it processes user input without blocking, updates the game state, and renders the game. It tracks the passage of time to control the rate of gameplay.

游戏循环模式:游戏循环在游戏过程中持续运转。每循环一次,它非阻塞地处理用户的输入,更新游戏状态,并渲染游戏。它跟踪流逝的时间并控制游戏的速率。

游戏循环将游戏的处理过程和玩家输入解耦,和处理器速度解耦,实现用户输入和处理器速度在游戏行进时间上的分离。

游戏循环也许需要与平台的事件循环相协调。如果在操作系统的高层或有图形UI和内建事件循环的平台上构建游戏,那就有了两个应用循环在同时运作,需要对他们进行相应的协调。

When to Use It 使用情形

任何游戏或游戏引擎都拥有自己的游戏循环,因为游戏循环是游戏运行的主心骨。

Unity已经内建了游戏循环模式,即Update( )方法。



2.游戏循环模式

3.数据局部性模式


Data Locality Pattern 数据局部性模式

Intent 意义

Accelerate memory access by arranging data to take advantage of CPU caching. 
通过合理组织数据利用CPU的缓存机制来加快内存访问速度。

The Pattern 模式描述

Modern CPUs have caches to speed up memory access. These can access memory adjacent to recently accessed memory much quicker. Take advantage of that to improve performance by increasing data locality — keeping data in contiguous memory in the order that you process it.

现代的CPU有缓存来加速内存读取,其可以更快地读取最近访问过的内存毗邻的内存。基于这一点,我们通过保证处理的数据排列在连续内存上,以提高内存局部性,从而提高性能。

为了保证数据局部性,就要避免的缓存不命中。也许你需要牺牲一些宝贵的抽象。你越围绕数据局部性设计程序,就越放弃继承、接口和它们带来的好处。没有银弹,只有权衡。

When to Use It 使用情形

使用数据局部性的第一准则是在遇到性能问题时使用。不要将其应用在代码库不经常使用的角落上。 优化代码后其结果往往更加复杂,更加缺乏灵活性。

就本模式而言,还得确认你的性能问题确实由缓存不命中而引发的。如果代码是因为其他原因而缓慢,这个模式自然就不会有帮助。

简单的性能评估方法是手动添加指令,用计时器检查代码中两点间消耗的时间。而为了找到糟糕的缓存使用情况,知道缓存不命中有多少发生,又是在哪里发生的,则需要使用更加复杂的工具—— profilers。

组件模式是为缓存优化的最常见例子。而任何需要接触很多数据的关键代码,考虑数据局部性都是很重要的。


4.脏标记模式

Dirty Flag Pattern 脏标记模式

Intent 意义

Avoid unnecessary work by deferring it until the result is needed. 
将工作推迟到必要时进行以避免不必要的工作。

The Pattern 模式描述

A set of primary data changes over time. A set of derived data is determined from this using some expensive process. A “dirty” flag tracks when the derived data is out of sync with the primary data. It is set when the primary data changes. If the flag is set when the derived data is needed, then it is reprocessed and the flag is cleared. Otherwise, the previous cached derived data is used.

一组原始数据随时间变化。一组颜色数据经过一些代价昂贵的操作由这些数据确定。一个脏标记跟踪这个衍生数据是否和原始数据同步。它在原始数据改变时被设置。如果它被设置了,那么当需要衍生数据时,它们就会被重新计算并且标记被清除。否则就使用缓存的数据。

When to Use It 使用情形

就像其他优化模式一样,此模式会增加代码复杂度。只在有足够大的性能问题时,再考虑使用这一模式。

脏标记在这两种情况下适用:

  • 当前任务有昂贵的计算开销
  • 当前任务有昂贵的同步开销。 若满足这两者之一,也就是两者从原始数据转换到目标数据会消耗很多时间,都可以考虑使用脏标记模式来节省开销。

若原始数据的变化速度远高于目标数据的使用速度,此时数据会因为随后的修改而失效,此时就不适合使用脏标记模式。



猜你喜欢

转载自blog.csdn.net/qq_35433081/article/details/80666983