Chatper 5 原型模式
核心思想是一个对象可以生成与自身相似的其他对象。
基类Monster,有一个抽象方法clone:
1 class Monster
2 {
3 public:
4
5 virtual ~Monster() {}
6 virtual Monster* clone() = 0;
7
8 // Other stuff...
9 };
子类的clone实现:
1 class Ghost : public Monster {
2 public:
3
4 Ghost(int health, int speed)
5 : health_(health),
6 speed_(speed)
7 {}
8
9 virtual Monster* clone()
10 {
11 return new Ghost(health_, speed_);
12 }
13
14 private:
15 int health_;
16 int speed_;
17 };
通用的Spawner类:
1 class Spawner
2 {
3
4 public:
5 Spawner(Monster* prototype)
6 : prototype_(prototype)
7 {}
8
9 Monster* spawnMonster()
10 {
11 return prototype_->clone();
12 }
13
14 private:
15 Monster* prototype_;
16 };
这样用:
1 Monster* ghostPrototype = new Ghost(15, 3); 2 Spawner* ghostSpawner = new Spawner(ghostPrototype); 3 Monster* newGhost = Spawner->spawnMonster();
生成器函数和孵化函数指针:
1 Monster* spawnGhost()
2 {
3 return new Ghost();
4 }
5 typedef Monster* (*SpawnCallback)();
6
7 class Spawner
8 {
9 public:
10 Spawner(SpawnCallback spawn)
11 : spawn_(spawn)
12 {}
13
14 Monster* spawnMonster()
15 {
16 return spawn_();
17 }
18
19 private:
20 SpawnCallback spawn_;
21
22 };
这样用:
1 Spawner* ghostSpawner = new Spawner(spawnGhost); 2 Monster* newGhost = ghostSpawner->spawnMonster();
Chatper 6 单例模式
确保一个类只有一个实例,并为其提供一个全局访问入口。
1 class FileSystem
2 {
3 public:
4 static FileSystem& instance()
5 {
6 static FileSystem *instance = new FileSystem();
7 return *instance;
8 }
9
10 private:
11 FileSystem() {}
12
13 };
- 延迟初始化
- C++11保证局部静态变量的初始化只进行一次
- 多线程安全
- 私有构造函数
继承单例(多平台):
1 class FileSystem
2 {
3 public:
4
5 static FileSystem& instance();
6
7 virtual ~FileSystem() {}
8
9 virtual char* readFile(char* path) = 0;
10 virtual void writeFile(char* path, char* contents) = 0;
11
12 protected:
13 FileSystem() {}
14
15 };
16
17 class PS3FileSystem : public FileSystem
18 {
19
20 public:
21 virtual char* readFile(char* path)
22 {
23 // Use Sony file IO API...
24 }
25
26 virtual void writeFile(char* path, char* contents)
27 {
28 // Use sony file IO API...
29 }
30 };
31
32 class WiiFileSystem : public FileSystem
33 {
34
35 public:
36 virtual char* readFile(char* path)
37 {
38 // Use Nintendo file IO API...
39 }
40
41 virtual void writeFile(char* path, char* contents)
42 {
43 // Use Nintendo file IO API...
44 }
45
46 };
Instance的编译跳转实现:
1 FileSystem& FileSystem::instance()
2 {
3
4 #if PLATFORM == PLAYSTATION3
5 static FileSystem *instance = new PS3FileSystem();
6 #elif PLATFORM == WII
7 static FileSystem *instance = new WiiFileSystem();
8 #endif
9
10 return *instance;
11 }
单例的缺陷:
- 全局变量,单例就是一个全局状态,只是被封装到了类中;
- 延迟初始化可能导致掉帧和卡顿,可能导致内存布局碎片化。
通过将全局对象类包装在现有类里来减少全局对象数量:
1 class Game
2 {
3
4 public:
5 static Game& instance() { return instance_; }
6
7 // Functions to set log_, et. al. ...
8
9 Log& getLog() { return *log_; }
10
11 FileSystem& getFileSystem() { return *fileSystem_; }
12
13 AudioPlayer& getAudioPlayer() { return *audioPlayer_; }
14
15 private:
16 static Game instance_;
17 Log *log_;
18 FileSystem *fileSystem_;
19 AudioPlayer *audioPlayer_;
20
21 };
22
23 Game::instance().getAudioPlayer().play(VERY_LOUD_BANG);
Chatper 7 状态模式
允许一个对象在其内部状态改变时改变自身的行为,对象看起来好像是在修改自身类。
复杂的分支和可变的状态是两种最容易出错的代码。
状态、输入和转换:
1. 拥有一组数目较小的状态,可以在这组状态之间切换;
2. 同一时刻只能处于一种状态;
3. 响应用户输入和游戏事件
定义一个接口,enter函数定义一些进入状态时的处理,exit函数定义一些状态改变前的处理:
1 class HeroineState
2 {
3
4 public:
5 virtual ~HeroineState() {}
6 virtual void handleInput(Heroine& heroine, Input input) {}
7 virtual void update(Heroine& heroine) {}
8
9 virtual void enter(Heroine& heroine) {}
10 virtual void exit(Heroine& heroine) {}
11
12 };
每一个状态都继承这个状态接口:
1 class DuckingState : public HeroineState
2 {
3
4 public:
5 DuckingState()
6 : chargeTime_(0)
7 {}
8
9 virtual void handleInput(Heroine& heroine, Input input) {
10 if (input == RELEASE_DOWN)
11 {
12 // Change to standing state...
13 heroine.setGraphics(IMAGE_STAND);
14 }
15 }
16
17 virtual void update(Heroine& heroine) {
18 chargeTime_++;
19 if (chargeTime_ > MAX_CHARGE)
20 {
21 heroine.superBomb();
22 }
23 }
24
25 private:
26 int chargeTime_;
27
28 };
主角类中有一个指针指向当前状态:
1 class Heroine
2 {
3
4 public:
5 virtual void handleInput(Input input)
6 {
7 state_->handleInput(*this, input);
8 }
9
10 virtual void update()
11 {
12 state_->update(*this);
13 }
14
15 // Other methods...
16
17 private:
18 HeroineState* state_;
19
20 };
静态状态(省CPU省内存):
1 class HeroineState
2 {
3
4 public:
5 static StandingState standing;
6 static DuckingState ducking;
7 static JumpingState jumping;
8 static DivingState diving;
9
10 // Other code...
11 };
12
13 if (input == PRESS_B)
14 {
15 heroine.state_ = &HeroineState::jumping;
16 heroine.setGraphics(IMAGE_JUMP);
17 }
实例化状态(handleInput方法返回后删除原状态):
1 void Heroine::handleInput(Input input)
2 {
3 HeroineState* state = state_->handleInput(*this, input);
4 if (state != NULL)
5 {
6 delete state_;
7 state_ = state;
8
9 // Call the enter action on the new state.
10 state_->enter(*this);
11 }
12 }
13
14 HeroineState* StandingState::handleInput(
15 Heroine& heroine, Input input)
16 {
17 if (input == PRESS_DOWN)
18 {
19 // Other code...
20 return new DuckingState();
21 }
22
23 // Stay in this state.
24 return NULL;
25 }
并发状态机(当两种状态没什么关系时):
1 class Heroine
2 {
3
4 // Other code...
5
6 private:
7 HeroineState* state_;
8 HeroineState* equipment_;
9
10 };
11
12 void Heroine::handleInput(Input input)
13 {
14 state_->handleInput(*this, input);
15 equipment_->handleInput(*this, input);
16 }
如果两种状态有一些联系(不能太多),需要对某些状态处理进行干预,可以做一些简单的if判断并特殊处理下。
层次状态机:
一个状态有父状态,如果子状态不处理就交给他的父状态处理。用来处理可能包含的大量相似状态。
1 class OnGroundState : public HeroineState
2 {
3
4 public:
5 virtual void handleInput(Heroine& heroine, Input input)
6 {
7 if (input == PRESS_B)
8 {
9 // Jump...
10 }
11 else if (input == PRESS_DOWN)
12 {
13 // Duck...
14 }
15 }
16 };
17
18 class DuckingState : public OnGroundState
19 {
20
21 public:
22 virtual void handleInput(Heroine& heroine, Input input)
23 {
24 if (input == RELEASE_DOWN)
25 {
26 // Stand up...
27 }
28 else
29 {
30 // Didn't handle input, so walk up hierarchy.
31 OnGroundState::handleInput(heroine, input);
32 }
33 }
34 };
下推自动机:

开火时push Firing,结束后pop掉开火状态,状态机自动返回开火前的状态。
来源:https://www.cnblogs.com/pandawuwyj/p/6256800.html