设为首页 加入收藏

TOP

《游戏编程模式》(6)(二)
2017-10-13 10:39:19 】 浏览:9013
Tags:《游戏编程模式》
s)
17 { 18 input_->update(*this); 19 physics_->update(*this, world); 20 graphics_->update(*this, graphics); 21 } 22 23 private: 24 InputComponent* input_; 25 PhysicsComponent* physics_; 26 GraphicsComponent* graphics_; 27 28 }; 29 30 GameObject* createBjorn() 31 { 32 return new GameObject(new PlayerInputComponent(), 33 new BjornPhysicsComponent(), 34 new BjornGraphicsComponent()); 35 }

 

 

Chapter 15 事件队列

对消息或事件的发送与受理进行时间上的解耦。

事件队列给接受端的控制权:延迟处理、聚合请求或完全抛弃。发送端所能做的就是往队列里投递消息,无法有实时反馈的预期。

避免A到B到A的事件循环:不要在处理事件端的代码里再发送事件。

 

Audio类:

 1 class Audio
 2 {
 3 
 4 public:
 5   static void init()
 6   {
 7     head_ = 0;
 8     tail_ = 0;
 9   }
10 
11   // Methods...
12 
13 private:
14   static int head_;
15   static int tail_; 
16 
17   static const int MAX_PENDING = 16;
18 
19   static PlayMessage pending_[MAX_PENDING];
20 };
21 
22 void Audio::playSound(SoundId id, int volume)
23 {
24   // Walk the pending requests.
25   for (int i = head_; i != tail_;
26        i = (i + 1) % MAX_PENDING)
27   {
28     if (pending_[i].id == id)
29     {
30       // Use the larger of the two volumes.
31       pending_[i].volume = max(volume, pending_[i].volume);
32  
33       // Don't need to enqueue.
34       return;
35     }
36   }
37 
38   assert((tail_ + 1) % MAX_PENDING != head_);
39 
40   // Add to the end of the list.
41   pending_[tail_].id = id;
42   pending_[tail_].volume = volume;
43   tail_ = (tail_ + 1) % MAX_PENDING;
44 } 
45 
46 void Audio::update()
47 {
48   // If there are no pending requests, do nothing.
49   if (head_ == tail_) return;
50 
51   ResourceId resource = loadSound(pending_[head_].id);
52   int channel = findOpenChannel();
53   if (channel == -1) return;
54   startSound(resource, channel, pending_[head_].volume); 
55 
56   head_ = (head_ + 1) % MAX_PENDING;
57 }
  1. 环状缓冲区;
  2. PlaySound只做元素入列,首先要判断是否有重复的,如果有就标记音量高的那个,tail增长时取余;
  3. Update做元素取出,首先判断是否有待取元素,head增长时取余。

 

Chapter 16 服务定位器

为某服务提供一个全局访问入口来避免使用者与该服务具体实现类之间产生耦合。

 

Audio服务:

 1 class Audio
 2 {
 3 
 4 public:
 5   virtual ~Audio() {}
 6 
 7   virtual void playSound(int soundID) = 0;
 8   virtual void stopSound(int soundID) = 0;
 9   virtual void stopAllSounds() = 0;
10 
11 };

Audio服务提供器:

 1 class ConsoleAudio : public Audio
 2 {
 3 
 4 public:
 5   virtual void playSound(int soundID)
 6   {
 7     // Play sound using console audio api...
 8   }
 9  
10   virtual void stopSound(int soundID)
11   {
12     // Stop sound using console audio api...
13   } 
14 
15   virtual void stopAllSounds()
16   {
17     // Stop all sounds using console audio api...
18   }
19 };

包含空服务的定位器:

 1 class Locator
 2 {
 3 
 4 public:
 5   static void initialize() { service_ = &nullService_; }
 6  
 7   static Audio& getAudio() { return *service_; }
 8  
 9   static void provide(Audio* service)
10   {
11     if (service == NULL)
12     {
13       // Revert to null service.
14       service_ = &nullService_;
15     }
16     else
17     {
18       service_ = service;
19     }
20   } 
21 
22 private:
23   static Audio* service_;
24   static NullAudio nullService_;
25 
26 };

注册一个服务提供器:

1 ConsoleAudio *audio = new ConsoleAudio();
2 Locator::provide(audio);

使用:

1 Audio *audio = Locator::getAudio();
2 audio->playSound(VERY_LOUD_BANG);

调用playSound()的代码对ConsoleAudio一无所知,它只知道Audio的抽象接口。Locator与ConsoleAudio也没有耦合,代码里唯一知道具体实现类的地方,是提供这个服务的代码。

 

空服务:

1 class NullAudio: public Audio
2 {
3 public:
4   virtual void playSound(int soundID) { /* Do nothing. */ }
5   virtual void stopSound(int soundID) { /* Do nothing. */ }
6   virtual void stopAllSounds()        { /* Do nothing. */ }
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇MediatorPattern(中介者模式) 下一篇《游戏编程模式》(7)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目