14_ Component 游戏开发组件模式
# component 不同作用的程序需要保持互相隔离 我们不想ai 物理 渲染 声音 等等功能 耦合在一起,像下面这样 ``` //bad if (collidingWithFloor() && (getRenderState() != INVISIBLE)) { playSound(HIT_FLOOR); } ``` 一个 entity 可跨多个领域, 不同的领域保持隔离(component class), entity == container of component(组件的容器) ### when to use 1 一个对象使用多个功能, 你想不同功能互相隔离 2 一个类变得很大, 越来越难用 3 只想使用基类的某个功能,就需要把那个功能做成组建. 就不用继承它了 ##### 问题 组建通信 性能变低 ### Code ``` class GraphicsComponent { public: void update(Bjorn& bjorn, Graphics& graphics) { Sprite* sprite = &spriteStand_; if (bjorn.velocity < 0) { sprite = &spriteWalkLeft_; } else if (bjorn.velocity > 0) { sprite = &spriteWalkRight_; } graphics.draw(*sprite, bjorn.x, bjorn.y); } private: Sprite spriteStand_; Sprite spriteWalkLeft_; Sprite spriteWalkRight_; }; class PhysicsComponent{}; class InputComponent{} class PlayerInputComponent : public InputComponent {} class Bjorn { public: int velocity; int x, y; Bjorn(InputComponent* input, PhysicsComponent *phys, GraphicsComponent *graph) : input_(input), physics_(phys), graphics_(graph) {} void update(World& world, Graphics& graphics) { input_->update(*this); physics_.update(*this, world); graphics_.update(*this, graphics); } private: InputComponent* input_; PhysicsComponent physics_; GraphicsComponent graphics_; }; GameObject* createBjorn() { return new GameObject(new PlayerInputComponent(), new BjornPhysicsComponent(), new BjornGraphicsComponent()); } ``` ### How do components communicate with each other? 1 通过修改容器对象的状态(容器对象复杂,对状态的实现) 2 包含直接引用(快速, 但是组件实例耦合了) 3 通过发送消息(复杂, 解耦, 容器对象简单)