C++ 在C+中为游戏对象设计类层次结构+;
我正在寻找一些关于为游戏对象设计类层次结构的建议。对于本次讨论,我将主要讨论两个特定的类。C++ 在C+中为游戏对象设计类层次结构+;,c++,oop,C++,Oop,我正在寻找一些关于为游戏对象设计类层次结构的建议。对于本次讨论,我将主要讨论两个特定的类。对象和精灵 对象是游戏中任何类型对象的基类Sprite直接继承自Object,但是Object的一些公共方法不再有意义。下面是一些代码来解释: class Object { public: Object() : renderer(NULL), controller(NULL), collider(NULL) { } virtual ~Object(); Renderer *getR
对象
和精灵
对象
是游戏中任何类型对象的基类Sprite
直接继承自Object
,但是Object
的一些公共方法不再有意义。下面是一些代码来解释:
class Object {
public:
Object() : renderer(NULL), controller(NULL), collider(NULL) { }
virtual ~Object();
Renderer *getRenderer() const;
Controller *getController() const;
Collider *getCollider() const;
void setRenderer(Renderer *renderer);
void setController(Controller *controller);
void setCollider(Collider *collider);
private:
Renderer *renderer;
Controller *controller;
Collider *collider;
};
对象
有三个组件:渲染器、碰撞器和控制器Sprite
当然有这三个组件,但是使用了spriteender
。我想我不希望为sprite类公开setRenderer
方法
因此,我认为我应该按照如下方式编写sprite类:
class Sprite : protected Object {
public:
Sprite(Texture *texture) : Object(), texture(texture) {
setRenderer(new SpriteRenderer(this));
}
Renderer *getRenderer() const;
Controller *getController() const;
Collider *getCollider() const;
void setController(Controller *controller);
void setCollider(Collider *collider);
private:
Texture *texture;
};
其中getter和setter只调用相关的对象
方法。但在这种情况下,我不能真正将精灵
用作对象
,例如,将其传递给接受对象
的函数
我的另一个实施方案是:
class Sprite : public Object {
public:
Sprite(Texture *texture) : Object(), texture(texture) {
setRenderer(new SpriteRenderer(this));
}
private:
Texture *texture;
};
它公开了setRenderer
方法
我的想法是,不应该公开setRenderer
方法,因为Sprite
是一个带有SpriteRenderer
的对象,因此如果它被更改,那么它就不是Sprite
。然而,我看不到一个明显的方法来阻止它改变
总的来说,这是我不应该担心的事情,还是有其他方法来进行此设计?不要使用getter和setter对对象进行建模,而是让对象实际执行您想要的操作——您不必担心在没有setter时暴露setter。:)
例如,让对象自身渲染,而不是返回渲染器。这样,精灵就可以覆盖这种行为:
class Object {
virtual void render() = 0;
}
class Sprite : public Object {
void render() {
// use a SpriteRenderer
}
}
不要使用getter和setter对对象进行建模,而是让对象实际执行您想要的操作——您不必担心在没有setter的情况下暴露setter。:)
例如,让对象自身渲染,而不是返回渲染器。这样,精灵就可以覆盖这种行为:
class Object {
virtual void render() = 0;
}
class Sprite : public Object {
void render() {
// use a SpriteRenderer
}
}
您应该问问自己:是否需要在运行时更改渲染器(和其他组件)?我相信在创建对象实例之后不需要这样做。因此,我根本不会将方法setRenderer(和其他setXXX)放在公共API中。
您需要公开这些参数吗?如果是,我可以提出以下建议:
这样你就有了一个很好的不可变类
为了构造精灵实例,您可能需要SpriteFactory或SpriteBuilder
类精灵:公共对象
{
公众:
精灵(常量渲染器和渲染器,常量精灵指定CSTUFF和素材):
对象(渲染器),
...
{
}
};
类SpriteBuilder
{
公众:
void set渲染器(常量渲染器*渲染器);
void setPriteSpecificStuff();
std::auto_ptr build();
};
同样,使用构建器,您将拥有一个很好的不可变类,您应该问问自己:是否需要在运行时更改渲染器(和其他组件)?我相信在创建对象实例之后不需要这样做。因此,我根本不会将方法setRenderer(和其他setXXX)放在公共API中。
您需要公开这些参数吗?如果是,我可以提出以下建议:
这样你就有了一个很好的不可变类
为了构造精灵实例,您可能需要SpriteFactory或SpriteBuilder
类精灵:公共对象
{
公众:
精灵(常量渲染器和渲染器,常量精灵指定CSTUFF和素材):
对象(渲染器),
...
{
}
};
类SpriteBuilder
{
公众:
void set渲染器(常量渲染器*渲染器);
void setPriteSpecificStuff();
std::auto_ptr build();
};
同样,使用构建器,您将拥有一个很好的不可变类。在我关于多重继承的评论中,您可以将对象看作是一些可渲染的对象,一些可碰撞的对象,一些可“控制”(无论在您的系统中意味着什么)。因此,您可以为每个功能使用一个基类,而不是使用一个包含所有这三个属性(可能更多)的基类对象
class Renderable
{
public:
Renderable(Rendered *renderer) : remderer_(renderer) {}
Renderer *getRenderer() const;
void setRenderer(Renderer *renderer);
private:
Renderer *renderer_;
}
class Controllable
{
public:
Controllable(Constroller &constroller) : controller_(constroller) {}
Controller *getController() const;
void setController(Controller *controller);
private:
Controller *controller_;
};
class Collidable {
public:
Collidable(Collider *collider) : collider_(collider) {}
Collider *getCollider() const;
void setCollider(Collider *collider);
private:
Collider *collider_;
};
然后,Sprite
类拥有这三种功能,您将继承这三种功能:
class Sprite : public Renderable, public Controllable, public Collidable
{
public:
Sprite()
: Renderable(new SpriteRenderer) // Supply special renderer
{}
private:
// Disallow users of the `Sprite` class to call this function;
using Renderable::setRenderer;
};
这个系统有能力类,在游戏世界中创建“对象”时工作得非常好。以一个幻想风格的游戏为例,你有一个类剑
,它继承了武器
,可穿戴
和可携带
,这意味着剑可以用作武器,可以佩戴和携带。根据我关于多重继承的评论,你可以将对象看作是可渲染的,有些是能够碰撞的,有些是“受控的”(无论在你的系统中意味着什么)。因此,您可以为每个功能使用一个基类,而不是使用一个包含所有这三个属性(可能更多)的基类对象
class Renderable
{
public:
Renderable(Rendered *renderer) : remderer_(renderer) {}
Renderer *getRenderer() const;
void setRenderer(Renderer *renderer);
private:
Renderer *renderer_;
}
class Controllable
{
public:
Controllable(Constroller &constroller) : controller_(constroller) {}
Controller *getController() const;
void setController(Controller *controller);
private:
Controller *controller_;
};
class Collidable {
public:
Collidable(Collider *collider) : collider_(collider) {}
Collider *getCollider() const;
void setCollider(Collider *collider);
private:
Collider *collider_;
};
然后,Sprite
类拥有这三种功能,您将继承这三种功能:
class Sprite : public Renderable, public Controllable, public Collidable
{
public:
Sprite()
: Renderable(new SpriteRenderer) // Supply special renderer
{}
private:
// Disallow users of the `Sprite` class to call this function;
using Renderable::setRenderer;
};
这个系统有能力类,在游戏世界中创建“对象”时工作得非常好。以一个幻想风格的游戏为例,你有一个类剑
,它继承了武器
,可穿戴
和携带
,这意味着剑可以用作武器,可以佩戴和携带。为什么不在具体对象上分离特征,然后使用多重继承?例如:RenderableObject
s包含渲染所需的所有内容,physicobject
s包含物理所需的所有内容,AliveObject
s用于所有活动对象。如果你需要一堵隐形墙,你可以