【问题标题】:C# XNA - Dispose graphics once they have been collectedC# XNA - 收集图形后处理图形
【发布时间】:2015-06-23 12:03:35
【问题描述】:

一段时间以来,我一直遇到同样的问题,一旦玩家从游戏中收集了一个对象,它就会被移除,但游戏仍然认为它在那里并抛出:

System.Drawing.dll 中出现“System.ComponentModel.Win32Exception”类型的未处理异常

附加信息:操作成功完成

我已经阅读了其他一些帖子,他们似乎在说您应该在收集图形后使用 Dispose() 删除图形以释放一些内存,但我不确定这是否是我的正确解决方案我也不知道该怎么做。

上面的警告出现在我的 Object 类中(它特别突出了 public Obj(Vector2 pos) 行,这可以在下面看到。

class Obj : Microsoft.Xna.Framework.Game
{
    public Vector2 position;
    public float rotation = 0.0f;
    public Texture2D spriteIndex;
    public string spriteName;
    public float speed = 0.0f;
    public float scale = 1.0f;
    public bool alive = true;
    public Rectangle area;
    public bool solid = false;

    public int score;


    public Obj(Vector2 pos)
    {
        position = pos;
    }

    private Obj()
    {

    }


    public virtual void Update()
    {
        if (!alive) return;

        UpdateArea();
        pushTo(speed, rotation);
    }



    public virtual void LoadContent(ContentManager content)
    {
        spriteIndex = content.Load<Texture2D>("sprites\\" + spriteName);
        area = new Rectangle((int)position.X - (spriteIndex.Width / 2), (int)position.Y - (spriteIndex.Height / 2), spriteIndex.Width, spriteIndex.Height);
    }


    public virtual void Draw(SpriteBatch spriteBatch)
    {
        if (!alive) return;

        Rectangle Size;
        Vector2 center = new Vector2(spriteIndex.Width / 2, spriteIndex.Height / 2);

        spriteBatch.Draw(spriteIndex, position, null, Color.White, MathHelper.ToRadians(rotation), center, scale, SpriteEffects.None, 0);
    }

    public bool Collision(Vector2 pos, Obj obj)
    {
        Rectangle newArea = new Rectangle(area.X, area.Y, area.Width, area.Height);
        newArea.X += (int)pos.X;
        newArea.Y += (int)pos.Y;

        foreach (Obj o in Items.objList)
        {
            if (o.GetType() == obj.GetType() && o.solid)
                if (o.area.Intersects(newArea))
                    return true;
        }
        return false;
    }

    public Obj Collision(Obj obj)
    {
        foreach (Obj o in Items.objList)
        {
            if (o.GetType() == obj.GetType())
                if (o.area.Intersects(area))
                    return o;
        }
        return new Obj();
    }

    public void UpdateArea()
    {
        area.X = (int)position.X - (spriteIndex.Width / 2);
        area.Y = (int)position.Y - (spriteIndex.Height / 2);
    }

    public T CheckCollisionAgainst<T>() where T : Obj
    {
        // If collision detected, returns the colliding object; otherwise null.
        return Items.objList
            .OfType<T>()
            .FirstOrDefault(o => o.area.Intersects(area));
    }

    public virtual void pushTo(float pix, float dir)
    {
        float newX = (float)Math.Cos(MathHelper.ToRadians(dir));
        float newY = (float)Math.Sin(MathHelper.ToRadians(dir));
        position.X += pix * (float)newX;
        position.Y += pix * (float)newY;
    }
}

【问题讨论】:

  • @Dave 这有点帮助,但我不确定我应该如何将它应用到我的游戏中以消除警告
  • 你在打电话给spritebatch.begin()spritebatch.end()吗?
  • @RobinDijkhof 不在 Object 类中(如上所示),我是否应该在 Draw(spriteIndex 之前调用 spriteBatch.Begin();,然后在之后调用 spriteBatch.End();
  • 不一定在那个位置,但在你用 spritbatch 绘制之前调用开始和当你准备好调用结束时。您可以在绘制循环之前调用开始(我假设您有多个对象)并在之后结束。

标签: c# memory-management xna drawing


【解决方案1】:

尝试一些类似的东西:

protected override void Dispose(bool disposing)
{
    spriteIndex.Dispose() 
    // any other object to dispose
    base.Dispose(disposing);
}

【讨论】:

  • 我应该在哪里添加这个?
  • 在你的类 Obj 中
  • 我已经这样做了,但是给出了一个错误提示“Microsoft.Xna.Framework.Vector2 不包含 Dispose 的定义并且没有扩展方法 Dispose 接受类型的第一个参数
  • 试试 spriteIndex.Dispose()
  • 唤醒了,但现在它告诉我 public override void Dispose(bool disposing) 在覆盖受保护的继承成员 Microsoft.Xna.Framework.Game.Dispose(bool) 时无法更改访问修饰符
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
  • 2010-11-15
  • 1970-01-01
  • 2011-05-03
相关资源
最近更新 更多