Programmiere grade Mühle für die Schule und bin mir bei einer
Sache unschlüssig.
Habe das Spielfeld in drei AchterArrays, die jeweils einen der
Spielfeldringe symbolisieren aufgeteilt.
Darin steht jetzt jeweils weiss, schwarz oder Leer.
Jetzt will ich nach jedem zug das spielfeld aktuell anzeigen.
habe 24 imagefelder, die auch in drei mal acht eingeteilt
sind.
nun dachte ich mir, bevor du da zig if abfragen einbaust was
nicht sehr praktisch ist, machst du was mit schleifen.
das problem oder die eigentliche frage ist jetzt: Kann ich
wenn ich in der schleife eine laufvariable x habe das bild mit
Ax bzw. Bx ansprechen? (normalerweise heissen die halt A1, A2,
usw.)??
Direkt auf diese Art geht es leider nicht.
Möglichkeit 1
Füge im PRIVATE-Teil Deines Formulars folgende Deklaration hinzu:
BildA: ARRAY[0…7] OF TImage;
BildB: ARRAY[0…7] OF TImage;
BildC: ARRAY[0…7] OF TImage;
oder gleich als ganz kompakte Alternative:
Bild: ARRAY[0…2, 0…7] OF TImage;
Die Elemente dieser Arrays sollen dazu dienen, auf die bestehenden Images auf Deinem Formular zu zeigen. Deshalb werden von den Elementen keine Instanzen angelegt, sondern sie werden lediglich auf die entsprechenden Images gesetzt. Dies sollte natürlich „möglichst früh“ geschehen, wobei andererseits die automatische Instantiierung der Formular-Images durch die VCL abgeschlossen sein muß. Der richtige Zeitpunkt für die Aktion ist gerade der, zu dem das OnCreate-Event des Formulars aufgerufen wird.
Erzeuge Dir also die „OnCreate“-Behandlungsprozedur (per Doppelklick im Objektinspktor) und schreib da hinein:
BildA[0] := ImageA1;
BildA[1] := ImageA2;
BildA[2] := ImageA3;
…
BildA[7] := ImageA8;
BildB[0] := ImageB1;
…
BildB[7] := ImageB8;
BildC[0] := ImageC1;
…
BildC[7] := ImageC8;
Das ImageB8 z. B. kannst Du nun im Quelltext weiterhin mit „ImageB8“ ansprechen, außerdem jetzt aber auch mit „BildB[7]“. Beides ist völlig gleichwertig, weil beide Zeiger auf dieselbe Speicherstelle zeigen.
Möglichkeit 2
Du verzichtest auf die Images zur Entwurfszeit und erzeugst sie zur Laufzeit.
Deklariere im PRIVATE-Teil Deines Formulars das Array
Bild: ARRAY[0…2, 0…7] OF TImage;
Nun legst Du (im Gegensatz zu Möglichkeit 1) von diesen Elementen Instanzen an. Da Du das in einer doppelten Schleife erledigst, wird Dein Code sehr kompakt.
In den „OnCreate“-Handler des Formulars schreibst Du:
FOR i := 0 TO 2 DO
begin
FOR k := 0 TO 7 DO
begin
// Parameter "Self", weil der Besitzer der Bilder
// das Formular ist
Bild[i, k] := TImage.Create(Self);
WITH Bild[i, k] DO
begin
// Folgende Zeile ist wichtig! Das "Parent"
// aller Bilder ist ebenfalls das Formular
Parent := Self;
Width := 30;
Height := 30;
Left := IMAGELEFT [i, k];
Right := IMAGERIGHT[i, k];
// ...und noch Anweisungen für alle weiteren
// Eigenschaften, die gesetzt werden müssen
end
end
end
IMAGELEFT[i, k] und IMAGERIGHT[i, k] sind dabei CONST-Arrays, die die gewünschten Koordinaten der Bilder enthalten.
oder hat jemand einen anderen lösungsvorschlag für die
grafische ausgabe, die vielleicht noch schneller geht oder das
problem umgeht?
Wenn es Dir nur darum geht, weiße oder schwarze oder „unsichtbare“ (mit Hintergrundfarbe gemalte) Kreise zu zeichnen (Du also nicht unbedingt richtige Bilder haben willst), solltest Du vielleicht besser mit „TPaintBox“ arbeiten (in der Komponentenpalette unter „System“ zu finden). Eine Paintbox stellt Dir mit ihrem Property „Canvas“ eine Zeichenfläche zur Verfügung. Der Vorteil für Dich wäre, daß Du mit einer einzigen Paintbox auskommst. Die Befehle, mit denen Du auf den Canvas malen kannst, kann ich Dir hier nicht alle erklären, und außerdem sind sie auch alle in der Online-Hilfe (Stichwort „TCanvas“) beschrieben.
MfG
Martin