РЕДАКТИРОВАТЬ: Исправлена проблема. Я создал новый Рандом для каждого астероида, поэтому между ними не было достаточно времени. Но когда я прошел код вручную, было достаточно времени, чтобы не создать то же значение.
Вот код. Управляйте с помощью WASD, стреляйте с пробела и нажимайте «L», чтобы вызвать астероид.
https://github.com/Geblin/Monogame-Asteroids
Астероиды делятся на 2-3 меньших астероида при стрельбе, и это те меньшие, которые имеют одинаковые значения, хотя я даю им случайные. Я прошел через код, и кажется, что они изначально получают разные значения.
Вот класс Астероидов. Поэтому я ввожу масштаб и позицию, чтобы можно было создавать меньшие астероиды в разных позициях. Здесь выбирается случайный угол и скорость.
public Asteroid(Texture2D texture, float scale, Vector2 pos)
{
rand = new Random();
this.texture = texture;
this.scale = scale;
this.pos = pos;
angle = degreesToRadian(rand.Next(0,360));
direction = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
origin = new Vector2(texture.Width / 2, texture.Height / 2);
isVisible = true;
sourceRectangle = new Rectangle(0, 0, texture.Width, texture.Height);
boundingCircle = new BoundingCircle(pos, texture, scale);
speed = (float)rand.NextDouble() * (3 - 1) + 1;
setupRotation();
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, pos, sourceRectangle, Color.White, angle, origin, scale, SpriteEffects.None, 1f);
}
public void Update(GameTime gameTime)
{
boundingCircle.x = pos.X;
boundingCircle.y = pos.Y;
pos += direction * speed;
//Sets the asteroids bounds
if (pos.X > 2120)
pos.X = -200;
else if (pos.X < -200)
pos.X = 2120;
if (pos.Y > 1280)
pos.Y = -200;
else if (pos.Y < -200)
pos.Y = 1280;
angle += (float)rotationDirection;
}
public float degreesToRadian(int degrees)
{
float radian = (float)(Math.PI / 180) * degrees;
return radian;
}
//Sets a random rotation speed and rotation direction.
public void setupRotation()
{
rotationDirection = rand.NextDouble() * (0.01f - 0.005f) + 0.005f;
int x = rand.Next(2);
if (x == 1)
rotationDirection = -rotationDirection;
}
Вот класс астероидов. Метод SetRandomSpawn предназначен для первых астероидов. Те, которые появляются за окном и смещаются внутрь. В основном классе у меня есть код, который проверяет столкновения между лазерами и астероидами, а затем порождает меньшие в той же позиции.
public AsteroidSpawner(List<Asteroid> asteroidList)
{
rand = new Random();
this.asteroidList = asteroidList;
}
public void LoadContent(ContentManager content)
{
texture = content.Load<Texture2D>("Asteroid");
}
public void Draw(SpriteBatch spriteBatch)
{
foreach (Asteroid asteroid in asteroidList)
asteroid.Draw(spriteBatch);
}
public void Update(GameTime gameTime)
{
UpdateAsteroids(gameTime);
if (Keyboard.GetState().IsKeyDown(Keys.L))
SpawnAsteroid(SetRandomSpawn(), 1f, 1);
}
public void SpawnAsteroid(Vector2 pos, float scale, int amount)
{
for (int i = 1; i <= amount; i++)
{
Asteroid newAsteroid = new Asteroid(texture, scale, pos);
asteroidList.Add(newAsteroid);
}
}
public void UpdateAsteroids(GameTime gameTime)
{
foreach (Asteroid asteroid in asteroidList)
{
asteroid.Update(gameTime);
}
for (int i = 0; i < asteroidList.Count; i++)
{
if (!asteroidList[i].isVisible)
{
asteroidList.RemoveAt(i);
i--;
}
}
}
//Sets a random spawn outside of screen bounds
public Vector2 SetRandomSpawn()
{
int side = rand.Next(4);
//Each number represents a side
switch (side)
{
// Left
case 0:
return new Vector2(2120, rand.Next(0, 1080));
// Top
case 1:
return new Vector2(rand.Next(0, 1920), 1280);
// Right
case 2:
return new Vector2(-200, rand.Next(0, 1080));
//Bottom
case 3:
return new Vector2(rand.Next(0, 1920), -200);
default:
throw new ArgumentException("Incorrect CrystalTypeEnum");
}
}