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();
}
In [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox) siehst Du eigentlich, wie man solche Animationen umsetzt.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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.
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);
}
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?
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.
Deine Zufall-Methode wird wahrscheinlich auch nicht funktionieren.
[FAQ] Random.Next liefert eine Zeit lang die gleiche Zufallszahl - Warum? Wie geht es richtig?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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.
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.
Richtig, ich hab Dir, Nexmo, den Link nicht umsonst geben - keine der beiden 🙂
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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();
}
}
}
}