Laden...

Bouncing-Ball- Plural

Erstellt von Nexmo vor 2 Jahren Letzter Beitrag vor 2 Jahren 366 Views
N
Nexmo Themenstarter:in
36 Beiträge seit 2021
vor 2 Jahren
Bouncing-Ball- Plural

Hallo zusammen.

Alles in Win-Form-App(.NET Framework)

ich hab folgendes Problem:
Ich soll aktuell ein Programm erstellen, indem der User eine Form wählt(Rechteck oder Kreis), dann die Anzahl der Formen eingibt und dann die entsprechenden Informationen:
Breite + Länge, oder eben Radius.

dies soll dann auf einer weiteren Form grafisch dargestellt werden. Bis hier her kein Problem.

Jetzt sollen diese aber von der Position, wo sie entstehen(derzeit und in Zukunft auch Zufallsposition) auf den Bodenfallen und wieder zur Ausgangsposition zurückkehren.

Mit einem einfachen "Ball" oder auch Kreis habe ich das schon hinbekommen.
Timer + folgenden Code:


 private void MoveBall(object sender, EventArgs e)
        {
            //update Koordinaten
            
            ballPosY += moveStepY;
            if(ballPosY <ballPosY_Start || ballPosY + ballhight> this.ClientSize.Height)
            {
                moveStepY = -moveStepY;
            }
            //update painting
            this.Refresh();
        }

Nun ist es aber so, dass ich ja mehr als nur ein Objekt habe, welches sich bewegen soll, und diese Anzahl zur Laufzeit erst festgelegt wird.
Meine Idee war mit einer Liste zu arbeiten. Klappt bis zum anzeigen auch wunderbar.
nur das bewegen will nicht so.

Hat da einer eine Idee dazu.

hier mein Code-ansatz


 private void MoveCircle(object sender, EventArgs e)             //Grafiken bewegen
        {

           
            foreach (Point p in Änderungswerte)
            {
                
                kreisPosY = p.Y;
                kreisPosY += MoveStepY;
                if (kreisPosY < 0 || kreisPosY + radius > this.ClientSize.Height)
                    kreisPosY = -MoveStepY;
   
            }

           this.Refresh();

        }

16.827 Beiträge seit 2008
vor 2 Jahren

In [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox) siehst Du eigentlich, wie man solche Animationen umsetzt.

N
Nexmo Themenstarter:in
36 Beiträge seit 2021
vor 2 Jahren

das bringt mich leider auch nicht weiter.
hier geht es ja immer nur um ein einzelnes Objekt.

ich hab jetzt aber z.b 2-x Kreise die sich bewegen sollen. und nicht nur 1 Kreis.

4.938 Beiträge seit 2008
vor 2 Jahren

Ob nun 1 Element oder mehrere, du mußt nur den oder die betreffenden Objekte bewegen.
In deinem 2. Code änderst du doch gar nicht die Listenobjekte, sondern nur die Membervariable kreisPosY. Soll Änderungswerte diese Liste sein (komischer Name dafür)? Dafür mußt du dann aber eine for-Schleife (anstatt der foreach) verwenden, da Point eine Struktur (= Wertetyp) ist:


for (int i = 0; i < Änderungswerte.Length; i++)
{
    // x und y passend vorher berechnen
    Änderungswerte[i] = new Point(x, y);
}

N
Nexmo Themenstarter:in
36 Beiträge seit 2021
vor 2 Jahren

Meine Liste Änderungswerte enthält ja Punkte(Objekte von Point).
diese rufe ich mit der foreach-schleife ab.
Davon nehme ich mir dann die Y Koordinate, da ich nur möchte, dass der Kreis sich auf und ab bewegt.

bei nur einem Kreis geht das mit diesem Code:


 public partial class New_Jumpingball : Form
    {
        private int ballwidth = 50;
        private int ballhight = 50;
        private int ballPosX = 0;
        private int ballPosY = 0;
        private int moveStepX = 4;
        private int moveStepY = 4;

        private int ballPosX_Start = 0;
        private int ballPosY_Start = 0;

        public New_Jumpingball()
        {
            InitializeComponent();
            Startfestlegung();
            ballPosX_Start = ballPosX;
            ballPosY_Start = ballPosY;
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.UserPaint, true);
            this.UpdateStyles();

        }

        private void Startfestlegung()
        {
            ballPosY = Zufallspunkt();
            Thread.Sleep(25);
            ballPosX = Zufallspunkt();
        }

        private void PainCircle(object sender, PaintEventArgs e)
        {
            
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            e.Graphics.Clear(this.BackColor);
            e.Graphics.FillEllipse(Brushes.Blue,ballPosX, ballPosY, ballwidth, ballhight);
            e.Graphics.DrawEllipse(Pens.Red, ballPosX, ballPosY, ballwidth, ballhight);

        }

        private void MoveBall(object sender, EventArgs e)
        {
            //update Koordinaten
            
            ballPosY += moveStepY;
            if(ballPosY <ballPosY_Start || ballPosY + ballhight> this.ClientSize.Height)
            {
                moveStepY = -moveStepY;
            }
            //update painting
            this.Refresh();
        }

        private int Zufallspunkt()
        {
            Random s = new Random();
            return s.Next(45, 80);
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
        }
    }
}

da ich jetzt aber nicht eine einzige Koordinate habe, sondern eine ganze Liste mit Koordinaten ist da nun die Frage, wie kann ich durch die Liste gehen, und jedesmal die Y-Koordinate ändern, sodass sich der Kreis dann bewegt.

also obigen Code so abändern, dass er auf eine Liste von Koordinaten angewendet werden kann. oder ist dies gar nicht möglich?

309 Beiträge seit 2020
vor 2 Jahren

Das was du vorhast wird in jedem 2. Buch über Programmierung und OOP durchgekaut.
Leg dir eine Klasse Kreis an und füge eine Move Methode ein:


   
    public class Kreis
    {
        // oder halt Point (nur als Beispiel)
        public int ballPosX { get; set; }
        public int ballPosY { get; set; }
        //...

        public Kreis(int clientHight, int ballPosY_Start, ... )
        {
...
        }
        public void Move(int xStep, int moveStepY)
        {
            ballPosY += moveStepY;
            if (ballPosY < ballPosY_Start || ballPosY + ballhight > clientHight)
            {
                moveStepY = -moveStepY;
            }
        }

    }

Dann brauchst du in deinen Form-Methoden nur noch die Objekte durchgehen und die Funktionen aufrufen.

16.827 Beiträge seit 2008
vor 2 Jahren

Deine Zufall-Methode wird wahrscheinlich auch nicht funktionieren.
[FAQ] Random.Next liefert eine Zeit lang die gleiche Zufallszahl - Warum? Wie geht es richtig?

N
Nexmo Themenstarter:in
36 Beiträge seit 2021
vor 2 Jahren

doch. die funktioniert.
es geht alles bis auf die Bewegung der Objekte. im eigentlichen Code.

der code oben, welcher komplett ist, geht. Der läuft.

190 Beiträge seit 2012
vor 2 Jahren

es läuft, d.h. es gibt keine Fehlermeldung, aber das Ergebnis ist nicht richtig. Schau mal in den Link von Abt unter Punkt 3. Dort wird es erklärt.

  • Wer lesen kann, ist klar im Vorteil
  • Meistens sitzt der Fehler vorm Monitor
  • "Geht nicht" ist keine Fehlermeldung!
  • "Ich kann programmieren" != "Ich habe den Code bei Google gefunden"

GidF

16.827 Beiträge seit 2008
vor 2 Jahren

Richtig, ich hab Dir, Nexmo, den Link nicht umsonst geben - keine der beiden 🙂

N
Nexmo Themenstarter:in
36 Beiträge seit 2021
vor 2 Jahren

also ich geb euch mal den kompletten Code

das hier kommt in Form1, die als aller erstes aufgerufen wird.


 public partial class Formen_auswahl : Form
    {
        public Formen_auswahl()
        {
            InitializeComponent();
        }

        public bool Rechteck_Auswahl = false;
        public bool Kreis_Auswahl = false;
               
        public int Anzahl_Formen()
        { 
            return int.Parse(Eingabe_Anzahl.Text);  
        }
        public int Breite_Rechteck()
        {
           return int.Parse(Eingabe_Breite.Text);
                   }

        public int Länge_Rechteck()
        {
            return int.Parse(Eingabe_Länge.Text);
        }

        public int Radius()
        {
            return int.Parse(Eingabe_Radius.Text);
        }

        private void Show_Graphic_Click(object sender, EventArgs e)
        {
            try
            {
                if (Rechteck_Auswahl == true)
                {
                    Form n = new Graphic_Rechteck(Breite_Rechteck(), Länge_Rechteck(), Anzahl_Formen());
                    n.Show();
                }
                if (Kreis_Auswahl == true)
                {
                    Form k = new Graphic_Kreis(Radius(), Anzahl_Formen());
                    k.Show();
                }
            }
            catch (Exception) { MessageBox.Show("Bitte geben Sie gültige Werte ein!"); }
        }

        private void Rechteck(object sender, EventArgs e)
        {
            label2.Visible = true;
            label3.Visible = true;
            label4.Visible = true;
            Eingabe_Anzahl.Visible = true;
            Eingabe_Breite.Visible = true;
            Eingabe_Länge.Visible = true;
            Rechteck_Auswahl = true;
            Show_Graphic.Visible = true;
            label5.Visible = false;
            Eingabe_Radius.Visible = false;
            Kreis_Auswahl = false;
            Eingabe_Radius.Clear();

        }

        private void Kreis(object sender, EventArgs e)
        {
            label2.Visible = true;
            Eingabe_Anzahl.Visible = true;
            label5.Visible = true;
            Eingabe_Radius.Visible = true;
            Kreis_Auswahl = true;
            Show_Graphic.Visible = true;

            label3.Visible = false;
            label4.Visible = false;
            Eingabe_Breite.Visible = false;
            Eingabe_Länge.Visible = false;
            Rechteck_Auswahl = false;
            Eingabe_Breite.Clear();
            Eingabe_Länge.Clear();
        }

        private void Cancel_Click(object sender, EventArgs e)
        {
            label2.Visible = false;
            label3.Visible = false;
            label4.Visible = false;
            Eingabe_Anzahl.Visible = false;
            Eingabe_Breite.Visible = false;
            Eingabe_Länge.Visible = false;
            Rechteck_Auswahl = false;
            label5.Visible = false;
            Eingabe_Radius.Visible = false;
            Kreis_Auswahl = false;

            Eingabe_Anzahl.Clear();
            Eingabe_Breite.Clear();
            Eingabe_Länge.Clear();
            Eingabe_Radius.Clear();

        }
    }
}


