/// <summary>
/// Erzeugt ein 2D Texture das zufällige Sternenbildungen hat.
/// </summary>
/// <param name="frequency">Angabe zur Dichte der Sternen.</param>
/// <returns>Gibt eine 2D Texture zurück.</returns>
public virtual Texture2D DrawStars(int frequency)
{
///Ermittle die Fenstergröße.
int winwidth = game.Window.ClientBounds.Width;
int winheight = game.Window.ClientBounds.Height;
///Erzeuge einen Color Array dass über den gesamten Feld sich erstreckt.
Color[] color = new Color[winwidth * winheight];
Random random = new Random(DateTime.Now.Millisecond);
///Sammlung der Farben die einmal verwendet wurden und deren Anzahl.
Dictionary<Color, int> exists = new Dictionary<Color,int>();
///Fülle Alles mit schwarze transparente Farbe.
for (int x = 0; x < winwidth; x++)
{
for (int y = 0; y < winheight; y++)
{
color[x+y*winwidth] = Color.TransparentBlack;
}
}
///Erzeuge ein Stern mit 5 Pixeln.
for (int i = 1; i <= winwidth*winheight/frequency; i++)
{
int x = random.Next(0, winwidth);
int y = random.Next(0, winheight);
Color c = this.RandomColor();
///Verhindere zu viele doppelte farben.
c = this.ColorDiffer(1, ref exists, c);
if ((x + 1) < winwidth)
color[x + 1 + y * winwidth] = c;
if ((x - 1) >= 0)
color[x - 1 + y * winwidth] = c;
if ((y + 1) < winheight)
color[x + (y + 1) * winwidth] = c;
if ((y - 1) >= 0)
color[x + (y - 1) * winwidth] = c;
color[x + y * winwidth] = c;
}
Texture2D t = new Texture2D(game.GraphicsDevice, winwidth, winheight);
t.SetData<Color>(color);
return t;
}
/// <summary>
/// Vergleiche ob die Farbe schon in eine Liste existiert und wie
/// oft diese gibt. Je nach Situation die Farbe neuauswählen.
/// </summary>
/// <param name="differ">Wie Oft darf die Farbe vorkommen.</param>
/// <param name="exists">Liste mit Farben.</param>
/// <param name="actual">Aktuelle Farbe.</param>
/// <returns></returns>
private Color ColorDiffer(int differ, ref Dictionary<Color, int> exists, Color actual)
{
if (exists.ContainsKey(actual))
{
int count = exists[actual];
/// Wenn die Anzahl der Farben zu groß ist, dann suche rekursive nach eine neue Farbe die
/// entweder noch nicht in der liste ist, oder schon vorhanden aber nicht so oft genutzt.
if (count > differ)
{
actual = this.RandomColor();
actual = this.ColorDiffer(differ, ref exists, actual);
}
else
{
exists[actual] += 1;
}
}
else
exists.Add(actual, 1);
return actual;
}
/// <summary>
/// Erzeugt eine zufällige Farbe.
/// </summary>
/// <returns></returns>
protected virtual Color RandomColor()
{
///Damit es nicht zu oft die selbe Farbe auftritt, wird für jeden Byte ein eigene Randomizer benutzt.
Random random = new Random(DateTime.Now.Millisecond * DateTime.Now.AddYears(new Random().Next(1, 12)).Millisecond);
Random random2 = new Random(random.Next() * random.Next());
Random random3 = new Random(random2.Next() * random2.Next());
Random random4 = new Random(random3.Next() * random2.Next() * random.Next());
byte r = (byte)random.Next(0, 255);
byte g = (byte)random2.Next(0, 255);
byte b = (byte)random3.Next(0, 255);
byte a = (byte)random4.Next(0, 255);
return new Color(r, g, b, a);
}