日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

游戏开发模式一:组件模式(Component)

發布時間:2025/3/15 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 游戏开发模式一:组件模式(Component) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

軟件設計模式告訴我們,程序中不同的領域要保持隔離,也就是解耦。所以,我們不希望AI,物理引擎,渲染引擎,聲音引擎,還有其他的事情影響到彼此,不能把他們放到同一個類里。

下面是一個反例:

if (collidingWithFloor() && (getRenderState() != INVISIBLE)) {playSound(HIT_FLOOR); }

如果有人要修改這段代碼,那么他就需要查看物理,繪圖,和聲音的代碼以保證不會出錯。更糟糕的情況是,你可能需要修改其他部分的代碼!

?

解決的辦法:

我們可以吧不同的領域分割城不同的組件,談后需要的時候持有這些組件的實例,例如?InputComponent。

?

再看一個難一點的例子:

class Bjorn { public:void update(World& world, Graphics& graphics){// Apply user input to hero's velocity.switch (Controller::getJoystickDirection()){case DIR_LEFT: velocity_ -= WALK_ACCELERATION; break;case DIR_RIGHT: velocity_ += WALK_ACCELERATION; break;}// Modify position by velocity.x_ += velocity_;world.resolveCollision(volume_, x_, y_, velocity_);// Draw the appropriate sprite.Sprite* sprite = &spriteStand_;if (velocity_ < 0) sprite = &spriteWalkLeft_;else if (velocity_ > 0) sprite = &spriteWalkRight_;graphics.draw(*sprite, x_, y_);}private:static const int WALK_ACCELERATION = 1;int velocity_;int x_, y_;Volume volume_;Sprite spriteStand_;Sprite spriteWalkLeft_;Sprite spriteWalkRight_; };

Bjorn?有一個?update()方法每一幀被調用一次。它獲取determine來決定方向,談后他用物理引擎來處理位置,最后,它把Bj?rn繪制到屏幕上。可以看到這里其實只做了很少的事情,但是卻顯得很復雜。

?

分割不同的領域:

首先讓我們把input分離:

class InputComponent { public:void update(Bjorn& bjorn){switch (Controller::getJoystickDirection()){case DIR_LEFT: bjorn.velocity -= WALK_ACCELERATION; break;case DIR_RIGHT: bjorn.velocity += WALK_ACCELERATION; break;}}private:static const int WALK_ACCELERATION = 1; };

Bjorn的變化:

class Bjorn { public:int velocity;int x, y;virtual void update(World& world, Graphics& graphics){input_.update(*this);// Modify position by velocity.x += velocity;world.resolveCollision(volume_, x, y, velocity);// Draw the appropriate sprite.Sprite* sprite = &spriteStand_;if (velocity < 0) sprite = &spriteWalkLeft_;else if (velocity > 0) sprite = &spriteWalkRight_;graphics.draw(*sprite, x, y);}private:InputComponent input_;Volume volume_;Sprite spriteStand_;Sprite spriteWalkLeft_;Sprite spriteWalkRight_; };

  然后我們把其他的組件都分離:

class PhysicsComponent { public:void update(Bjorn& bjorn, World& world){bjorn.x += bjorn.velocity;world.resolveCollision(volume_, bjorn.x, bjorn.y, bjorn.velocity);}private:Volume volume_; };

  

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_; };

  現在Bjorn變得很簡潔:

class Bjorn { public:int velocity;int x, y;virtual void update(World& world, Graphics& graphics){input_.update(*this);physics_.update(*this, world);graphics_.update(*this, graphics);}private:InputComponent input_;PhysicsComponent physics_;GraphicsComponent graphics_; };

  

現在我們已經把不同的組件都分開了,但是Bjorn依然知道這些行為的具體實現。我們將把我們的組件隱藏在借口背后,這樣就需要把InputComponent變成一個抽象類:

class InputComponent { public:virtual void update(Bjorn& bjorn) = 0; };

  然后實現它:

class PlayerInputComponent : public InputComponent { public:virtual void update(Bjorn& bjorn){switch (Controller::getJoystickDirection()){case DIR_LEFT: bjorn.velocity -= WALK_ACCELERATION; break;case DIR_RIGHT: bjorn.velocity += WALK_ACCELERATION; break;}}private:static const int WALK_ACCELERATION = 1; };

我們將持有一個InputComponent的指針,

class Bjorn { public:int velocity;int x, y;Bjorn(InputComponent* input): input_(input){}virtual void update(World& world, Graphics& graphics){input_->update(*this);physics_.update(*this, world);graphics_.update(*this, graphics);}private:InputComponent* input_;PhysicsComponent physics_;GraphicsComponent graphics_; };

  現在我們可以傳入一個InputComponent來實例化Bjorn:

Bjorn* bjorn = new Bjorn(new PlayerInputComponent());

  來看看InputComponent的另一個實現:

class DemoInputComponent : public InputComponent { public:virtual void update(Bjorn& bjorn){// AI to automatically control Bjorn...} };

  

?

好了,最后讓我們看看最簡介的一般實現:

我們有兩個component:

class PhysicsComponent { public:virtual void update(GameObject& obj, World& world) = 0; };class GraphicsComponent { public:virtual void update(GameObject& obj, Graphics& graphics) = 0; };

  一個GameObject:

class GameObject { public:int velocity;int x, y;GameObject(InputComponent* input,PhysicsComponent* physics,GraphicsComponent* graphics): input_(input),physics_(physics),graphics_(graphics){}virtual void update(World& world, Graphics& graphics){input_->update(*this);physics_->update(*this, world);graphics_->update(*this, graphics);}private:InputComponent* input_;PhysicsComponent* physics_;GraphicsComponent* graphics_; };

  

?

?

?

?

?

?

轉載于:https://www.cnblogs.com/shangdahao/archive/2013/04/02/2995051.html

總結

以上是生活随笔為你收集整理的游戏开发模式一:组件模式(Component)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。