Benutzer mit den meisten Antworten
Figuren mit einem Timer bewegen lassen

Frage
-
hallo,
ich mache gerade ein fernstudium zum Programmierer auf C#.
nun stehe ich vor der aufgabe eine Figur wie Kreis oder Rechteck von der Mitte eines Panels was ich unter Graphics zeichenflaeche angewiesen habe vergrößern zulassen bis es den rand des Panels erreicht hat und dan wieder zurück zur ausgangsposition. Desweiteren sollen beim einstellen das Linien gezeichnet werden so aussehen das die Linie von der mitte aus nach oben und nach untenen wandert bis zur ausgangsposition.
dies soll der benutzer selber einstellen können mit welcher anzahl der wiederholung und geschwindigkeit.
ich steh total auf dem schlauch sitz jetzt schon seit 5 tagen dran jedoch ohne erfolg.
Antworten
-
Hallo Ronny,
die Mitte wird über 300px/2=150px berechnet. Das Problem ist wahrscheinlich der Ausrichtungspunkt, der ist eben oben links und nicht in der Mitte. Ich habe nochmal einen neuen Code zusammen geschrieben:
private void timer1_Tick(object sender, EventArgs e) { if (direction == false) { --pos;//Bewegung nach links if (pos <= 1) { direction = true;//richtung umkehren wenn am linken Rand } } else { ++pos;//Bewegung nach rechts if (pos >= Math.Min( panel1.Width,panel1.Height)/2) { direction = false;//richtung umkehren wenn am rechten Rand } } panel1.Invalidate();//Neuzeichnen des Panels erzwingen } int pos = 0; //momentane Position der Ellipse bool direction = true; //momentane Bewegungsrichtung (größer/kleiner) private void panel1_Paint(object sender, PaintEventArgs e) { var centerx = panel1.Width / 2; var centery = panel1.Height / 2; e.Graphics.DrawEllipse(Pens.Black, centerx - pos, centery - pos, pos * 2, pos * 2);//Ellispe zeichnen }
Die pos-Variable wird wieder im Tick-Event erhöht und erniedrigt. Der Wert pendelt zwischen 1 und der Hälfte der Größe des Panels. Die Math.Min Methode gibt den kleineren der übergebenen Werte aus. Somit wird sicher gestellt das der gezeichnete Kreis wirklich immer komplett angezeigt wird.
In der letzten Code Zeile wird nun die Position berechnet und dann das Control gezeichnet. Viel sagen kann ich dazu nicht. Wenn man einmal weiß wie es geht ist es eigentlich ganz einfach. So zumindest mein Empfinden.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 15. Mai 2015 13:20
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 26. Mai 2015 06:23
Alle Antworten
-
Hallo,
mit welcher Technologie (WinForms, WPF, ...) arbeitest du?
Grundsätzlich hast du immer die Möglichkeit im Tick-Event eines Timers eine Variable anzupassen und dann von der Variable abhängig die Figur zu zeichnen. In Windows Forms im Paint-Ereignis oder aber du bewegst ein Control.
Die Festlegung des Werts für die Variable musst du dann entsprechend abhängig von der Zeit und Position der Figur im Panel machen.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
erstmal vielen Dank für deine Antwort,
Ich arbeite mit WinForm ich habe ettliche foren gelesen auch die Hilfe von Visual bezüglich Timer, ClientRectangle und ClientSize habe auch versucht die demenstsprechend in Codes Enzubauen aber nix ging so wie es Sollte.
ich Zeige Dir gern mal den Code den ich zur Zeit am Basteln bin.
Er funktioniert soweit das ich den kreis oder besser Die Figur in die Mitte des Panels gezeichnet bekomme aber mehr nicht leider.
private void timer1_Tick(object sender, EventArgs e)
{
int groesse = 0;
int aufrufe = 0;
int zaehler = 0;
bereich = panel1.ClientRectangle;
Pen stift = new Pen(Color.Black);
switch (trackBar1.Value)
{
case 1: groesse = 125;
break;
case 2: groesse = 100;
break;
case 3: groesse = 75;
break;
}
if (radioButtonKreis.Checked == true)
{
if (radioButtonFuenfMal.Checked == true)
{
zaehler = Convert.ToInt32(numericUpDown1.Value);
zeichenflaeche.Clear(BackColor);
if (aufrufe < 5)
bereich.Width = bereich.Width + 10;
bereich.Height = bereich.Height + 10;
zeichenflaeche.DrawEllipse(stift, panel1.ClientRectangle.Left + groesse, panel1.ClientRectangle.Top + groesse, panel1.ClientRectangle.Width - (groesse * 2), panel1.ClientRectangle.Height - (groesse * 2));
aufrufe++;
}
}
also soweit bin ich, ich weiß nur nicht ab das der richtige weg ist.
-
Hallo,
das Zeichnen an sich solltest du ins Paint-Event verlagern, da es sonst passieren kann das Windows das bereits gezeichnete Fenster für ungültig erklärt und alles bisher gezeichnete weg ist. Ich habe dir mal einen Beispielcode erstellt, der eine Ellipse mit einem Timer innerhalb eines Panels hin- und her bewegt:
public partial class Form1 : Form { public Form1() { InitializeComponent(); timer1.Interval = 10; timer1.Start(); } private void timer1_Tick(object sender, EventArgs e) { if (direction == Direction.Left) { --pos;//Bewegung nach links if (pos <= 0) { direction = Direction.Right;//richtung umkehren wenn am linken Rand } } else { ++pos;//Bewegung nach rechts if (pos >= panel1.Width - width) { direction = Direction.Left;//richtung umkehren wenn am rechten Rand } } panel1.Invalidate();//Neuzeichnen des Panels erzwingen } const int width = 20, height = 20; //größe der Ellipse int pos = 0; //momentane Position der Ellipse Direction direction = Direction.Right; //momentane Bewegungsrichtung der Ellipse enum Direction { Left, Right, } private void panel1_Paint(object sender, PaintEventArgs e) { e.Graphics.DrawEllipse(Pens.Black, pos, 0, width, height);//Ellispe zeichnen } }
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
hi tom,
vielen Dank für deinen Hilfe.Du musst wissen ich mache ein Fernstudium.
nu habe ich das Thema Grafikprogrammierung:-(...... Meine Aufgabe lautet ein Program zu schreiben, wo der
Benutzer selbst einstellen kann den timer (dauer) die wiederholungen ( wie oft) und die Figur ( kreis, rechteck und linie) das ist ja eigentlich kein Problem, aber der Kreis und das Rechteck sollen sich von der mitte des Panels aus nach außen vergrößern bis zum Rand und danach wieder zurück. Die linien sollen sich von der mitte aus nach unten und nach oben jeweils bis zum Rand bewegen und wieder zurück zur mitte. genau das ist mein Problem ich bekomme es hin das der Kreis oder die Figur sich bewegen aber genau in die Flasche richtung, da sitz ich jetz schon seid Tagen drüber....... das Grundgestell ist soweit fertig.
Ich verwende eine Form mit 600 Breite und 420 als Höhe. Ein Panel mit 300x300.
3 x radiobutton für Kreis, Rechteck und Linie.
3x radiobutton für die wiederholungen.
1 numericupdown für den timerund die Normalen 2 Button für Beenden und Los geht´s
zum Code
// ist nur ein Anfang
public partial class Form1 : Form
{
int aufrufe;
Pen stift;
Graphics zeichenflaeche;
Rectangle bereich;
public Form1()
{
InitializeComponent();
aufrufe = 0;
bereich = panel1.ClientRectangle;
stift = new Pen(Color.Blue);
zeichenflaeche = panel1.CreateGraphics();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
// den timer auslösen
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
// abfragen was angeklickt wurde
if (radioButtonKreis.Checked==true)
{
// abfragen wie oft die Figur wiederholt werden soll
if ( radioButtonZehnMal.Checked==true)
{
//zeichenfläche löschen
zeichenflaeche.Clear(Color.White);
if (aufrufe < 10)
{
//jeweils 10 von der höhe und breite abziehen
bereich.Width = bereich.Width -10;
bereich.Height = bereich.Height -10;
// den Startpunkt setzen
bereich.Location=new Point(bereich.Location.X +5, bereich.Location.Y +5);
// die Figur zeichnen
zeichenflaeche.DrawEllipse(stift, bereich);
// die aufrufe erhöhen
aufrufe++;
}
wie gesagt ist nur ein auschnitt, der mit jetzt dir figur aber nur verkleinert ich brauchte es genau andersrum aber das bekomme ich nicht hin den jedesmal wenn ich den Startpunkt verändere zum beispiel x+130, y+130
springt es entwerder nach links oben ins eck oder nach unten rechts ins eck,
Ich verzweifle schön langsam daran.
-
Hallo,
gucke dir bitte zunächst mal an wie mein Code arbeitet. So sollte das unter Windows Forms programmiert werden (Paint Event etc.).
In meinem Code hast du eine Variable Position deren Wert sich stetig zwischen 0 und Panelbreite-width bewegt. Du musst deinen Code so umschreiben, dass die gezeichneten Objekte von dieser Variablen abhängig gemacht werden.
Ich könnte dir auch einfach den Code geben, nur hättest du wahrscheinlich keinen sonderlich großen Lerneffekt damit.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Hallo,
Ja ich hab deinen Code angesehen und er ist super nur darf ich nicht damit arbeiten weil wir die komponenten wie Direction noch nicht bearbeitet haben leider .
Ich muss mich an die vorgegebenen daten halten verstehst du...
Ich habe selber noch mal bisl rumgespielt am Code
zumindestens vergrößert er jetz die Figur schon mal.
aber eine frage habe ich mit
bereich.Width = bereich.Width + 10;
bereich.Height = bereich.Height +10;ist doch die größe von der Figur oder?
und mit
bereich.Location = new Point(bereich.Location.X +5, bereich.Location.Y +5);
setzte ich doch den Anfangspunkt.
wenn mein Panel 300 x 300 ist dann ist doch der Mittelpunkt 150.
also müsste doch die X und die Y achse 140 sein weil -10 wegen der Figur größe
bereich.Width = bereich.Width + 10;
bereich.Height = bereich.Height +10;bereich.Location= new Point(bereich.Location.X +140, bereich.Location.Y+140);
zeichenflaeche.DrawEllipse(stift,bereich);
aufrufe--;
dachte ich mir so aber der funktioniert auch nicht so da verschiebt sich die Figur aus dem Panel herraus.
-
Hallo,
entschuldige bitte meine etwas späte Rückmeldung, ich habe deine Antwort leider übersehen.
Ja ich hab deinen Code angesehen und er ist super nur darf ich nicht damit arbeiten weil wir die komponenten wie Direction noch nicht bearbeitet haben leider .
In solchen Fällen solltest du immer mitschreiben was du schon kannst und was du verwenden darfst. Dann können wir den Code natürlich entsprechend umbauen. Statt meinem eigenen Enum Direction kannst du einfach einen bool nutzen. Dieser gibt dann an ob sich die Figur momentan vergrößert oder verkleinert.
bereich.Width = bereich.Width + 10; bereich.Height = bereich.Height +10; ist doch die größe von der Figur oder?
Der Code vergrößert die Figur in beide Richtungen um je 10px.
mit bereich.Location = new Point(bereich.Location.X +5, bereich.Location.Y +5); setzte ich doch den Anfangspunkt.
Genau gesagt verschiebst du damit die obere linke um je 5px nach untern rechts.
Das fett markierte dürfte das Verschieben aus dem Panel heraus verursachen.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Hi Tom
vielen dank das du dich meiner sache annimst
das mit dem vergrößern ist mit jetzt klar.
Aber wie kann ich dan die mitte berechnen, wenn bereich panel1.ClientRectangle also das Ganze Rechteck
mit 300x 300 aufgeteilt ist also sprich dich X achse 300 und die Y auch 300px hat.
dan ist der mittelpunkt genau bei 150 wenn ich das richtig gelesen habe.
zum thema was ich darf und schon kann:
also wir arbeiten noch auf die ich sag mal komplexere methode also alles genau komentieren und ausführlich
schreiben der Code sollte in etwa so aussehen wie oben schon geposten zum verkleinern eines Rechteckes.
In dem Lehrheft was ich ab bearbeiten bin steht onst leider nix weiteres drinn als dieser code auch keine genauere beschreibung wie mann eventuell das umschreiben könnte oder wie ich eine mitte berechne leider, hab ich der Hife anleitung von Visual nachgelesen wie es Funktionieren müsste aber ohne erfolg.
mfg Ronny
-
Hallo Ronny,
die Mitte wird über 300px/2=150px berechnet. Das Problem ist wahrscheinlich der Ausrichtungspunkt, der ist eben oben links und nicht in der Mitte. Ich habe nochmal einen neuen Code zusammen geschrieben:
private void timer1_Tick(object sender, EventArgs e) { if (direction == false) { --pos;//Bewegung nach links if (pos <= 1) { direction = true;//richtung umkehren wenn am linken Rand } } else { ++pos;//Bewegung nach rechts if (pos >= Math.Min( panel1.Width,panel1.Height)/2) { direction = false;//richtung umkehren wenn am rechten Rand } } panel1.Invalidate();//Neuzeichnen des Panels erzwingen } int pos = 0; //momentane Position der Ellipse bool direction = true; //momentane Bewegungsrichtung (größer/kleiner) private void panel1_Paint(object sender, PaintEventArgs e) { var centerx = panel1.Width / 2; var centery = panel1.Height / 2; e.Graphics.DrawEllipse(Pens.Black, centerx - pos, centery - pos, pos * 2, pos * 2);//Ellispe zeichnen }
Die pos-Variable wird wieder im Tick-Event erhöht und erniedrigt. Der Wert pendelt zwischen 1 und der Hälfte der Größe des Panels. Die Math.Min Methode gibt den kleineren der übergebenen Werte aus. Somit wird sicher gestellt das der gezeichnete Kreis wirklich immer komplett angezeigt wird.
In der letzten Code Zeile wird nun die Position berechnet und dann das Control gezeichnet. Viel sagen kann ich dazu nicht. Wenn man einmal weiß wie es geht ist es eigentlich ganz einfach. So zumindest mein Empfinden.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 15. Mai 2015 13:20
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 26. Mai 2015 06:23
-
Hallo,
ich bin es leider schon wieder.
also ich habe den code soweit es geht eingebaut das es funktioniert also das der benutzer wählen kann zwischen kreis und rechteck nun liegt das problem mit der linie die in der mitte gezeichnet werden soll und dann nach unten und nach oben wandern soll bis hin zur ausgangs position das klappt nicht kanns oder besser überhaupt nicht.
desweiteren hab ich auch versucht das, der Benutzer beim zeichen der Ellipse oder des Rectangels selbst einstellen kann wie oft die figur wiederholt werden soll also ob sie 5 mal oder 10 mal gezeichnet werden soll bis sie wieder ihre ausgangsposition hat.
ich bin erhlich ich versteh das null komma null.
kann mir da bitte wer helfen.
mfg Ronny
-
Hallo Ronny,
ich weiß ehrlich gesagt nicht mehr was ich noch weiter schreiben soll. Für mich ist es einfach nur etwas verschieben von Figuren in einem Koordinatensystem und somit einfachste Mathematik.
Mehr als den kommentierten Code kann ich dir hier nicht geben.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Hallo Tom,
Entschuldige das ich nerv :-(
wenn mann es versteht dann Denke ich mir das es Einfach ist.
mein problem hierbei ist das die Linien jetzt Momentan links Oben gezeichnet werden und sich im Kreis Drehen.
if (radioButtonLinie.Checked == true)
{
var centerx = panel1.Bottom / 2;
var centery = panel1.Top / 2;
timer1.Interval = Convert.ToInt32(numericUpDownTimer.Value * 1000);
e.Graphics.DrawLine(Pens.Green, centerx - pos, centery - pos, pos * 2, pos * 2);
}
Ich möchte aber das die Linie in der Mitte des Panels gezeichnet wird und das Sie sich nach unten und nach oben bewegt weißt du was ich meine?Mfg Ronny