C# XNA, Sternhimmel erzeugen.

roker002

Commander
Registriert
Dez. 2007
Beiträge
2.103
Ich habe mal außerhalb meiner Arbeit versucht mit XNA sich auseinander zu setzen. Wollte mal ein Sternenhimmel Zeichen in 2D. Irgendwie finde ich nichts passendes. Kann da jemand helfen?

PS: Ich will es nicht extern laden.
 
Ich hab vor einiger Zeit mal versucht einen 2D Space Shooter zu machen.

Als Hintergrund hab ich einfach einen in Paint erstellten schwarzen Hintergrund mit weißen Punkten genommen und dann wie hier beschrieben animiert.
 
Ich habe jetzt herumgebastelt und endlich fertig gemacht.


Code:
        /// <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);
        }


ah ja, wer mehr Weiß haben will, sollte r,g,b von 180 bis 255 durchlaufen lassen.


EDIT

Ich habe eine technische Frage.

Zur Kollisionserkennung benutze ich den Interface des GameObjects. Ich habe eine andere Klasse, die als Abstract gekennzeichnet ist, erstellt um die gesamten Grundfunktionen auszurüsten. Eigentlich kann man den Interface vergessen und durch Abstract Klasse komplett ersetzten. Ich möchte aber auf Interface nicht verzichten, weil es einfacher und Speicherplatzgünstiger um die Objekte zu vergleichen, z.B. wenn man die Kollision abfragt.

Wollte nur wissen ob es Programmiertechnisch OK ist. Naja es funktioniert alles so wie es ist, aber könnten später Probleme Auftauchen?
 

Anhänge

  • Unbenannt.png
    Unbenannt.png
    52,9 KB · Aufrufe: 201
Zuletzt bearbeitet:
Zurück
Oben