我最近开始使用 Microsoft XNA 和 C# 开发一款自娱自乐的小游戏。我的问题是关于设计游戏对象和继承它的对象。我将把游戏对象定义为可以在屏幕上呈现的东西。因此,为此,我决定创建一个基类,所有其他需要渲染的对象都将继承该基类,称为 GameObject。下面的代码是我制作的类:
class GameObject
{
private Model model = null;
private float scale = 1f;
private Vector3 position = Vector3.Zero;
private Vector3 rotation = Vector3.Zero;
private Vector3 velocity = Vector3.Zero;
private bool alive = false;
protected ContentManager content;
#region Constructors
public GameObject(ContentManager content, string modelResource)
{
this.content = content;
model = content.Load<Model>(modelResource);
}
public GameObject(ContentManager content, string modelResource, bool alive)
: this(content, modelResource)
{
this.alive = alive;
}
public GameObject(ContentManager content, string modelResource, bool alive, float scale)
: this(content, modelResource, alive)
{
this.scale = scale;
}
public GameObject(ContentManager content, string modelResource, bool alive, float scale, Vector3 position)
: this(content, modelResource, alive, scale)
{
this.position = position;
}
public GameObject(ContentManager content, string modelResource, bool alive, float scale, Vector3 position, Vector3 rotation)
: this(content, modelResource, alive, scale, position)
{
this.rotation = rotation;
}
public GameObject(ContentManager content, string modelResource, bool alive, float scale, Vector3 position, Vector3 rotation, Vector3 velocity)
: this(content, modelResource, alive, scale, position, rotation)
{
this.velocity = velocity;
}
#endregion
}
我省略了执行旋转、移动和绘制对象等操作的额外方法。现在,如果我想创建另一个对象,比如一艘船,我会创建一个继承 GameObject 的 Ship 类。示例代码如下:
class Ship : GameObject
{
private int num_missiles = 20; // the number of missiles this ship can have alive at any given time
private Missile[] missiles;
private float max_missile_distance = 3000f; // max distance a missile can be from the ship before it dies
#region Constructors
public Ship(ContentManager content, string modelResource)
: base(content, modelResource)
{
InitShip();
}
public Ship(ContentManager content, string modelResource , bool alive)
: base(content, modelResource, alive)
{
InitShip();
}
public Ship(ContentManager content, string modelResource, bool alive, float scale)
: base(content, modelResource, alive, scale)
{
InitShip();
}
public Ship(ContentManager content, string modelResource, bool alive, float scale, Vector3 position)
: base(content, modelResource, alive, scale, position)
{
InitShip();
}
public Ship(ContentManager content, string modelResource, bool alive, float scale, Vector3 position, Vector3 rotation)
: base(content, modelResource, alive, scale, position, rotation)
{
InitShip();
}
public Ship(ContentManager content, string modelResource, bool alive, float scale, Vector3 position, Vector3 rotation, Vector3 velocity)
: base(content, modelResource, alive, scale, position, rotation, velocity)
{
InitShip();
}
#endregion
}
同样,我省略了任何额外的特定于 Ship 的方法,例如发射导弹。你认为这种设计好还是应该改进或彻底改变?看起来子类的构造函数很乱,但也许这是唯一的方法。我从来没有做过这样的事情,我想知道我是否偏离了轨道。
感谢所有留下答案的人。他们都非常乐于助人。似乎普遍认为最好将其更改为使用 MVC 模式。我将进一步研究具体如何做到这一点。我还将删除大部分构造函数,并且将只有一个构造函数,因为 modelResource 之后的所有参数都不是创建对象所必需的,并且它们都可以在以后通过方法调用进行更改。
最佳答案
就我个人而言,我发现构造函数的绝对数量有点令人反感,但这是你的选择,从根本上没有错:)
关于从公共(public)基础派生游戏对象的一般策略,这是一种非常常见的做事方式。标准,甚至。我倾向于开始使用更类似于 MVC 的东西,使用仅包含数据的令人难以置信的轻量级“模型”游戏对象。
我在 XNA 中看到的其他常见方法包括/您可能想要考虑的事情:
- 实现 IRenderable 接口(interface),而不是在基类或派生类中执行任何呈现代码。例如,您可能想要永远不会渲染的游戏对象 - 路标或类似的东西。
- 您可以将基类抽象化,您可能永远都不想实例化 GameObject。
不过,还是小问题。你的设计很好。
关于c# - 设计游戏对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/180119/