C# XNA游戏不是在非常奇怪的条件下启动的
首先要说的是,对不起,如果我遗漏了一些非常明显的东西,我还是个新手 不管怎么说,我一直在XNA的小行星克隆上工作,出于某种原因,如果我点击开始调试按钮,它有时不会启动。我将这个问题跟踪到我的Asternosmanager类,该类需要生成初始小行星的int、最小和最大速度以及旋转速度,以及小行星和粒子的两个纹理列表。现在奇怪的是:C# XNA游戏不是在非常奇怪的条件下启动的,c#,c#-4.0,xna,xna-4.0,C#,C# 4.0,Xna,Xna 4.0,首先要说的是,对不起,如果我遗漏了一些非常明显的东西,我还是个新手 不管怎么说,我一直在XNA的小行星克隆上工作,出于某种原因,如果我点击开始调试按钮,它有时不会启动。我将这个问题跟踪到我的Asternosmanager类,该类需要生成初始小行星的int、最小和最大速度以及旋转速度,以及小行星和粒子的两个纹理列表。现在奇怪的是: temp = new AsteroidManager(1, 20, 50, 1, 2, asteroids, particles, true); //With this
temp = new AsteroidManager(1, 20, 50, 1, 2, asteroids, particles, true); //With this constructor, the game always starts fine...
但如果我增加初始小行星的数量:
temp = new AsteroidManager(10, 20, 50, 1, 2, asteroids, particles, true); //This seems to start about 1/3 times in the Visual Studio debugger, but if I launch it without debugging or from the bin folder, it works fine.
最后,如果我将小行星设置为大于~20,它将不会在调试器中启动,如果我尝试从文件夹中启动它,进程将显示在任务管理器中,但不会发生任何事情。或者它只是在发射时崩溃。老实说,我不知道是什么导致了这种情况,如果需要的话,我很乐意提供任何代码,但以下是我认为相关的内容:
全职经理:
public class AsteroidManager
{
#region Declarations
public List<GameObject> Asteroids { get; set; }
public bool RegenerateAsteroids { get; set; }
public readonly int InitialAsteroids;
public readonly float MinVelocity;
public readonly float MaxVelocity;
public readonly float MinRotationalVelocity; //in degrees
public readonly float MaxRotationalVelocity; //in degrees
public readonly List<Texture2D> Textures;
public readonly List<Texture2D> ExplosionParticleTextures;
List<ParticleEmitter> emitters;
Random rnd;
const int MINPARTICLES = 50;
const int MAXPARTICLES = 200;
const int PARTICLEFTL = 40;
#endregion
public AsteroidManager(
int initialAsteroids,
float minVel,
float maxVel,
float minRotVel,
float maxRotVel,
List<Texture2D> textures,
List<Texture2D> explosionParticleTextures,
bool regenAsteroids)
{
rnd = new Random();
InitialAsteroids = initialAsteroids;
MinVelocity = minVel;
MaxVelocity = maxVel;
MinRotationalVelocity = minRotVel;
MaxRotationalVelocity = maxRotVel;
Textures = textures;
ExplosionParticleTextures = explosionParticleTextures;
RegenerateAsteroids = regenAsteroids;
Asteroids = new List<GameObject>();
emitters = new List<ParticleEmitter>();
for (int i = 0; i < InitialAsteroids; i++)
addAsteroid();
}
public void Update(GameTime gameTime)
{
for (int i = 0; i < Asteroids.Count; i++)
Asteroids[i].Update(gameTime);
for (int i = 0; i < emitters.Count; i++)
emitters[i].Update(gameTime);
if (Asteroids.Count < InitialAsteroids && RegenerateAsteroids)
addAsteroid();
}
public void Draw(SpriteBatch spriteBatch)
{
for (int i = 0; i < Asteroids.Count; i++)
Asteroids[i].Draw(spriteBatch);
for (int i = 0; i < emitters.Count; i++)
emitters[i].Draw(spriteBatch);
}
public void DestroyAsteroid(GameObject asteroid)
{
int x = rnd.Next(MINPARTICLES, MAXPARTICLES);
List<Color> colors = new List<Color>();
colors.Add(Color.White);
emitters.Add(new ParticleEmitter( //TODO: Test
x,
asteroid.WorldCenter,
ExplosionParticleTextures,
colors,
PARTICLEFTL,
true,
1,
x,
1f,
0.3f,
0f,
180f));
Asteroids.Remove(asteroid);
}
protected void addAsteroid()
{
GameObject tempAsteroid;
bool isOverlap = false;
do //Do-While to ensure that the asteroid gets generated at least once
{
Texture2D text = Textures.PickRandom<Texture2D>();
float rot = MathHelper.ToRadians((float)rnd.NextDouble(0f, 359f));
float rotVel = MathHelper.ToRadians((float)rnd.NextDouble(MinRotationalVelocity, MaxRotationalVelocity));
int colRadius = (((text.Width / 2) + (text.Height / 2)) / 2); //Get the mean of text's height & width
Vector2 vel = Vector2.Multiply( //calculate a random velocity
rot.RotationToVectorFloat(),
(float)rnd.NextDouble(MinVelocity, MaxVelocity));
Vector2 worldPos = new Vector2(
rnd.Next(Camera.WorldRectangle.X, Camera.WorldRectangle.Width),
rnd.Next(Camera.WorldRectangle.Y, Camera.WorldRectangle.Height));
tempAsteroid = new GameObject( //init a temporary asteroid to check for overlaps
text, worldPos, vel, Color.White, false, rot, rotVel, 1f, 0f, colRadius);
foreach (GameObject asteroid in Asteroids)
{
if (tempAsteroid.BoundingBox.Intersects(asteroid.BoundingBox))
{
isOverlap = true;
break;
}
}
} while (isOverlap); //if overlapping, loop
Asteroids.Add(tempAsteroid); //add the temp asteroid
}
}
游戏1更新:
protected override void Update(GameTime gameTime)
{
InputHandler.Update(); //update InputHandler
if (InputHandler.IsKeyDown(Keys.Left))
Camera.Position += new Vector2(-3f, 0f);
if (InputHandler.IsKeyDown(Keys.Right))
Camera.Position += new Vector2(3f, 0f);
if (InputHandler.IsKeyDown(Keys.Up))
Camera.Position += new Vector2(0f, -3f);
if (InputHandler.IsKeyDown(Keys.Down))
Camera.Position += new Vector2(0f, 3f);
fpsDisplay.Value = (int)Math.Round(1 / gameTime.ElapsedGameTime.TotalSeconds, 0);
//calculate framerate to the nearest int
temp.Update(gameTime);
base.Update(gameTime);
}
我猜你的重叠代码永远找不到放置小行星的位置。它进入了一个接近无限或可能无限的空间,如果空间被适当地覆盖,则循环永远不会退出。你可以使用一个计数器,在多次尝试后,它就放弃了。或者你可以增加他们可以产卵的游戏区域的最大大小,或者减少他们的大小;这将减少这种无限循环发生的可能性,但考虑到足够多的小行星,这并不是不可能的
int attempts = 0;
do //Do-While to ensure that the asteroid gets generated at least once
{
attempts++;
...
foreach (GameObject asteroid in Asteroids)
{
if (tempAsteroid.BoundingBox.Intersects(asteroid.BoundingBox))
{
isOverlap = true;
break;
}
}
} while (isOverlap && attempts < 20); //if overlapping, loop, give up after 20 tries
if (attempts == 20)
{
//log it! Or fix it, or something!
}
即使您通过增加游戏大小或减小小行星大小来解决此问题,我仍然建议您使其运行最大次数以避免无限循环。我猜您的重叠代码永远找不到放置小行星的位置。它进入了一个接近无限或可能无限的空间,如果空间被适当地覆盖,则循环永远不会退出。你可以使用一个计数器,在多次尝试后,它就放弃了。或者你可以增加他们可以产卵的游戏区域的最大大小,或者减少他们的大小;这将减少这种无限循环发生的可能性,但考虑到足够多的小行星,这并不是不可能的
int attempts = 0;
do //Do-While to ensure that the asteroid gets generated at least once
{
attempts++;
...
foreach (GameObject asteroid in Asteroids)
{
if (tempAsteroid.BoundingBox.Intersects(asteroid.BoundingBox))
{
isOverlap = true;
break;
}
}
} while (isOverlap && attempts < 20); //if overlapping, loop, give up after 20 tries
if (attempts == 20)
{
//log it! Or fix it, or something!
}
即使您通过增加游戏大小或减小小行星大小来解决此问题,我仍然建议您使其运行最大次数以避免无限循环。现在效果很好,谢谢!我甚至没有考虑过无限循环是个问题。当然要注意,如果它找不到小行星的位置,它就会被踢出。所以如果你指定了20颗小行星,你可能只会得到16颗。现在效果很好,谢谢!我甚至没有考虑过无限循环是个问题。当然要注意,如果它找不到小行星的位置,它就会被踢出。因此,如果你指定了20颗小行星,那么最终可能只有16颗。
int attempts = 0;
do //Do-While to ensure that the asteroid gets generated at least once
{
attempts++;
...
foreach (GameObject asteroid in Asteroids)
{
if (tempAsteroid.BoundingBox.Intersects(asteroid.BoundingBox))
{
isOverlap = true;
break;
}
}
} while (isOverlap && attempts < 20); //if overlapping, loop, give up after 20 tries
if (attempts == 20)
{
//log it! Or fix it, or something!
}