chrisyFIAE Geschrieben 12. Februar 2008 Geschrieben 12. Februar 2008 hallo, folgende Frage: Ich habe mehrere Shapes. Dann habe ich noch ein Edit-Feld und ein Button. Wenn ich im Edit-Feld eine Zahl eingebe z.B. 8 und ich drücke auf dem Button, dann soll Shape_08 z.B. grün markiert werden. Wie man die Shapes färbt, weis ich ja, aber wie ich die Shapes der eingetippten Zahl nach entsprechend verrücken kann, bekomme ich einfach nciht hin...bin auch noch Anfänger in Sachen Delphi. Kann mir bitte jemand helfen? Es würde mir auch schon ein Ansatz reichen. Vielen Dank. Zitieren
geloescht_JesterDay Geschrieben 14. Februar 2008 Geschrieben 14. Februar 2008 Wie man die Shapes färbt, weis ich ja, aber wie ich die Shapes der eingetippten Zahl nach entsprechend verrücken kann, bekomme ich einfach nciht hin...bin auch noch Anfänger in Sachen Delphi. Kapier nicht ganz was du tun willst, aber ich versuch es mal: Also erstmal musst du auf dem Form KeyPreview einschalten. Dann bekommt das form immer zuerst alle Tasten-Events. In einem Key-Event (OnKeyDown schätz ich mal) ermittelst du dann welche Taste gedrückt wurde und reagierst darauf. Verschieben? Shape1.left := Shape1.left div 2; Meintest du das? Zitieren
chrisyFIAE Geschrieben 14. Februar 2008 Autor Geschrieben 14. Februar 2008 hallo, also es soll wie ein Mensch ärgere dich nicht Spiel sein nur mit dem Unterschied, dass ich selber eine Zahl eintippe und das entsprechende Shape der eingetippten Zahl nach orientiert nach drücken des Buttons z.B. grün werden soll. Gebe ich die nächste Zahl ein und drücke auf dem Button, so soll wieder um den Wert der eingetippten Zahl weitergerückt werden. Sprich: altes Shape wieder weiß, neues Shape grün und immer so weiter. Ich hoffe ich konnte mich jetzt besser ausdrücken, aber vielen dank schon einmal für deine Hilfe. Zitieren
geloescht_JesterDay Geschrieben 15. Februar 2008 Geschrieben 15. Februar 2008 ah, also du hast z.B. 6 Shapes, der einfachheithalber alle übereinander angeordnet, alle mit Farbe weiß. Du würfelst eine 1, dann soll das unterste shape grün werden. Dann würfelst du eine 5, und dann soll das zweitoberste grün werden, das erste aber wieder weiß. Hab ich das richtig verstanden? OK, also erstmal ist dafür das Drag'n'Drop (shape anklicken und auf Form droppen und dann anordnen) was du mit Sicherheit verwendet hast eher blöd. Was du brauchst ist ein programatischer zugriff auf alle Shapes in geordneter Form. Ich würde das über ein (dynamisches) Array machen. Ich bin in Delphi etwas aus der Übung und mach das aus dem kopf, also keine Garantie dass das ohne Fehler ist type TShapeArray = Array of TShape; Form01 = TForm [...] private FArShapes: TShapeArray; FActiveShape: TShape; public procedure destroy; override; end; const cShapeCount = 6; cShapeWidth = 30; cShapeHeight = 15; //*** Farben cColorInactiv = clWhite; cColorActive = clGreen; implementation //*** Event OnActivate procedure Form01Activate(sender: TObject) begin createShapes; end; //*** shapes erzeugen procedure createShapes var i, index: Integer; begin For i:= 0 to cshapeCount-1 do begin //*** Array vergrößern //*** hier bin ich nicht mehr sicher müsste aber so ung. sein setlength(FArShapes, length(FArShapes)+1); //*** höchster Index für neues shape index:= High(FArShapes); //*** neues shape FArShapes[index]:= TShape.create(nil); //*** Größe und Position festlegen FArShapes[index].width:= cShapeWidth; FArShapes[index].height:= cShapeHeight; //*** der einfachheithalber X = 0 FArShapes[index].left:= 0; //*** übereinander stapeln FArShapes[index].top:= index * cShapeHeight + cShapeHeight; //*** Farbe FArShapes[index].color:= clColorInactive; //*** Parent wegen der anzeige (s.Kommentar unten) FArShapes[index].parent:= Panel01; end; end; //*** ein Shape "aktivieren", 0 basierter Index! procedure activateShape(index: Integer) begin //*** altes deaktivieren FActivceShape.Color:= cColorInactive; //*** neues aktivieren und merken FActiveShape:= FArShapes[index] FActiveShape.color:= cColorActive; end; //*** alles wieder freigeben //*** !!!wichtig!!! procedure destroy var i: Integer; begin //*** alle erzeugten Shapes freigeben for i:= 0 to High(FArShapes) do begin FreeAndNil(FArShapes[i]); end; //*** aktiven shape sicherheitshalber auch FreeAndNil(FActiveShape); //*** geerbten Destructor aufrufen! inherited destroy; end; so, also denke mal das lößt dein Problem. Musst die Prozedur nur entsprechend mit einer Zahl von 0-5 (in meinem Beispiel) aufrufen. Wichtig ist: Alles was du selbst erzeugt hast, musst du auch wieder freigeben! Deswegen überschreibst du den Destruktor, damit du am ende, wenn das Formular freigegeben wird darauf reagieren kannst und aufräumst. (Ich bin irgendwie kein Freund des GarbageCollectors bei Java oder .net fand das so immer gut. Nur waren wohl viele einfach zu faul aufzuräumen...) Das ist zwar kein Anfänger-Delphi mehr, aber so bekommst du gleich mal einen Einstieg in die Objektorientierung von Delphi (wenn auch nur einen kleinen) und fortgeschrittenes Delphi . Nachtrag: Alles was du für das Beispiel brauchst ist ein leeres Form und evtl. ein Edit-Feld und einen Button für deine Eingaben. Die ganzes Uses weiß ich nicht auswendig, aber wenn er wo meckert, hilft die OnlineHilfe, weil da steht in welcher Unit die KLasse o.ä. zu finden ist. EDIT2: Das mit dem FActiveShape könnte noch schiefgehen, in dem Fall merkst du dir dann einfach den aktiven Index. Oder wenn du es unelegant willst, färbst du einfach alle erstmal weiß Nochwas: So wie das oben ist, wirst du wohl keine shapes angezeigt bekommen. Dazu solltest du noch z.B. ein Panel auf das form legen und dann wenn du ein TShape erzeugt und position etc zugewiesen hast noch: FArShapes[index].parent:= Panel01; Damit das Ding auch auf dem Panel angezeigt wird. (Hab das grad mal schnell eingefügt oben) Zitieren
gi_networx Geschrieben 19. Februar 2008 Geschrieben 19. Februar 2008 Oder man macht es einfach so: (Form1.FindComponent('Shape' + IntToStr(i)) as TShape).Eigenschaft := Wert; :cool: Viele Grüße Michl Zitieren
geloescht_JesterDay Geschrieben 19. Februar 2008 Geschrieben 19. Februar 2008 Oder man macht es einfach so: Einfach ist eben relativ. Eine Suche (Find...) ist immer viel aufwendiger als der direkte Zugriff. Das mag bei kleinen Anfänger Programmen noch gehen, aber betont sei hier Anfänger. Außerdem sehen Forms die nur Komponenten mit Name Typ1..99 schrecklich aus und wenn du viele Komponenten vom selben Typ aner für unterschiedliche Dinge hast ist das auch alles andere als ein Spass damit zu arbeiten. Zum Beispiel hat er 16 Shapes als Felder und dazu noch 4 Shapes für irgendwas anderes. Wenn die 16 Feldshapes jetzt von 1-16 gehen, hat er sogar noch eher Glück gehabt. Wenn dann aber z.B. noch 10 Shapes hinzukommen die er auf ähnliche Weise ansprechen will gleicht die Programmierung eher einem Ratespiel. Vorallem wenn mal später jemand anderes das Programm ändern oder erweitern soll. Ja, ich weiß, das ist nur ein kleiner Test. Aber wenn er sich das jetzt so angewöhnt, wird er das später auch nicht viel anders machen. Lieber von anfang an korrekt ist meine Meinung. Eine Komponente bekommt einen Namen, so dass man wenn man nur den Quelltext sieht schon weiß was es ist. Hm, ok, Spielfeld1..Spielfeld16 als Namen würden in dem Fall auch passen und eindeutig sein Zitieren
geloescht_JesterDay Geschrieben 25. Februar 2008 Geschrieben 25. Februar 2008 Hab mir das grad nochmal angesehen und mir ist aufgefallen, dass man das ja noch besser und eleganter machen kann. Du machst das nciht über eine Prozedur (activateShape), sondern, ganz OOP like, über eine Event. Dazu schreibst du erstmal eine Event-Prozedur (Parameter bin ich mir nicht mehr sicher, kannst du aber bei jedem OnClick Event abgucken): procedure shapeClick(Sender: TObject) being if FActiveShape <> nil then // das hab ich oben auch vergessen begin FActiveShape.color:= cColorInactive; end; FActiveShape:= (Sender as TShape) FActiveShape.color:= cColorActive; end; [/code] Und dann weißt du beim Erzeugen den Shapes dieses Event zu [code] FShapesArray[index].OnClick:= shapeClick; Somit brauchst du gar nichts weiter zu tun und deine Shapes reagieren auf dein Klicken. Wie oben schon gesagt: Angaben ohne Gewähr. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.