C# XNA - 当图形被收集后,请释放它们。
C# XNA - 当图形被收集后,请释放它们。
我一直遇到同样的问题,当玩家从游戏中收集一个物体后,它被移除,但游戏仍然认为它仍在那里,并抛出以下错误:\n
\n未处理的异常类型 \'System.ComponentModel.Win32Exception\' 发生在 System.Drawing.dll 中\n附加信息:操作成功完成\n
\n我已经阅读了一些其他帖子,它们似乎在说你应该在收集图形后使用Dispose()
来释放一些内存,但我不确定这是否是适合我的正确解决方案,也不知道如何做到这一点。\n上面的警告发生在我的Object类中(特别是突出显示public Obj(Vector2 pos)
这一行),如下所示。\n
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("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 () where T : Obj { // 如果检测到碰撞,返回碰撞对象;否则返回null。 return Items.objList .OfType () .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; } }
问题的原因是在C# XNA中,当收集了图形对象后,应该将其销毁,以释放内存空间。解决方法是在类的Dispose方法中添加代码来销毁对象。具体的解决方法是在类的Dispose方法中添加代码spriteIndex.Dispose()来销毁spriteIndex对象。另外,还需要将Dispose方法的访问修饰符修改为protected override。
代码实现如下:
protected override void Dispose(bool disposing) { spriteIndex.Dispose(); // any other object to dispose base.Dispose(disposing); }
这段代码应该添加在Obj类中。如果在添加后出现错误提示"Microsoft.Xna.Framework.Vector2 does not contain a definition for Dispose and no extension method Dispose accepting first argument of type",可以尝试将代码修改为spriteIndex.Dispose()。
如果修改后仍然出现警告提示"public override void Dispose(bool disposing) cannot change access modifiers when overriding protected inherited member Microsoft.Xna.Framework.Game.Dispose(bool)",可以将Dispose方法的访问修饰符修改为protected override void Dispose(bool disposing)。
最后,需要注意的是,如果在public Obj(Vector2 pos)
这一行出现了警告提示,可能是其他地方还有问题,需要进一步检查代码。