myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE
   » Gadget für Windows
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin

Ressourcen
» guide to C#
» openbook: Visual C#
» openbook: OO
» MSDN Webcasts
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » GUI: Windows-Forms » Nach einer bestimmten Zeit zusätzliche Kreise zeichnen
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Nach einer bestimmten Zeit zusätzliche Kreise zeichnen

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
RingYK RingYK ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.01.2017
Beiträge: 9
Entwicklungsumgebung: .Net (C#)


RingYK ist offline

Nach einer bestimmten Zeit zusätzliche Kreise zeichnen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

 [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox)  [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox) Hallo,

ich bin Anfängfer und bin gerade dabei das Spiel "Asteroids" nachzuprogrammieren.
Es läuft ganz gut, jedoch habe ich ein paar Probleme.

Die Asteroiden sind bei mir Kreise, die ich in einer pictureBox zeichnen lasse, wenn ich auf den "Start"-Button drücke.
Diese lasse ich dann mit einem Timer nach unten bewegen.
Jedoch möchte ich, dass immer nach einem bestimmten Zeitabschnitt wieder neue Kreise gezeichnet werden...
Ich habe das schon mit einem zweiten Timer und einer zweiten pictureBox probiert, aber es will alles nicht hinhauen... :(
Habt ihr Anhaltspunkte?

Mein Code vom Start-Button:

C#-Code:
  private void buttonStart_Click(object sender, EventArgs e)
        {
            timerAsteroid.Start();
            Random Rnd = new Random();
            int RndNumber2 = Rnd.Next(8, 20);

            if (checkBox1.Checked == true)
            {
                triangle = new Triangle() { X = 300, Y = 550, Vx = (int)numericUpDown4.Value, Vy = (int)numericUpDown4.Value, D1 = (int)numericUpDown5.Value, D2 = (int)numericUpDown6.Value, D3 = (int)numericUpDown7.Value, Alpha = (int)numericUpDown8.Value };
                listBox1.Items.Add(triangle);
                pictureBox1.Refresh();
            }
            else if(checkBox2.Checked == true)
            {
                rectangle = new Rectangle() { X = 300, Y = 555, Width = (int)numericUpDown2.Value, Height = (int)numericUpDown3.Value, Vx = (int)numericUpDown4.Value, Vy = (int)numericUpDown4.Value};
                listBox1.Items.Add(rectangle);
                pictureBox1.Refresh();
            }
            for (int i = 0; i < RndNumber2; i++)
            {
                int rndnumber1 = Rnd.Next(0, 1600);
                Asteroid asteroids = new Asteroid() { X = rndnumber1, Radius = (int)numericUpDown1.Value, Height = (int)numericUpDown1.Value * 2, Width = (int)numericUpDown1.Value * 2 };
                listBox1.Items.Add(asteroids);
                pictureBox1.Refresh();
            }
        }

Mein Code in Form1.cs (Ausschnitt):

C#-Code:
  private void timerMoving_Tick(object sender, EventArgs e)
        {
            TimeSpan elapsed = DateTime.Now - lastPaint;
            double resultSeconds = elapsed.TotalSeconds;

            List<Shot> toDisposeShot = new List<Shot>();
            List<Asteroid> toDisposeAsteroid = new List<Asteroid>();

            foreach (Object item in listBox1.Items)
            {
                Triangle triangle = item as Triangle;
                Rectangle rectangle = item as Rectangle;
                Asteroid asteroid = item as Asteroid;
                Shot shot = item as Shot;
                spaceship = item as Spaceship;

                #region Zusammenführung
                if (item is Spaceship)
                {
                    Spaceship geoObject = item as Spaceship;
                    if (objPosition == Position.Left)
                    {
                        geoObject.Vx -= 10;
                    }
                    if (objPosition == Position.Right)
                    {
                        geoObject.Vx += 10;
                    }
                    if (objPosition == Position.Up)
                    {
                        geoObject.Vy -= 10;
                    }
                    if (objPosition == Position.Down)
                    {
                        geoObject.Vy += 10;
                    }
                    if (geoObject.X <= 0 && geoObject.Vx < 0 || geoObject.X <= 0 && geoObject.Vy < 0)
                    {
                        geoObject.Vx = 0;
                        geoObject.Vy = 0;
                        geoObject.X = 0;
                    }
                    if (geoObject.Y <= 0 && geoObject.Vy < 0 || geoObject.Y <= 0 && geoObject.Vx < 0 || geoObject.Y <= 0 && geoObject.Vx > 0)
                    {
                        geoObject.Vy = 0;
                        geoObject.Vx = 0;
                        geoObject.Y = 0;
                    }
                    if (geoObject.X >= pictureBox1.Width - geoObject.Width && geoObject.Vx > 0 || geoObject.X >= pictureBox1.Width - geoObject.Width && geoObject.Vy > 0 || geoObject.X >= pictureBox1.Width - geoObject.Width && geoObject.Vy < 0)
                    {
                        geoObject.Vx = 0;
                        geoObject.Vy = 0;
                        geoObject.X = pictureBox1.Width - geoObject.Width;
                    }
                    if (geoObject.Y >= pictureBox1.Height - geoObject.Height && geoObject.Vy > 0 || geoObject.Y >= pictureBox1.Height - geoObject.Height && geoObject.Vx > 0 || geoObject.Y >= pictureBox1.Height - geoObject.Height && geoObject.Vx < 0)
                    {
                        geoObject.Vy = 0;
                        geoObject.Vx = 0;
                        geoObject.Y = pictureBox1.Height - geoObject.Height;
                    }
                    geoObject.X += geoObject.Vx * resultSeconds;
                    geoObject.Y += geoObject.Vy * resultSeconds;

                //    if (geoObject.X < 0)
                //    {
                //        geoObject.X = 0;
                //    }
                //    if (geoObject.Y < 0)
                //    {
                //        geoObject.Y = 0;
                //    }
                //    if (geoObject.X > pictureBox1.Width - geoObject.Width)
                //    {
                //        geoObject.X = pictureBox1.Width - geoObject.Width;
                //    }
                //    if (geoObject.Y > pictureBox1.Height - geoObject.Height)
                //    {
                //        geoObject.Y = pictureBox1.Height - geoObject.Height;
                //    }
                }
                #endregion
                else if (asteroid != null)
                {
                    if (asteroid.Kmy > pictureBox1.Height)
                    {
                        toDisposeAsteroid.Add(asteroid);
                    }
                    else
                    {
                        asteroid.Vy += 2;
                        asteroid.Y += asteroid.Vy * resultSeconds;
                    }
                }
                else if (shot != null)
                {
                    if (objShoot == true)
                    {
                        if (shot.X < 0 || shot.Y < 0)
                        {
                            toDisposeShot.Add(shot);
                        }
                        else
                        {
                            shot.Y += shot.Vy * resultSeconds;
                            shot.X += shot.Vx * resultSeconds;
                        }
                    }
                }
            }
            lastPaint = DateTime.Now;
            for (int i = 0; i < toDisposeShot.Count; i++)
            {
                var shot = toDisposeShot[i];
                listBox1.Items.Remove(shot);
                shot.Dispose();
            }
            for (int i = 0; i < toDisposeAsteroid.Count; i++)
            {
                var asteroid = toDisposeAsteroid[i];
                listBox1.Items.Remove(asteroid);
                asteroid.Dispose();
            }
            //pictureBox1.Refresh();
            UpdatePictureBox();
        }
        public void timerAsteroid_Tick(object sender, EventArgs e)
        {
            //    if (asteroid != null)
            //    {
            //        Random Rnd = new Random();
            //        int RndNumber3 = Rnd.Next(8, 30);

            //        List<GeometricObject> NewAsteroids = new List<GeometricObject>();
            //        for (int i = 0; i < RndNumber3; i++)
            //        {
            //            int RndNumber1 = Rnd.Next(0, 1600);
            //            asteroid = new Asteroid() { X = RndNumber1, Radius = (int)numericUpDown1.Value, Height = (int)numericUpDown1.Value * 2, Width = (int)numericUpDown1.Value * 2 };
            //            listBox1.Items.Add(asteroid);
            //            //NewAsteroids.Add(asteroid);

            //            foreach (object item in listBox1.Items)
            //            {
            //                GeometricObject asteroid = item as GeometricObject;
            //                if (asteroid != null)
            //                {
            //                pictureBox2.Refresh();
            //                }
            //            }
            //            UpdatePictureBox();
            //    }
            //}
            ////pictureBox1.Refresh();
            //UpdatePictureBox();

            pictureBox2.Refresh();
        }
        private void pictureBox2_Paint(object sender, PaintEventArgs e)
        {
            List<GeometricObject> NewAsteroid = new List<GeometricObject>();
            Random Rnd = new Random();
            int RndNumber1 = Rnd.Next(0, 1600);

            asteroid = new Asteroid() { X = RndNumber1, Radius = (int)numericUpDown1.Value, Height = (int)numericUpDown1.Value * 2, Width = (int)numericUpDown1.Value * 2 };
            NewAsteroid.Add(asteroid);

        }
        private void UpdatePictureBox()
        {
            if (pictureBox1.Image == null) pictureBox1.Image = new Bitmap(2400, 2050);

            List<GeometricObject> toDeleteSpaceship = new List<GeometricObject>();

            using (var g = Graphics.FromImage(pictureBox1.Image))
            {
                g.DrawImage(Resources.weltraum001_1400x1050, 0, 0);

                // grap all astroids
                List<GeometricObject> astroids = new List<GeometricObject>();
                foreach (var item in listBox1.Items)
                {
                    if (item is Asteroid)
                    {
                        astroids.Add((Asteroid)item);
                    }
                }
                foreach (Object item in listBox1.Items)
                {
                    Spaceship rectangle = item as Spaceship;
                    Spaceship triangle = item as Spaceship;
                    Spaceship spaceship = item as Spaceship;
                    GeometricObject asteroid = item as GeometricObject;
                    GeometricObject shot = item as GeometricObject;

                    if (triangle != null)
                    {
                        triangle.Draw(g);
                    }
                    if (rectangle != null)
                    {
                        rectangle.Draw(g);
                    }
                    if (asteroid != null)
                    {
                        asteroid.Draw(g);
                    }

                    if (item is Spaceship)
                    {
                        var collison = ((Spaceship)item).CheckCollison(astroids);
                        if (collison != null)
                        {
                            toDisposeSpaceship.Add(spaceship);
                            MessageBox.Show("Bum, das Raumschiff wurde zerstört durch: " + collison.Object2.ToString());
                            //toDeleteAfterShot();
                        }
                        if (item is Shot)
                        {
                            if (objShoot == true)
                            {
                                shot.Draw(g);
                            }
                        }
                    }
                }
                      pictureBox1.Refresh();
            }
        }

Gruß und Danke im Vorraus! :D
12.01.2017 10:08 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
wcseller wcseller ist männlich
myCSharp.de-Mitglied

Dabei seit: 14.09.2008
Beiträge: 161


wcseller ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Beschäftige Dich mal mit dem Thema Debugging/Debugger - damit solltest Du den/die Fehler finden können. Ich denke nicht, dass Dir hier jemand diese Arbeit abnehmen möchte/wird...
12.01.2017 10:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
RingYK RingYK ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.01.2017
Beiträge: 9
Entwicklungsumgebung: .Net (C#)

Themenstarter Thema begonnen von RingYK

RingYK ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wenn ich debugge, geht der Programmablauf gar nicht erst in den "TimerAsteroid_Tick"-Event hinein....
12.01.2017 10:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
RingYK RingYK ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.01.2017
Beiträge: 9
Entwicklungsumgebung: .Net (C#)

Themenstarter Thema begonnen von RingYK

RingYK ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Es muss ja auch keiner eine Komplettlösung hier schreiben.
Aber ein paar Anhaltspunkte, wie ich das schaffen könnte wäre echt nett. :)
12.01.2017 10:42 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
pinki
myCSharp.de-Mitglied

images/avatars/avatar-4072.jpg


Dabei seit: 24.08.2008
Beiträge: 406
Herkunft: Minden


pinki ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hast du evtl. den Timer nicht gestartet oder den EventHandler nicht ans Event gehängt?
12.01.2017 10:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Coffeebean Coffeebean ist männlich
myCSharp.de-Team

images/avatars/avatar-3295.gif


Dabei seit: 25.08.2011
Beiträge: 1.901
Entwicklungsumgebung: VS 2005-2017, VS Code
Herkunft: Deutschland/Schweiz


Coffeebean ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo RingYK,

du startest den Timer zwar, aber sagst ihm nie, dass er beim Ablauf auch in die Methode soll. Zumindest ist das in dem Code oben nicht ersichtlich.

Gruss

Coffeebean
12.01.2017 10:51 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
RingYK RingYK ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.01.2017
Beiträge: 9
Entwicklungsumgebung: .Net (C#)

Themenstarter Thema begonnen von RingYK

RingYK ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo @Coffeebean,

Ich dachte mit "pictureBox2.Refresh()" sage ich, dass er dahingehen soll?

In der pictureBox habe ich noch hinzugefügt:

C#-Code:
  foreach (object item in NewAsteroid)
            {
                GeometricObject asteroid = item as GeometricObject;

                if (asteroid != null)
                {
                    asteroid.Draw(e.Graphics);

                }
            }
            pictureBox2.Refresh();

Leider klappt auch das nicht...
12.01.2017 11:31 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
p!lle
myCSharp.de-Mitglied

images/avatars/avatar-3556.jpg


Dabei seit: 22.02.2007
Beiträge: 727
Entwicklungsumgebung: Visual Studio (Community) 2017


p!lle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Coffeebean meint, ob du den Eventhandler für das Ticken des Timers angemeldet hat.
 Timer.Tick-Ereignis
12.01.2017 11:38 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
RingYK RingYK ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.01.2017
Beiträge: 9
Entwicklungsumgebung: .Net (C#)

Themenstarter Thema begonnen von RingYK

RingYK ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Also in meinem Form1.Designer.cs sieht es folgendermaßen aus:

C#-Code:
  // timerAsteroid
            //
            this.timerAsteroid.Enabled = true;
            this.timerAsteroid.Interval = 4000;
            this.timerAsteroid.Tick += new System.EventHandler(this.timerAsteroid_Tick);
            //

Mit "timerMoving" sieht es auch so aus und der funktioniert ja...
12.01.2017 13:30 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

images/avatars/avatar-2981.png


Dabei seit: 20.07.2008
Beiträge: 10.180
Herkunft: Süddeutschland


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hast Du mal den Debugger aufgerufen, ob überhaupt das in der Reihenfolge und mit den Informationen ausgeführt wird, wie Du Dir das im Kopf vorstellst?
 [Artikel] Debugger: Wie verwende ich den von Visual Studio?

Zur Not mal Dir den Workflow auf ein Blatt papier, dann sieht man oft einen Denkfehler leicht als im Code.
Danach Debugger anwerfen und schauen, ob der erdachte Workflow so auch umgesetzt wurde.
12.01.2017 13:35 Beiträge des Benutzers | zu Buddylist hinzufügen
p!lle
myCSharp.de-Mitglied

images/avatars/avatar-3556.jpg


Dabei seit: 22.02.2007
Beiträge: 727
Entwicklungsumgebung: Visual Studio (Community) 2017


p!lle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von RingYK:
this.timerAsteroid.Enabled = true;

Auch wenn es wahrscheinlich nicht das Problem löst:
Wenn ein Timer manuell (per Start-Methode) gestartet werden soll, dann muss Enabled auf jeden Fall erstmal auf false stehen - ist der Wert true, startet der Timer sofort.
12.01.2017 13:44 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
RingYK RingYK ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.01.2017
Beiträge: 9
Entwicklungsumgebung: .Net (C#)

Themenstarter Thema begonnen von RingYK

RingYK ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke @p!lle, ich habe es angepasst. ^^

Soo, jetzt habe ich es soweit, dass er in den Timer geht, auf einen neuen Kreis verweist und dann in die Draw-Methode des Kreises hineingeht. Aber genau dann gibt er mir eine Null-Referenz züruck...

Also:

Fehlermeldung:
Additional information: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.

Hier mein Code:

C#-Code:
  public void timerAsteroid_Tick(object sender, EventArgs e)
        {
               NewAsteroids(g);
        }
        public void NewAsteroids(Graphics g)
        {
            List<GeometricObject> NewAsteroid = new List<GeometricObject>();
            Random Rnd = new Random();
            int RndNumber1 = Rnd.Next(0, 1600);

            Asteroid asteroid = new Asteroid() { X = RndNumber1, Radius = (int)numericUpDown1.Value, Height = (int)numericUpDown1.Value * 2, Width = (int)numericUpDown1.Value * 2 };
            NewAsteroid.Add(asteroid);

            foreach (object item in NewAsteroid)
            {
                //GeometricObject asteroid = item as GeometricObject;

                if (asteroid != null)
                {
                    asteroid.Draw(g);
                }
            }
        }

Und meine Draw-Methode in der Klasse "Asteroid":

C#-Code:
  public class Asteroid : GeometricObject, IDisposable
    {
        public override void Draw(Graphics g)
        {
            g.FillEllipse(Brushes.Brown, (float)X, (float)Y, (float)Height, (float)Width);

            //g.DrawLine(Pens.Beige, (float)Kmx, (float)Kmy, (float)Kmx + (float)radius, (float)Kmy + (float)radius);  
        }

g.FillEllipse(Brushes.Brown, (float)X, (float)Y, (float)Height, (float)Width); ---> Hier kommt die Null-Referenz.


Ich frage mich wieso, da ich doch überall die Kreise instanziiert habe?
Oder könnte das an etwas anderem liegen?

Gruß

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von RingYK am 12.01.2017 15:13.

12.01.2017 15:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
p!lle
myCSharp.de-Mitglied

images/avatars/avatar-3556.jpg


Dabei seit: 22.02.2007
Beiträge: 727
Entwicklungsumgebung: Visual Studio (Community) 2017


p!lle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

12.01.2017 15:39 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
RingYK RingYK ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.01.2017
Beiträge: 9
Entwicklungsumgebung: .Net (C#)

Themenstarter Thema begonnen von RingYK

RingYK ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ahh, jetzt funktioniert es! Danke! :D
13.01.2017 10:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.258


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich find bei deim Code schlecht gelöst ist, dass du deine ZeichenObjekte in einer Listbox verwaltest.
In diesem Listbox-Control kann ja eiglich nichts vernünftiges angezeigt werden.
Da nimm lieber eine List<Object> - die ist eh kein Gui-Element.

Auch kannst du bei diesem Problem sehr schön Vererbungslehre und OOP walten lassen:
Schaff dir eine abstrakte Basisklasse "ZeichenObjekt", von der deine verschiedenen ZeichenObjekte erben, und die je nach ihrer Art die Basis-Zeichen-Methoden überschreiben.
Dann kann jedes Objekt - egal welcher Art - sich selber zeichnen, mit seiner je spezifischen Überschreibung, und die ganzen Typ-Überprüfungen sind überflüssig.
Tu die ZeichenObjekte dann nicht in eine List<Object>, sondern in eine List<ZeichenObjekt>.

Hier ist sowas vorgeturnt mit noch paar weiteren Schikanen:  Performantes OwnerDrawing
14.01.2017 11:32 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 6 Monate.
Der letzte Beitrag ist älter als 6 Monate.
Antwort erstellen


© Copyright 2003-2017 myCSharp.de-Team. Alle Rechte vorbehalten. 21.07.2017 10:29