0

我正在使用 C# 和 XNA 4.0,以及 Farseer 物理引擎(非常类似于 Box2D),并且有一个 Block 类,我从中派生出 OBlock、LBlock 等。

块如下:

class Block
{
    public Body m_body;
    public virtual void Draw(SpriteBatch spriteBatch) { }

    public virtual void RemoveBody(World world)
    {
        //world.RemoveBody(m_body);
    }
}

我只放入了这些方法、字段等,因此我可以在列表中访问它们的覆盖版本

所以我的覆盖版本看起来像这样:OBlock.cs

class OBlock : Block
{

    private static Texture2D blockImg; //I load this in LoadContent so I don't have loads of Texture2Ds
    public new Body m_body; //Is this right?

    public OBlock(World world, Vector2 position)
    {
        m_body = BodyFactory.CreateBody(world, position); // Create the body, changing it from null
        FixtureFactory.AttachRectangle(Game1.blockSide *2, Game1.blockSide *2, 1.0f, new Vector2(0, 0), m_body); //This bit changes between classes
        m_body.BodyType = BodyType.Dynamic;

    }

    public override void RemoveBody(World world)
    {
        world.RemoveBody(m_body);
    }

    public static void LoadImage(Texture2D tex)
    {
        OBlock.blockImg = tex;
    }

    public override void Draw(SpriteBatch spriteBatch)
    {

        Vector2 position = m_body.Position * Game1.MetreInPixels;
        Vector2 origin = new Vector2(blockImg.Width / 2, blockImg.Height / 2);

        float rotation = m_body.Rotation;

        spriteBatch.Begin();

        spriteBatch.Draw(blockImg, position, null, Color.White, rotation, origin, Game1.BLOCK_SCALE, SpriteEffects.None, 1);

        spriteBatch.End();

        base.Draw(spriteBatch);
    }
}

除了我评论的那一点之外,还有 LBlock、ZBlock 等,它们看起来都非常相似。

然后我把它们都放进去

List<Block> blocks //As a field in Game1

blocks = new List<Block>(); // In LoadContent after loading images

我正在尝试做的是访问列表中任何 Block 的 m_body ,无论使用哪种类型

blocks[index].m_body.DOSTUFF();

显然 m_body 总是为空......

4

3 回答 3

2

公共新身体 m_body; //这是正确的吗?

不!这声明了第二个存储位 - 所以你有 Block 的 m_body 和 OBlock 的 m_body 并且你只将一个初始化为非空。对 m_body 的特定引用将解析为的确切规则可能太无聊而无法理解。

您可能应该完全删除上面的行并花一些时间熟悉继承的基础知识,例如http://msdn.microsoft.com/en-gb/library/ms173149.aspx

于 2013-02-03T09:29:12.593 回答
0
public new Body m_body; 

这隐藏了基类的 m_body。所以基本上你是在派生类(不是基类)中定义一个新的 m_body 实例。所以我认为这就是你的基类 m_body 为空的原因,因为它从未被初始化。

因此,请删除该特定行,因为对于每个派生类, m_body 已经定义为所有派生自 Block 类。阅读这篇 MSDN 文章了解更多详细信息。

于 2013-02-03T09:51:57.433 回答
0
public new Body m_body;

这个不对。m_body来自您的班级Block(您应该标记abstractbtw)在派生自它的所有班级中都是可见的。您现在正在做的事情被称为隐藏(在 imo 中应始终避免),这会导致各种并发症。

您现在已经做到了,每个OBlock人都有两个成员m_body,一个属于Block,一个属于OBlock。它使得任何时候你this.m_body在你的OBlock类中引用,你都在分配m_body属于的字段OBlock,而不是单独m_block声明。Block这是隐藏成员带来的奇怪并发症之一:

Block myBlock = new OBlock();
// myBlock.m_block is null, because myBlock is of type block, and remember,
// the m_block belonging to Block is never assigned to, only the one belonging
// to OBlock

而这将按预期工作:

OBlock myOBlock = new OBlock();
// myOBlock.m_block isn't null, because it was assigned to in the constructor.

所以避免隐藏!消除

public new Body m_body;

从你的代码文件中,你很高兴,因为m_block声明 inBlock无论如何都会被所有派生自它的类继承。

于 2013-02-03T10:34:56.453 回答