folgendes kommt dann in die Graphic_Kreis, die aufgerufen wird

[csharp]
public partial class Graphic_Kreis : Form
    {

        public Graphic_Kreis(int a, int b)
        {
            InitializeComponent();

            anzahl = b;
            radius = a;

            this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.UserPaint, true);
            this.UpdateStyles();

            for (int i = 0; i < anzahl; i++)
            {
                Point p = new Point();
                p.X = Zufallswert();
                Thread.Sleep(40);
                p.Y = Zufallswert();
                Startbereich.Add(p);
            }


        }
        #region Instanzieren von variablen
        public List<Point> Startbereich = new List<Point>();
        public List<Point> Änderungswerte = new List<Point>();
        private int kreisPosY;
        private int kreisPosX;
        private  int moveStepY = 4;
        private  int moveStepX = 4;

        private int anzahl, radius, positionx, positiony ;
        #endregion

        #region get_und_set_Methoden
        public int Positionx
        {
            set {positionx = value; }
            get {return positionx; }
        }
        public int PositionY
        {
            set { positiony = value; }
            get { return positiony; }
        }
        
        public int KreisPosX
        {
            set { kreisPosX = value; }
            get { return kreisPosX; }
        }
        public int KreisPosY
        {
            set { kreisPosY = value; }
            get { return kreisPosY; }
        }
           
        public int Anzahl
        {
            set { anzahl = value; }
            get { return anzahl; }
        }
        public int Radius
        {
            set { radius = value; }
            get { return radius; }
        }

        public int MoveStepY
        {
            set { moveStepY = 4; }
            get { return moveStepY; }
        }

        #endregion

        
        private int Zufallswert()
        {
            Random r = new Random();
            int a = r.Next(50, 200);
            return a;
        }

        private PictureBox pictureBox1 = new PictureBox();
        private Font fnt = new Font("Arial", 15);

        private void start_Click(object sender, EventArgs e)
        {
            Starter_Kreis.Enabled = true;
        }

        private void Graphic_Kreis_Load(object sender, EventArgs e)
        {

        }

        private void stop_Click(object sender, EventArgs e)
        {
            Starter_Kreis.Enabled = false;
        }

        private void Painting(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.DrawString("Hier werden die Kreise angezeigt", fnt, Brushes.Blue, new Point(30, 30));
            e.Graphics.Clear(this.BackColor);
            foreach (Point p in Startbereich)
            {

                kreisPosY = p.Y; ;
                kreisPosX = p.X; ;
                e.Graphics.FillEllipse(Brushes.Red, kreisPosX, kreisPosY, radius, radius);
                e.Graphics.DrawEllipse(Pens.Red, kreisPosX, kreisPosY, radius, radius);
                Point c = new Point();
                c.Y = kreisPosY;
                c.X = kreisPosX;
                Änderungswerte.Add(c);
            }
        }

/* ------------------------------------ab hier ist der Fehler----------------------------*/    

        private void MoveCircle(object sender, EventArgs e)             //Grafiken bewegen
        {
 
            foreach (Point p in Änderungswerte)
            {
                int i = 0;
                kreisPosY = p.Y;
                do
                {
                    kreisPosY += moveStepY;
                    if (kreisPosY < 0 || kreisPosY + radius > this.ClientSize.Height)
                        kreisPosY = -moveStepY;
                    i++;
                } while (i<50);this.Refresh();
            }

            

        }

       
    }
}