![]() |
Bingo Karte
Guten Tag zusammen und frohes neues.
Wahrscheinlich ist das hier der falsche Bereich und die Frage schonmal da gewesen. Ich habe aber nichts gefunden. Ich muss ein Bingo Programm schreiben. Die Zahlen für die einzelnen Felder müssen hierbei den einzelnen Feldern zugewiesen werden. Nun ist meine Frage: Kann man in einer For Schleife bei des Beschreibung des Panels eine Variable einsetzen? ich hatte mir das in etwa so vorgestellt: var i : integer; p : string; begin randomize; for i := 1 to 25 do begin KZahlen[i] := random(99)+1; p := inttostr(i + 5); //Es beginnt mit Panel6 Form1.Panel[p].Caption := KZahlen; end; Ich hoffe ihr könnt mir helfen. morgen ist Abgabe und ich bin echt verzweifelt. Edit: Hat sich erledigt. Wie so oft sucht man lange die Lösung und kaum fragt man andere, findet man sie selbst. Falls es jemanden interessiert, ich habe das ganze jetzt so gelöst. var i : integer; p : string; KZahlen : Array[1..25] of integer; begin randomize; for i := 1 to 25 do begin KZahlen[i] := random(99)+1; p := inttostr(i + 5); TPanel(Form1.FindComponent('Panel'+p)).Caption := inttostr(KZahlen[i]); end; |
AW: Bingo Karte
Hey! Willkommen in der DP! :)
Ich weiß, du bist vermutlich einfach erleichtert, dass das jetzt so läuft; aber es gibt noch eine elegantere Lösung. Du "suchst" jetzt quasi jedes Panels anhand seines Namens.
Delphi-Quellcode:
TPanel(Form1.FindComponent('Panel'+p))
Einfachere Zugriffe auf deine Panels bekommst du, wenn du Referenzen zu deinen Panels in einem Array oder einer Liste speicherst.
Delphi-Quellcode:
Warum ist diese Lösung schöner als die "FindComponent"-Lösung?
var
fPanels : Array[0..24] of TPanel; // beispiel array 1. wegen der Typsicherheit: mit
Delphi-Quellcode:
versuchst du die Instanz die du mit FindComponent erhälst auf den Typ TPanel zu casten. Problem: Du kannst im Allgemeinen nicht sicher sein, dass es sich bei deiner Instanz tatsächlich um eine Instanz oder ein Derivat von TPanel handelt!
TPanel()
(Stelle dir einfach vor, da hat jemand in geistiger Umnachtung ein TButton oder so "Panel20" genannt. Dann kannst du da gegen die Wand laufen, weil ein TButton kein TPanel ist; zugegeben: das Beispiel ist etwas konstruiert...) 2. Zugriff: findComponent braucht intern String Vergleiche, um die passende Instanz zu finden. In einem Array auf das du direkt mit dem richtigen Index zugreifst geht das quasi sofort! (ist schneller) Ich hoffe, ich konnte Dir helfen! :wink: Brighty |
AW: Bingo Karte
Vielen Dank. Das ist ja noch besser.
Ich stehe schon vor dem nächsten Problem. Ich möchte, dass bei einem Klick auf ein Panel geprüft wird ob die Zahl mit der gezogenen übereinstimmt. Ist es möglich eine Allgemeine Procedure zu schreiben, bei der ich nicht das Panel genau angeben muss (also Form1.Panelx.Caption) sondern sagen kann, dass geklickte Panel soll geprüft werden? |
AW: Bingo Karte
Im OnClick-Ereignis jedes Panels wird Dir dieses im Sender-Parameter mitgegeben. Du kannst also eine allgemeine Ereignisbehandlungsroutine dafür schreiben und jedem Panel zuweisen.
|
AW: Bingo Karte
Zitat:
|
AW: Bingo Karte
Ich habe mal ein Beispiel geschrieben (da ich Deine Delphi-Version nicht kenne, vorsichtshalber in Delphi 7). Zunächst die Definition des Formulars:
Delphi-Quellcode:
Jetzt die einzelnen Methoden: InitializePanels erzeugt die Panels zur Laufzeit, richtet sie aus und weist ihrer Tag-Eigenschaft eine zufällige Zahl zu. Diese wird auch gleich mit dargestellt.
type
TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private-Deklarationen } FPanels: array[1..5, 1..5] of TPanel; // 5 Reihen zu je 5 Panels procedure InitializePanels; // Initialisierungsroutine zum Befüllen des Arrays procedure DoOnPanelClick(Sender: TObject); // Ereignishandler für das OnClick jedes Panels public { Public-Deklarationen } end;
Delphi-Quellcode:
Jetzt der zugewiesene Handler für das OnClick (Methode DoOnPanelClick):
procedure TForm1.InitializePanels;
const PANELWIDTH = 40; //Kantenlänge jedes Panels var x, y: integer; ALeft, ATop: integer; Panel: TPanel; begin ATop := 10; for y := Low(FPanels) to High(FPanels) do begin ALeft := 10; for x := Low(FPanels[y]) to High(FPanels[y]) do begin Panel := TPanel.Create(self); Panel.Parent := self; Panel.Left := ALeft; Panel.Top := ATop; Panel.Width := PANELWIDTH; Panel.Height := PANELWIDTH; Panel.Tag := Random(99) + 1; Panel.Caption := IntToStr(Panel.Tag); Panel.OnClick := DoOnPanelClick; FPanels[x, y] := Panel; inc(ALeft, PANELWIDTH); end; inc(ATop, PANELWIDTH); end; end;
Delphi-Quellcode:
Und im OnCreate-Ereignis des Formulars wird der Zufallsgenerator angeworfen und die InitializePanels-Methode aufgerufen.
procedure TForm1.DoOnPanelClick(Sender: TObject);
begin if Sender is TPanel then ShowMessage(IntToStr(TPanel(Sender).Tag)); end;
Delphi-Quellcode:
Hilft Dir das weiter?
procedure TForm1.FormCreate(Sender: TObject);
begin Randomize; InitializePanels; end; |
AW: Bingo Karte
Das hätte mir sehr viel Arbeit beim erstellen gespart.
Mein Problem war eigentlich, dass bei dem Klicken eines Panels geprüft werden soll, ob die Caption mit der aktuellen gezogenen Zahl übereinstimmt. Also einfach testen, ob "Ziehung" und Form1.Panelx.Caption übereinstimmen. Und das möglichst so, dass ich nicht für jedes der 25 Panels den Ganzen Code wiederholen muss. |
AW: Bingo Karte
Das wäre dann in meinem Beispiel innerhalb von DoOnPanelClick, statt des ShowMessage dann halt auf Gleichheit prüfen und entsprechend reagieren.
|
AW: Bingo Karte
Tut mir leid ich stehe auf dem Schlauch. habe das jetzt so versucht:
Delphi-Quellcode:
Hab leider echt keinen Plan davon.
var Pan : string;
begin if sender is TPanel then Begin Pan := Form1.TPanel(Sender).Caption; If Pan = Ziehung then begin sender(TPanel).Enabeld := false; sender(TPanel).Color := clRed; end; end; |
AW: Bingo Karte
Zitat:
Delphi-Quellcode:
) Speicher für die Panels. Diesen Speicher solltest du in deinem Destruktor (spätestens) wieder mit
TPanel.Create(self)
Delphi-Quellcode:
für jedes einzelne Panel aus dem Array freigeben. Ich weiß, dass das jetzt nicht zur Beantwortung der primären Frage dieses Threads beiträgt... :P
Panel.Free
Ich habe damals beigebracht bekommen, dass man am Besten zeitnah für jedes Create, das man schreibt, ein Free spendiert. Vielleicht hilft dir dieser Tipp noch weiter... :thumb: Brighty |
Nur mal so als Idee
Man könnte doch auch einfach ein StringGrid nehmen und dort für die amerikanische Variante 5 x 5 Felder oder für die englische Variante 3 x 9 Felder anlegen. In die so entstandenen Zellen schreibt man die Zahlen rein, die man braucht, oder auch einen Jokernamen und kann dann sehr leicht beim Klick auf das StringGrid rausfinden, welchen Wert der Benutzer angeklickt hat. Vor vielen Jahren hab ich das mal so ähnlich bei einem Lottozahlenprogramm gemacht, allerdings mit Grafiken, die beim OnDraw dort reingezeichnet werden. Beim Klick auf eine Zelle wird geprüft, ob die Zelle bereits angeklickt wurde, wenn nein, wird eine zweite Grafik in diese Zelle gemalt, die dunkler ist als Zeichen dafür, dass die aktiviert wurde, und es wird natürlich auch geprüft, wie viele Felder angeklickt werden dürfen je nach Spielart. Das OnClick-Handling sieht dann so aus:
Delphi-Quellcode:
Nun ist Bingo nicht Lotto, hat demnach auch keine feststehende Zahlenreihe von 1-49 und muss da natürlich anders programmiert werden. Man könnte die Zahlenreihe in einem Record speichern, für den man dann ein Array anlegt, nur mal so als Idee.
procedure TForm1.StrGrid_SpielDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
var Zahl : Integer; begin Zahl := SpaltZeilToZahl(ACol,ARow); // in dieser Function wird die Zahl anhand von Spalte und Zeile ermittelt if Zahl < 1 then Exit; FeldZeichnen(StrGrid_Spiel.Canvas,Rect,Zahl); // diese procedure zeichnet eine bestimmte Grafik in die Zelle end; |
AW: Bingo Karte
Form1 hat da nichts zu suchen, und Du castest falsch herum. So sollte es klappen (ungetestet, da im Editor getippt):
Delphi-Quellcode:
var
Pan : string; Panel: TPanel; begin if Sender is TPanel then begin Panel := TPanel(Sender); Pan := Panel.Caption; If Pan = Ziehung then begin Panel.Enabled := false; Panel.Color := clRed; end; end; |
AW: Bingo Karte
Super genau das habe ich gesucht. Vielen Dank.
Eine Frage hab ich noch. Wo muss ich die Allgemeine Procedur den schrieben, die ich dann in den Events der Panels benutze? hab die bis jetzt immer einfach direkt nach der Implementation geschrieben:
Delphi-Quellcode:
Aber so bekomme ich eine Fehlermeldung wegen dem sender.
implementation
{$R *.lfm} { TForm1 } procedure TestB; var Pan : string; Panel : TPanel; begin if sender is TPanel then Begin Panel := TPanel(sender); Pan := 'B'+Panel.Caption; If Pan = Ziehung then begin Panel.Enabled := false; Panel.Color := clRed; end; end; end; |
AW: Bingo Karte
Schau Dir doch mein Beispiel noch einmal genau an, da gibt es auch keine parameterlose reguläre Prozedur.
|
AW: Bingo Karte
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz