我目前正在以单一游戏创建一个2d平台游戏。 我创造了一个块,当玩家击中时,开始消失。当它消失时,我在它周围画一个矩形。每一块相同类型的瓷砖(BrittleTile)也会开始消失,直到整个连接的BrittleTiles暴徒都消失了。
问题在于,对于每一个被摧毁的BrittleTile,我的游戏运行速度明显变慢,直到它在10个左右的BrittleTiles被摧毁后成为幻灯片。我不知道是什么原因引起了这种情况,我一直试图简化类的Update方法,但似乎没有任何帮助。
有什么可能导致这种情况的想法吗?
class BrittleTile: Tile, IIncludeSound
{
public Rectangle DestroyedCheckRectangle;
private BrittleTile brittle;
private bool _isPlayed;
private bool _hasBroken;
private SoundEffect _sfxBreak;
private SoundEffectInstance _sfxiBreak;
private TimeSpan _breakTimer = new TimeSpan();
public Rectangle BrokenViewRectangle { get; set; }
private bool _isBreaking = false;
public BrittleTile(Texture2D texture, Rectangle baseViewRectangle, Rectangle brokenViewRectangle):base(texture, baseViewRectangle, true )
{
this.BrokenViewRectangle = brokenViewRectangle;
this.ViewRectangle = baseViewRectangle;
}
public void Update(GameTime gameTime, Hero hero, Entity[,] grid)
{
if (!this._hasBroken)
{
if (!this._isBreaking && !this._hasBroken && this.hasCollision)
_checkCollision(hero, grid);
if (this._isBreaking)
{
if (!this._isPlayed)
_sfxiBreak.Play();
this._isPlayed = true;
this._breakTimer += gameTime.ElapsedGameTime;
if (this._breakTimer.TotalMilliseconds < 250)
this.GhostMode(gameTime);
else
{
this._isBreaking = false;
this.hasCollision = false;
this._breakTimer -= this._breakTimer;
}
}
else
{
if (!this.hasCollision && this.DestroyedCheckRectangle.Width == 0)
{
this.DestroyedCheckRectangle.X = this.DestinationRectangle.X - 10;
this.DestroyedCheckRectangle.Y = this.DestinationRectangle.Y - 10;
this.DestroyedCheckRectangle.Height = this.DestinationRectangle.Height + 20;
this.DestroyedCheckRectangle.Width = this.DestinationRectangle.Width + 20;
this._hasBroken = true;
}
}
}
}
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(this.Texture, this.DestinationRectangle, this.BrokenViewRectangle, Color.White);
if (this.hasCollision)
spriteBatch.Draw(this.Texture, this.DestinationRectangle, this.ViewRectangle, Color.White * this.GhostDraw * 0.9f);
spriteBatch.Draw(this.Texture, DestroyedCheckRectangle, new Rectangle(1, 1, 1, 1), Color.Yellow);
Console.WriteLine(this.DestroyedCheckRectangle.X + ", " + this.DestroyedCheckRectangle.Y + ", " + this.DestroyedCheckRectangle.Width + ", " + this.DestroyedCheckRectangle.Height);
}
private void _checkCollision(Hero hero, Entity[,] grid)
{
if (this.DestinationRectangle.Intersects(hero.AttackHitBox))
{
this._isBreaking = true;
}
foreach (Shuriken star in hero.Stars)
{
if (this.DestinationRectangle.Intersects(star.DestinationRectangle))
this._isBreaking = true;
}
foreach (Entity entityObject in grid)
{
if (hasCollision && entityObject.GetType() == typeof(BrittleTile)){
brittle = entityObject.DeepCopy() as BrittleTile;
if (this.DestinationRectangle.Intersects(brittle.DestroyedCheckRectangle))
this._isBreaking = true;
}
}
}
override public void LoadSounds(ContentManager content)
{
this._sfxBreak = content.Load<SoundEffect>("SFX/brittleBreak");
_sfxiBreak = _sfxBreak.CreateInstance();
_sfxiBreak.Volume = 0.2f;
}
}
答案 0 :(得分:3)
首先,这一行:
if (!this._isBreaking && !this._hasBroken && this.hasCollision)
!this._hasBroken是多余的。
我的第一个警告标志是这一行:
brittle = entityObject.DeepCopy() as BrittleTile;
我假设DeepCopy()创建了该对象的新版本,并复制了它的所有属性,对吧?看到它的代码可能有助于确定它,但在这个假设上......
对于每一个瓷砖,你都会在你网格中的每个对象中循环,并且你将这个对象完全复制为一个BrittleTile,为什么?
我的第一个改变是修改该foreach以使其中包含此内容:
var brittle = entityObject as BrittleTile
if (brittle != null && hasCollision){
if (this.DestinationRectangle.Intersects(brittle.DestroyedCheckRectangle))
this._isBreaking = true;
}
}
不确定这是减速的主要原因,但这肯定是个问题。如果您正在克隆一个物体,然后立即扔掉一个物体,那么您几乎肯定会做错事。如果您正在克隆某个对象而您根本没有编辑该副本的属性(并使用这些编辑),那么您肯定做错了什么。在使用这样的方法之前我要小心谨慎,除非你真的确定这是你想要的。