Autor |
Beitrag |
CodeKiddy
Hält's aus hier
Beiträge: 9
WIN 10
C#
|
Verfasst: Sa 14.04.18 15:47
Ein freundliches Hallo in die Runde.
Ich trete heute mit einem Problem an euch ran, dass mich zum Verzweifeln bringt. Trotz etlichen Momenten des Brainfucks war es mir nicht möglich, dieses Problem zu beheben.
Unzwar soll ich in einer Hausaufgabe eine kleine Anwendung entwerfen, wo man ein bisschen mit dem Zeichenbereich eines Panels "spielen" kann, indem man ein paar Kreise, Rechtecke, Linien hinzeichnet. Das habe ich ziemlich gut hinbekommen. Doch das "Sahnehäubchen" der Anwendung soll sein, eine kleine "Animation" erstellen zu können, wo im Panel ein Kreis oder ein Rechteck von einem Ausgangspunkt in der Mitte des Panels alle paar Sekunden ein wenig weiter wandert, bis der Rand des Panels ungefähr erreicht ist und sich anschließend wieder zur Mitte hin bewegen, bis er seinen ursprünglichen Ausgangspunkt einigermaßen wieder hat. Dabei soll der Anwender die Zahl der Wiederholungen vorgeben.
Ich habe alle nötigen Komponenten erstellt und auch den Code gut vervollständigt, doch ich komme einfach nicht an dem Problem vorbei, wie ich es schaffe, dass die Zeichnung der Kreise/Rechtecke am Rand stoppt und wieder beginnt, die Zeichnungen an innen auszuführen. Der Abstand jeder Zeichnung beträgt 5 Punkte zu seiner Ausgangszeichnung. Bei mir geht die Zeichnung jedoch immer über den Rand des 300 x 300 Punkte großen Panels hinaus. Mir ist schleierhaft, wie ich die Grenzen richtig bestimme. Seltsamerweise habe ich es aber geschafft, den umgekehrten Effekt zu erzielen: vom Ausgangspunkt nach innen zu zeichnen und sich dann wieder zu vergrößern. Das ist aber ja nicht das Ziel, und ich konnte es nicht schaffen, es umzukehren.
Hat einer von euch eine Lösung?
Wie gesagt, das Panel soll eine Größe von 300 x 300 haben. Die Kreise und Rechtecke von 100 x 100 (anfangs, denn der Anwender kann hier zwischen drei Größen wählen, aber ich denke, wenn ich verstehe, wie das mit einer Größe funktioniert, bekomme ich es auch für die anderen hin ). Der Mittelpunkt aller Figuren liegt bei 150, 150. Veränderung bei jeder Zeichnung um 5 in jede Richtung. Nach jedem Zeichnen soll die Figur nach 100 ms gelöscht werden. Der Anwender gibt die Anzahl der Wiederholungen vor (was mich zu der Überlegung führt, wie ich es nach dem Zurückzeichnen auch noch schaffe, dass es sich WIEDER vergrößert... ). Die Wiederholungsrate kann zwischen 1 und 200 liegen. Den Stift sucht der Anwender sich vorher aus; braucht also bei dem Problem jetzt nicht groß beachtet werden, da er zu dem Zeitpunkt schon festgelegt ist. Startpunkt der ersten Zeichnung ist erst einmal irrelevant; kann ich ja später an mein Programm anpassen.
Uff, ich hoffe, ich habe mich verständlich ausgedrückt und ihr könnt mir helfen.
Liebe Grüße, CodeKiddy.
|
|
Th69
Beiträge: 4784
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Sa 14.04.18 16:52
Hallo,
ich denke, es ist einfacher, wenn du uns deinen bisherigen Code für die Animation zeigst. Verwendest du denn die Timer-Komponente?
Das Erkennen des Randes sollte ja nur ein bißchen Mathematik sein.
|
|
CodeKiddy
Hält's aus hier
Beiträge: 9
WIN 10
C#
|
Verfasst: Mo 16.04.18 16:52
Oh, natürlich gerne.
Nein, ich habe keinen Timer verwendet, sondern die Methode genommen, die auch in meinem Lernheft verwendet wird.
Ich habe bisher folgendes zusammengebastelt:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288:
| namespace kleineSpielerei { public partial class FormSpielerei : Form { Graphics zeichenflaeche; Color linienfarbe; Color hintergrundfarbe;
System.Drawing.Drawing2D.DashStyle[] linienstil = { System.Drawing.Drawing2D.DashStyle.Dash, System.Drawing.Drawing2D.DashStyle.DashDot, System.Drawing.Drawing2D.DashStyle.DashDotDot, System.Drawing.Drawing2D.DashStyle.Dot, System.Drawing.Drawing2D.DashStyle.Solid };
System.Drawing.Drawing2D.HatchStyle[] fuellstil = { System.Drawing.Drawing2D.HatchStyle.Cross, System.Drawing.Drawing2D.HatchStyle.DottedGrid, System.Drawing.Drawing2D.HatchStyle.ForwardDiagonal, System.Drawing.Drawing2D.HatchStyle.Sphere, System.Drawing.Drawing2D.HatchStyle.Vertical, System.Drawing.Drawing2D.HatchStyle.Wave, System.Drawing.Drawing2D.HatchStyle.ZigZag };
public FormSpielerei() { InitializeComponent(); }
private void FormSpielerei_Load(object sender, EventArgs e) {
linienfarbe = Color.Black; hintergrundfarbe = Color.Black;
foreach (System.Drawing.Drawing2D.DashStyle element in linienstil) listBoxLinieStil.Items.Add("");
foreach (System.Drawing.Drawing2D.HatchStyle element in fuellstil) listBoxHintergrundStil.Items.Add("");
zeichenflaeche = panelZeichenbereich.CreateGraphics(); }
private void buttonLoeschen_Click(object sender, EventArgs e) { zeichenflaeche.Clear(panelZeichenbereich.BackColor); }
private void buttonBeenden_Click(object sender, EventArgs e) { Close(); }
private void buttonStart_Click(object sender, EventArgs e) { int groesse = 0; Pen stift = new Pen(linienfarbe); SolidBrush pinsel = new SolidBrush(hintergrundfarbe);
stift.Width = Convert.ToInt32(numericUpDownLinieStaerke.Value);
switch (trackBar1.Value) { case 1: groesse = 125; break; case 2: groesse = 100; break; case 3: groesse = 75; break; }
if (listBoxLinieStil.SelectedIndex >= 0) stift.DashStyle = linienstil[listBoxLinieStil.SelectedIndex];
if (radioButtonOhne.Checked == true) { if (radioButtonKreis.Checked == true) { if (radioButtonHintergrundOhne.Checked == true) { zeichenflaeche.DrawEllipse(stift, panelZeichenbereich.ClientRectangle.Left + groesse, panelZeichenbereich.ClientRectangle.Top + groesse, panelZeichenbereich.ClientRectangle.Width - (groesse * 2), panelZeichenbereich.ClientRectangle.Height - (groesse * 2)); }
if (radioButtonHintergrundFarbe.Checked == true) { zeichenflaeche.FillEllipse(pinsel, panelZeichenbereich.ClientRectangle.Left + groesse, panelZeichenbereich.ClientRectangle.Top + groesse, panelZeichenbereich.ClientRectangle.Width - (groesse * 2), panelZeichenbereich.ClientRectangle.Height - (groesse * 2)); }
if (radioButtonHintergrundMuster.Checked == true && listBoxHintergrundStil.SelectedIndex >= 0) { System.Drawing.Drawing2D.HatchBrush musterPinsel = new System.Drawing.Drawing2D.HatchBrush(fuellstil[listBoxHintergrundStil.SelectedIndex], stift.Color, Color.White);
zeichenflaeche.FillEllipse(musterPinsel, panelZeichenbereich.ClientRectangle.Left + groesse, panelZeichenbereich.ClientRectangle.Top + groesse, panelZeichenbereich.ClientRectangle.Width - (groesse * 2), panelZeichenbereich.ClientRectangle.Height - (groesse * 2)); } }
if (radioButtonRechteck.Checked == true) { if (radioButtonHintergrundOhne.Checked == true) { zeichenflaeche.DrawRectangle(stift, panelZeichenbereich.ClientRectangle.Left + groesse, panelZeichenbereich.ClientRectangle.Top + groesse, panelZeichenbereich.ClientRectangle.Width - (groesse * 2), panelZeichenbereich.ClientRectangle.Height - (groesse * 2)); }
if (radioButtonHintergrundFarbe.Checked == true) { zeichenflaeche.FillRectangle(pinsel, panelZeichenbereich.ClientRectangle.Left + groesse, panelZeichenbereich.ClientRectangle.Top + groesse, panelZeichenbereich.ClientRectangle.Width - (groesse * 2), panelZeichenbereich.ClientRectangle.Height - (groesse * 2)); } }
if (radioButtonLinie.Checked == true) { zeichenflaeche.DrawLine(stift, panelZeichenbereich.ClientRectangle.Left + groesse, panelZeichenbereich.ClientRectangle.Height / 2, panelZeichenbereich.ClientRectangle.Width - groesse, panelZeichenbereich.ClientRectangle.Height / 2); } } else { if (radioButtonHintergrundMuster.Checked == true || radioButtonHintergrundFarbe.Checked == true) { MessageBox.Show("Bei einer Animation ist es leider nicht möglich, eine Hintergrundfarbe oder ein Hintergrundmuster festzulegen.", "Fehler Animation"); } else { int geschwindigkeit = trackBarAnimationGeschwindigkeit.Value; int wiederholung = Convert.ToInt32(numericUpDownAnimationWiederholungen.Value);
if (radioButtonKreis.Checked == true) { System.Threading.Thread.Sleep(100); zeichenflaeche.Clear(Color.White); }
if (radioButtonRechteck.Checked == true) { System.Threading.Thread.Sleep(100); zeichenflaeche.Clear(Color.White); }
if (radioButtonLinie.Checked == true) { System.Threading.Thread.Sleep(100); zeichenflaeche.Clear(Color.White); } } } }
private void buttonLinieFarbe_Click(object sender, EventArgs e) { if(colorDialogLinie.ShowDialog() == DialogResult.OK) { panelLinieFarbeVorschau.BackColor = colorDialogLinie.Color;
linienfarbe = colorDialogLinie.Color; } }
private void buttonHintergrundFarbe_Click(object sender, EventArgs e) { if(colorDialogHintergrund.ShowDialog() == DialogResult.OK) { panelHintergrundFarbeVorschau.BackColor = colorDialogHintergrund.Color;
hintergrundfarbe = colorDialogHintergrund.Color;
radioButtonHintergrundFarbe.Checked = true; } }
private void listBoxLinieStil_DrawItem(object sender, DrawItemEventArgs e) { int y; Pen boxStift = new Pen(Color.Black);
y = (e.Bounds.Top + e.Bounds.Bottom) / 2;
e.DrawBackground();
boxStift.DashStyle = linienstil[e.Index]; e.Graphics.DrawLine(boxStift, e.Bounds.Left + 1, y, e.Bounds.Right - 1, y); }
private void listBoxHintergrundStil_DrawItem(object sender, DrawItemEventArgs e) { System.Drawing.Drawing2D.HatchBrush boxPinsel = new System.Drawing.Drawing2D.HatchBrush(fuellstil[e.Index], Color.Black, Color.White);
e.DrawBackground();
e.Graphics.FillRectangle(boxPinsel, e.Bounds.Left + 1, e.Bounds.Top + 1, e.Bounds.Width - 1, e.Bounds.Height - 1); } } } |
|
|
Th69
Beiträge: 4784
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Di 17.04.18 08:33
Ich sehe aber keinen Animationscode.
Und darf ich fragen, was das für ein Lernbuch ist? Denn der Code enthält einige Anti-Pattern bzgl. WinForms-Programmierung:
- Zeichnen sollte man nur im OnPaint bzw. Paint-Ereignis (auch hier wieder mein Standard-Link dazu: [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox)
Tipp: Laß mal etwas zeichnen, dann minimiere dein Fenster und zeige es wieder an...
- Der UI-Thread darf nicht blockiert werden, d.h. Thread.Sleep ist absolutes Tabu (WinForms-Programmierung ist nicht wie bei einem Konsolenprogramm)!
- Alle lokalen Grafikobjekte müssen wieder 'disposed' werden, s. meine Antwort ("PS") in Mehrere erstellte Images flackern teilweise
|
|
CodeKiddy
Hält's aus hier
Beiträge: 9
WIN 10
C#
|
Verfasst: Fr 20.04.18 16:03
Du siehst keinen Animationscode, weil ich den einfach nicht hinbekomme. Ich weiß nicht, wie ich den aufbauen soll. Mit einer for-Schleife und innen drin if-Abfragen? Lieber eine while-Schleife? Ich stehe total auf dem Schlauch. Dort, wo die Codezeilen mit dem System.Threading.Thread.Sleep sind, soll letztendlich der Animationscode hinkommen.
Ich mache einen Fernkurs bei der ILS Hamburg zum Thema Programmieren mit C#. Die stellen die Lernhefte bereit.
Ich stehe noch ziemlich am Anfang meiner Programmierkenntnisse. Vielleicht wird das, was du ansprichst, in einem späteren Lernheft genauer unter die Lupe genommen, und sie haben darauf erst einmal verzichtet, weil es vielleicht als "zu schwierig" für den Anfang angesehen wird. Ich weiß es nicht, aber ich kann meinen Fernlehrer gerne mal auf die Probleme hinweisen, die du mir genannt hast.
Meine Hausaufgaben sind immer genau vorgeschrieben. Den größten Teil des Codes haben wir im Lernheft "gemeinsam" erstellt, d.h. er war vorgeschrieben und ich musste nur abschreiben. Als Beschreibung zu meiner HA stand nur, dass ich den Code um die gewünschten Funktionen erweitern soll. Weshalb ich davon ausgehe, dass die "Fehler", die sich hier noch im Code verstecken, in einem der nächsten Lernhefte behandelt werden. Hoffe ich. Wenn nicht, wäre das ziemlich...schlecht.
_________________ Diese Software verdient die 3 großen GGG: Gesehen — Gelacht — Gelöscht.
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 20.04.18 19:31
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
|