Einzelnen Beitrag anzeigen

Scurra

Registriert seit: 19. Jan 2015
81 Beiträge
 
Delphi 10.3 Rio
 
#1

Canvas: Änderungen/Bewegungen zeichnen

  Alt 26. Aug 2018, 10:54
Delphi-Version: 10 Seattle
Hallo zusammen,

ich schreibe gerade zum Üben einen Flugsicherungssimulator, wobei es mir besonders auf strukturierten und testbaren Code ankommt. Ein Kernelement des UIs soll ein Radarbildschirm sein, vom Prinzip her vergleichbar wie auf folgendem Bild: https://flyawaysimulation.com/downlo.../airtrfcfx.jpg

Neben der eigentlichen Darstellung (z. B. Flugzeuge, deren letzten Positionen, Landebahnen, Wegpunkte, Beschreibungstexte) soll später auch die Möglichkeit bestehen, den Bildausschnitt zu verschieben (so dass der Flughafen nicht zwingend zentriert liegen muss) und den sichtbaren Ausschnitt zu zoomen. Außerdem soll es evtl. möglich sein, durch Klicken auf die dargestellten Flugzeuge zusätzliche Beschreibungstexte anzuzeigen.

Da ich bislang kaum mit einem Canvas gearbeitet habe und mir die Erfahrung damit fehlt, bräuchte ich einmal euren Rat bei ein paar Fragen.


1. Welche Komponente bietet sich eurer Meinung nach bei meiner Problemstellung an? Wäre eine TPaintBox eine gute Wahl?

2. Wie kann man Änderungen in einer Zeichnung am besten implementieren? Sollte im Datenmodell die Position aller grafischen Elemente, die sich auf dem Canvas befinden, gespeichert werden, so dass man bei jeder Änderung (z. B. Position eines Flugzeugs wird verändert) alle Elemente komplett neuzeichnen kann? Falls ja, könnte das zu Flackern beim Neuzeichnen führen? Oder sollte jedes Element sich selbst darum kümmern, dass die alte Position gelöscht und die neue Position gezeichnet wird?

3. Rein logisch finde ich, dass es besser ist, wenn jedes Objekt selbst in der Lage ist, sich zu zeichnen. Meine erste Idee war beispielsweise, folgendes Interface anzulegen:
Delphi-Quellcode:
IDrawable = interface
  procedure Draw(const Canvas: TCanvas);
end;
Jedes Element, das auf dem Radarbildschirm sichtbar sein kann, muss lediglich dieses Interface unterstützen, womit es in der Lage wäre, sich auf den übergebenen Canvas zu zeichnen. Allerdings stellt sich mir bei diesem Ansatz die Frage: Wer kümmert sich darum, dass die alte Position vom Canvas verschwindet? Klar könnte sich jedes Objekt die alte Position merken und jedes Mal, wenn Draw aufgerufen wird, setzt das Objekt die Punkte von der letzten Position wieder zurück, aber das würde zu falschem Verhalten führen, wenn sich Positionen von verschiedenen Objekten überlagern, denn dann führt das Zurücksetzen/Löschen der alten Position dazu, dass möglicherweise Bestandteile anderer dargesteller Objekte mitgelöscht werden. Außerdem soll ja auch ein Verschieben/Zoomen des Bildausschnittes möglich sein. Wie können sich die Objekte wie Flugzeuge selbst auf ein Canvas zeichnen, wenn sie nicht wissen, welcher Bildausschnitt gerade sichtbar ist und an welcher Position sie sich auf dem Canvas platzieren sollen?
Aus diesem Blickwinkel wäre es wiederum gut, wenn es eine separate Klasse (eine Art "Zeichnen-Manager") gibt, die sich um alle Zeichenoperationen kümmert. Ich sehe darin dann aber ein sehr schlechtes Design, denn jedes Mal, wenn ein neuer zeichenbarer Objekttyp erstellt wird, dann müsste man die Klasse anpassen, damit sie auch weiß, wie der neue Objekttyp zu zeichnen ist. Außerdem: Angenommen eine Instanz einer Flugzeugklasse meldet sich beim "Zeichnen-Manager", weil es neu gezeichnet werden soll. Wie weiß dann dieser "Zeichnen-Manager", welche Pixel zur vorherigen Position gehören, damit er diese Pixel zurücksetzen kann?

Wie ihr seht, habe ich noch keine passende Idee, wie ich mein Vorhaben implementieren kann. Habt ihr einen Vorschlag für mich?
  Mit Zitat antworten Zitat