Anzeige

Performance - Tipps gesucht

#1
Hallo zusammen,

zunächst einmal weiß ich nicht, ob ich die Anfrage ins richtige Forum gesteckt habe, bitte dies falls nicht zu entschuldigen.

Ich habe ein kleines Spiel in Anlehung an ATARI Asteroids geschrieben, funktioniert auch alles ganz gut, Eine ganze Menge Objekte fliegen in der Gegend rum und können abgeschossen oder eingesammelt werden.
Grundsätzliche Sorge hat mir die Performance gemacht, da bei der Prüfung, ob ein Geschoss jetzt einen Meteoriten trifft oder ein Meteorit das Raumschiff ja eine ganze Menge abfragen laufen. Ich habe das über Rectangle.IntersectsWith() gelöst.

Die ganze Sache wird im Timer (der alle 0,05 Sekunden tickt )überwacht der ja im Form sitzt(daher das Forum Forms).
Es laufen also einige Schleifen, die jeweils Prüfen, ob sich die Rectangles überschneiden. (In den Rectangles befinden sich die Sprites).

Hier mal der Code dazu:

Code:
List<GalacticObjects> gos=new List<GalacticObjects>();


//Timer
        private void timer1_Tick(object sender, EventArgs e)
        {
            foreach (GalacticObject o in gos)
            {
                if (o is Bullet) 
                {//Prüfe ob Schüsse ihr Ziel erreichen
                    foreach (GalacticObject m in gos)
                    {
                        if (m is Meteor || m is Splinter )
                        {
                            if (o.Rect.IntersectsWith(m.Rect)) 
                            { 
                                //Blabla   
                            }
                        }
                        if (m is ExplosiveMeteor)
                        {  
                            if (o.Rect.IntersectsWith(m.Rect))
                            {
                               //Blabla                          
                            }
                        }
                    }
                 }
                else { o.checkHit(spaceship); }
            }
            Refresh();
            if (spaceship.Explode)
            {
             gos.Clear(); 
             if (explosionCounter < 9)
                {//Animation der Explosion
                    //blabla
                }
                else
                {                    
                    //Anweisungen
                }
            }
            else
            {
                for (int i = 0; i < gos.Count; i++)
                { 
                    if (gos[i].BreakUp)
                    {//Meteoritensplitter erzeugen
                    for (int a = 1; a < 4; a++)
                        {
                            GalacticObject s = new Splinter(game, Width, Height, gos[i].Rect,a);
                            gos.Add(s);
                        }
                    }
                    if (gos[i].DeleteMe) { gos.RemoveAt(i); } //zerstörte Objekte löschen
                }
            }
            spaceship.Move(Width,Height);
            Refresh();

             
            counter++;
        }//Ende Timer
Alle Objekte erben vob GalacticObject, Bullets können fliegende Objekte treffen und zerstören, fliegende Objekt zerstören das Raumschiff.

Die Frage die sich mir jetzt stellt ist, ob das Ganze auch eleganter gemacht werden kann, sprich Ressourcenschonender?
Vm Aufruf des GarbageCollectors habe ich abgesehen, da ich so häufig gelesen habe, dass man ohnehin keine Kontrolle hat, wann dann die Objekte entsorgt werden und den Speicherplatz wieder freigeben.

Auf meinem System (16GB RAM) läuft das Ganze ohne Murren, bei Geräten mit nur 3 stockt es aber gehörig.

Für jeden sachdienlichen Hinweis bin ich sehr dankbar. ;)
 

ksk

Erfahrenes Mitglied
#2
Timer eignet sich in diesem Fall eher nicht. Ich würde all deine Abfragen (ob ein Meteorit ein Schifft trifft oder ein Geschoss das Meteorit usw.) in die OnPaint-Methode hinein tun da es dafür ambesten geeignet ist.
DoubleBuffering noch aktivieren.
Code:
            this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.UserPaint |
                          ControlStyles.AllPaintingInWmPaint |
                          ControlStyles.ResizeRedraw |
                          ControlStyles.ContainerControl |
                          ControlStyles.OptimizedDoubleBuffer |
                          ControlStyles.SupportsTransparentBackColor, true);
 
Anzeige
Anzeige