Entwickler-Ecke
Multimedia / Grafik - blinkendes Image ( "instabil" )
beastofchaos - Sa 25.12.10 23:36
Titel: blinkendes Image ( "instabil" )
Hallo Leute, ich habe schon das nächste Problem für mein Minigolfprogramm, im Anhang findet ihr die Datei mit allem DrumundDran ;)
Mein programm zeichnet per MouseMove eine Linie und speichert sie in Image2. dieses Image2 überlagert leider die Canvaszeichnung meiner Kugel ( auch wenn Image2 im Hintergrund ist ). Image2 ist übrigens so ziemlich über das ganze Form verteilt und dadurch, dass es über alles drüber geht, aktualisiert es auch die Images und Canvaszeichnungen, die dadurch blinken oder gar nicht erzeugt werden/hinter dem Image sind. Schaut euch doch bitte mal meinen Quelltext an. Hab auch einen Timer, der die Kugel imemr wieder malen soll, aber da ist es halt wirklich so, dass die Kugel hinter dem Image2 ist.
MfG Thomas
Moderiert von
Martok: Topic aus Sonstiges (Delphi) verschoben am Sa 25.12.2010 um 22:37
@Martok:Tschuldige, da hab ich mich wohl geirrt^-^
edit: Da hab ich noch eine Frage zu meiner Kugelzeichnung. Wie schaff ich es, dass bei FormCreate gleich die Kugel gezeichnet wird mit Canvas. Wenn ich den Befehl bei Formcreate eingebe oder nem Timer, der auf True gesetzte ist, das machen lasse, kommt nichts. Erst, wenn ich einen Button klicke, funktioniert das. Weiß jem eine Lösung?
Moderiert von
Narses: Inline- in normalen Anhang gewandelt und Binaries aus dem Archiv entfernt.
platzwart - Sa 25.12.10 23:50
Naja, habs mir nicht angeschaut, klingt aber so, als würdest du mehrere Komponenten benutzen, um zu zeichnen? Dann solltest du besser nur eine einzige Zeichenfläche nehmen, die zur Anzeige des Gesamtbildes verwendet wird. Um Teilbereiche zu zeichnen (Ball, Hintergrund, Schläger oder was auch immer) solltest du besser Komponenten wählen, die nicht angezeigt werden, sondern nur zum internen Gebrauch gedacht sind. Wie z.B. TBitmap, in der kannst du beliebig zeichnen, dem Benutzer wird nichts angezeigt. Wenn du mit dem Zeichnen fertig bist, kopierst du es in die visuelle Komponente zum Anzeigen hinein.
jaenicke - So 26.12.10 00:00
Ein wenig Besserung könnte es schon bringen, wenn du DoubleBuffered des Formulars und ggf. von Panels usw. auf True setzt.
Wirklich sinnvoll wäre aber wie schon geschrieben das insgesamt zu zeichnen, am besten vermutlich auf eine TPaintBox.
beastofchaos - So 26.12.10 00:14
Ich find die TBitmap / TPaintbox nicht bei mir ( habe Delphi 7 ). In welches Kategorie ist das?
Hab mal Doublebuffered von Form auf True gesetzt. Mein Hindernis ( Image1 ) funktioniert einwandfrei. Nur blinkt imemr noch meine Canvaszeichnung von der Kugel. Ich mach das ganze ( außerdem Hindernis ) mit Shape. Mal schaun, ob das funktioniert.
beastofchaos - So 26.12.10 00:32
Ich hab schon eine andere Lösung gefunden. Ich benutze jetzt immer noch Image2 ( da ich ja auch die anderen nicht finden kann^^). ich binde den Kreis in Image2 mit ein - also es nicht einfach gezeichnet wird, sondern auch in Image2 mit der Linie gespeichert wird ;)
Bloß schaffe ichs jetzt nicht, die Brush.Color/Pen.Color zu verändern und er malt nur einen kreis, der "Pen.Color:= Black" und "Brsuh.Color:=White" hat... Wisst ihr wieso und kennt ihr eine Lösung?
platzwart - So 26.12.10 01:11
Eine Lösung wäre, TPaintBox zu verwenden. Über lang oder kurz wirst du darauf zurückgreifen müssen, denn alles andere sind nur kurzfristige Lösungen.
beastofchaos - So 26.12.10 01:19
Kann ich ruhig machen, aber ich bekomms nicht hin. Dieser Befehl zum Beispiel funktioniert nicht mit Paintbox: Paintbox1.Canvas.Ellipse(x1,y1,x2,y2);
Wie müss das da dann lauten? :)
Gehe jetzt schlafen, bis morgen
jaenicke - So 26.12.10 01:24
Inwiefern funktioniert der nicht? Kann es sein, dass du aus Versehen den Code nicht im OnPaint der PaintBox zu stehen hast?
Und auch dort ist das eigentlich nicht so sinnvoll. Meistens ist es besser, wenn du zuerst (wie im Link oben beschrieben) auf eine TBitmap zeichnest und diese in OnPaint nur auf die PaintBox kopierst. Denn sonst flackert es meistens trotzdem etwas.
beastofchaos - So 26.12.10 02:06
Jep, in nem anderen Topic hab ich das schon mitbekommen/durch gelesen ( habe noch nie mit bmp und paintbox gearbeitet ). Weiß jetzt wie es funktioniert, aber hab gleich wieder ein Problem ( warsch mit der Bitmap ). Im Anhang ist ein BIld, Sobald ich mit der maus auf das ausführende Form dann komme, aktiviert er ja das MouseMove Ereignis, bloß kommt dann diese Fehlermeldung: "Access violation at adress 00430300 in module 'Project.exe'. Read of addres 000000000." Also hat er ein Problem mit dem Auslesen der exe-Datei, aber ich hab keinen blassen Schimmer, wieso :/
jaenicke - So 26.12.10 02:07
Kein Problem mit der Exe, ich vermute du hast vergessen die Bitmap zu erzeugen.
beastofchaos - So 26.12.10 02:10
jaenicke hat folgendes geschrieben : |
Kein Problem mit der Exe, ich vermute du hast vergessen die Bitmap zu erzeugen. |
Ne, steht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var bmp: TBitMap . . . Formcreate[...] begin bmp := TBitmap.Create; bmp.Canvas.Brush.Color := clRed; bmp.Canvas.Pen.Width := 3; bmp.Width := Paintbox1.Width; bmp.Height := Paintbox1.Height |
Im Anhang ist
ein Bild davon (jpg, 412.27 KB) ;)
Moderiert von
Narses: Delphi-Tags und Link auf Bild im Anhang hinzugefügt
jaenicke - So 26.12.10 02:14
Was steht denn an der Stelle, an der der Fehler auftritt?
Die Fehlermeldung heißt einfach, dass du versuchst auf die Adresse 0 (also nix) zuzugreifen. Weil in einer Variable der Wert 0 steht.
beastofchaos - So 26.12.10 02:28
jaenicke hat folgendes geschrieben : |
Kein Problem mit der Exe, ich vermute du hast vergessen die Bitmap zu erzeugen. |
jaenicke hat folgendes geschrieben : |
Was steht denn an der Stelle, an der der Fehler auftritt?
Die Fehlermeldung heißt einfach, dass du versuchst auf die Adresse 0 (also nix) zuzugreifen. Weil in einer Variable der Wert 0 steht. |
Ah, mich hat gewundert, dass das nicht in der üblichen Fehlleiste steht (Problem war: "PaintBox1:=nil"). Jetzt hab ich das entfernt und er zeichnet nichts. Iwie schaff ich das nicht, dass er die bmp zeichnet und das dann in der Paintbox ausgibt.
Hier der Quellcode:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Timer1.Enabled=False then begin Canvas.Pen.Color:=ClBlack; Canvas.Brush.Color:=ClBlue; Maus:=PaintBox1.ScreentoClient(Mouse.CursorPos); d:=(x1+x2)/2; e:=(y1+y2)/2; bmp.Canvas.MoveTo(trunc(d-PaintBox1.Left),trunc(e-PaintBox1.top)); bmp.Canvas.LineTo(Maus.x,Maus.y); PaintBox1.Repaint; bmp.Canvas.Ellipse(x1,y1,x2,y2); PaintBox1.Repaint; end; end; |
Moderiert von
Narses: Code- durch Delphi-Tags ersetzt
jaenicke - So 26.12.10 02:46
beastofchaos hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4:
| procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Timer1.Enabled=False then begin | |
Besser:
Delphi-Quelltext
1:
| if not Timer1.Enabled then |
beastofchaos hat folgendes geschrieben : |
Delphi-Quelltext 1: 2:
| Canvas.Pen.Color:=ClBlack; Canvas.Brush.Color:=ClBlue; | |
Das ist zwar nicht falsch, aber ich verstehe nicht, warum du die Farben beim Formular änderst. Dort zeichnest du doch sowieso nicht. :gruebel:
beastofchaos hat folgendes geschrieben : |
Delphi-Quelltext 1:
| Maus:=PaintBox1.ScreentoClient(Mouse.CursorPos); | |
Du hast die Koordinaten doch schon als Parameter direkt in X und Y.
Hast du OnPaint denn auch implementiert? Kopierst du dort die Bitmap auf die PaintBox?
beastofchaos - So 26.12.10 14:19
Zitat: |
beastofchaos hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4:
| procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Timer1.Enabled=False then begin | | Besser: Delphi-Quelltext 1:
| if not Timer1.Enabled then | |
Das ist eigentlich nicht so wichtig/benötigend , aber danke :)
Zitat: |
beastofchaos hat folgendes geschrieben : | Delphi-Quelltext 1: 2:
| Canvas.Pen.Color:=ClBlack; Canvas.Brush.Color:=ClBlue; | | Das ist zwar nicht falsch, aber ich verstehe nicht, warum du die Farben beim Formular änderst. Dort zeichnest du doch sowieso nicht. :gruebel: |
Naja, damit kann man doch die allgemeine Farbe für alles bestimmen, oder? der muss ich davor ein "Paintbox1." oder "bmp." setzen?
Zitat: |
beastofchaos hat folgendes geschrieben : | Delphi-Quelltext 1:
| Maus:=PaintBox1.ScreentoClient(Mouse.CursorPos); | | Du hast die Koordinaten doch schon als Parameter direkt in X und Y. |
Ich find das sauberer, weil ich das ja später dafür brauche:
Delphi-Quelltext
1:
| bmp.Canvas.LineTo(Maus.x,Maus.y); |
Zitat: |
Hast du OnPaint denn auch implementiert? Kopierst du dort die Bitmap auf die PaintBox? |
ich weiß nicht, was du meinst. Ich hab Paintbox1 auf dem Form gemacht, bmp in variablen definiert und in Form nochmal "bmp:=TBitmap.Creat" geschrieben.
Muss ich der Painjtbox ncoh sagen, dass er das von bmp malen soll, weil ich das ja von bmp auf die Paintbox kopieren will? ;)
platzwart - So 26.12.10 15:00
Doch, das ist wichtig. Führt in 99% der Fälle nicht zu Fehlern, aber NUR so ist es absolut sauber programmiert. Am besten direkt abgewöhnen, Konstruktionen wie =true oder =false zu verwenden.
Wenn du nichts davor schreibst (und das gilt für alle Anweisungen analog), dann bezieht sich das immer nur auf dein Hauptformular (Form1). Woher soll Delphi denn wissen, worauf es sich sonst bezieht?
Ist trotzdem nicht sauberer. Die Parameter bekommst du ja bereits korrekt übergeben, da muss man das Rad nicht neu erfinden ;) Jeder, der nach dir den Sourcecode lesen wird, wird sich fragen, warum du das so machst und wird sich in die Doku einlesen, ob das ScreentoClient eventuell was anderes liefert als das X und Y. Niemand kann ahnen, warum du das verwendest (es sei denn, du kommentierst die Stelle).
beastofchaos hat folgendes geschrieben : |
Zitat: | Hast du OnPaint denn auch implementiert? Kopierst du dort die Bitmap auf die PaintBox? |
ich weiß nicht, was du meinst. Ich hab Paintbox1 auf dem Form gemacht, bmp in variablen definiert und in Form nochmal "bmp:=TBitmap.Creat" geschrieben.
Muss ich der Painjtbox ncoh sagen, dass er das von bmp malen soll, weil ich das ja von bmp auf die Paintbox kopieren will? ;) |
Ja logisch! Du sagst der Paintbox, dass sie sich neuzeichnen soll, aber du sagst ihr nicht, was wie wo wann warum...
beastofchaos - So 26.12.10 15:08
1. Das mit "True" und "False" merk ich mir, denke. Vll bekomm ich bei meinem Referat dafür ein Plus :p
2.Also soll ich schreiben:
Delphi-Quelltext
1: 2:
| Paintbox1.Canvas.Pen.Color:=ClBlack; Paintbox1.Canvas.Brush.Color::=ClBlue; |
oder soll ich das mit
bmp.Canvas etc.
schreiben?
3.Wie soll ich das dann schreiben? etwa so:
Delphi-Quelltext
1:
| bmp.Canvas.LineTo(PaintBox1.ScreentoClient(Mouse.CursorPos.x),PaintBox1.ScreentoClient(Mouse.CursorPos.y); |
Denn ich meine, dass geht nicht. Und statt der langen Wortfolge fand ich halt Maus übersichtlicher ;)
4.Wie lautet der Befehl, mit dem ich Paintbox sage bmp zu zeichnen?
Hab mal im anderen Topic nachgeschaut, so? :
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure TForm1.PaintBox1Paint(Sender: TObject); begin BitBlt(PaintBox1.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, bmp.Canvas.Handle, 0, 0, SrcCopy); end; |
platzwart - So 26.12.10 15:31
2) Schreib eben das dahin, worauf gezeichnet werden soll. Ob bmp, Paintbox1 oder was auch immer, kannst ja nur du wissen ;)
3) Vlt. vertue ich mich da auch. Aber wenn ich das richtig verstanden habe, dann zeichnet du im MouseMove-Event einer Image-Komponente? Falls ja, so liefert das MouseMove direkt X und Y mit, also musst du nur X und Y schreiben. Oder findet das Zeichnen außerhalb dieses Events statt?
beastofchaos - So 26.12.10 16:03
platzwart hat folgendes geschrieben : |
2) Schreib eben das dahin, worauf gezeichnet werden soll. Ob bmp, Paintbox1 oder was auch immer, kannst ja nur du wissen ;)
|
Jo, meine Frage war da eher, ob man as mit der virtuellen Bitmap machen soll doer mit der Paintbox, weil die das ja dann erst malt.
platzwart hat folgendes geschrieben : |
3) Vlt. vertue ich mich da auch. Aber wenn ich das richtig verstanden habe, dann zeichnet du im MouseMove-Event einer Image-Komponente? Falls ja, so liefert das MouseMove direkt X und Y mit, also musst du nur X und Y schreiben. Oder findet das Zeichnen außerhalb dieses Events statt? |
Das ganze ist in MouseMove drin, das stimmt! Aber wenn er die Koordinaten liest, liest er nur die Koordinaten auf dem ganzen Bildschirm und nicht in der Paintbox. Deswegen benutz ich ja auch "ScreenToClient".
beastofchaos - Di 28.12.10 14:51
Das passt zu diesem Thema, glaub ich wieder: Also bei meinem aktuellen Stand der Dinge ist das Hauptproblem, dass die Kugel nicht immer glatt sich bewegt. Wie bummi es mir empfohlen hat, lass ich alles direkt in der OnPaint-procedure direkt zeichnen, wobei sie auch unterscheidet zwischen aktiv(Kugel bewegt sich) oder stehen, damit sie nicht während des schusses eine Linie von der Kugel zur Maus macht. Ich kann nur soweit sagen, dass er am Anfang des Schusses noch ein bisschen hängt und dann erst glatt sich geradeaus bewegt. Vll hängts auch von der Leistung des jeweiligen Rechners ab, aber schaut euch das am besten mal an ;)
MfG Thomas
Moderiert von
Narses: Inline- in normalen Anhang gewandelt und binaries aus dem Code-Archiv gelöscht.
edit: so hab mal nur Quelltext und die exe-Datei (auf Wunsch der Mods) hochgeladen ( auf dem akturellen Stand ). Dabei hab ich jetzt auch schon die Spiegelung an einem Hindernis(Image) getestet. Mein Problem ist, dass die Kugel anfangs sehr hängt und beim Spiegeln sehr schnell sich an die Wand bewegt und wieder entfernt... ? Weiß jemand aushilfe. Vll mit den "Timebased movements", aber leider komme ich mit denen nicht klar bzw. versteh sie nicht. Im moment ist es bei mir auch nur möglich in 4 verschiedenen Geschwindigkeiten abzuschießen ( werde ich noch versuchen zu ändern ). Vll könnt ihr es euch mal anschaun und mir bei der Fehleranalyse helfen oder eine ganz andere Art an der Stelle der Spiegelung vorschlagen, mit der ich einwandfreier die Kugel bewegen kann.
MfG Thomas
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!