![]() |
"MineSweeper" - Probleme mit Rundtime-Buttons
Hallo DP,
ich stehe mal wieder kurz vorm Verzwefeln -.- Ich sitze atm an einer MineSweeper-Version und habe für die Minenfelder Runtime-Buttons erstellt. Die werden alle erstellt, sind sichtbar und funktionieren alle sehr gut. Aber wenn ich dann anhand der Mausposition versuche herauszufinden, welcher der Buttons gedrückt worden ist, bekomme ich seltsame Ergebnisse! Hier mal der Code:
Delphi-Quellcode:
Das ist die Prozedur, die ausgelöst wird wenn IRGENDEINER meiner Runtime-Buttons gedrückt wird.
procedure TFrmMS.MineBtnDadClick(Sender: TObject);
var x, y: integer; RealPosX, RealPosY: integer; Found: boolean; begin RealPosX := Mouse.CursorPos.X - Left; RealPosY := Mouse.CursorPos.Y - Top ; ShowMessage(IntToStr(RealPosX)+', '+IntToStr(RealPosY)); x:=0; repeat begin if ((MineBtn[x, 0].Left < RealPosX) and (MineBtn[x, 0].Left + MineBtn[0, 0].Width > RealPosX)) then begin y:=0; repeat begin if ((MineBtn[x, y].Top < RealPosY) and (MineBtn[x, y].Top + MineBtn[x, y].Height > RealPosY)) then Found := TRUE; y:=y+1; end; until ((y = RowsForLevel) or Found); end; x:=x+1; end; until ((x = ColsForLevel) or Found); Aufdecken(x, y); end; (MineBtn ist ein Array aus TSpeedButtons (groß genug!) und Rows/ColsForLevel sind integers, der Name erklärt den Rest) Misteriöserweise bekomme ich immer ein "y" welches 2 zuviel ist als es eingentlich sein müsste und wenn ich das einfach korrigiere indem ich später sage y ist y-2, dann erhalte ich immer Fehler wenn ich Buttons der rechten unteren Ecke drücke. Also iwas stimmt da nicht, aber ich kann den Fehler nicht finden... Wer kann helfen? Danke schonmal, greetZ DaSebi |
Re: "MineSweeper" - Probleme mit Rundtime-Buttons
Warum verwendest du nicht den Sender-Parameter des Click-Events?
|
Re: "MineSweeper" - Probleme mit Rundtime-Buttons
Guten Abend,
die könntest beim Erstellen der Buttons jedem Button einen Tag-Wert mitgeben. Anhand dieses Tag kannst Du den Button dann identifizieren. Im Button Click Ereignis kannst Du dann so darauf zugreifen:
Delphi-Quellcode:
Du kannst dann ein Click Ereignis für alle Buttons benutzen, so wie mkinzler schon geschrieben hat.
(sender as TButton).tag
Grüße Klaus |
Re: "MineSweeper" - Probleme mit Rundtime-Buttons
@mkinzler
Meinst du damit dass jeder Button als der Sender gilt? Das heißt ja dass ich mit Sender.XXX auf alles zugreifen könnte und anhand von Werten wie zB. dem Sender.Left ganz einfach Reihe/Spalte des Butons herausbekomme -.- Na klasse xD :wall: :wall: :wall: Vielen Dank! Meine Methode war wohl mit Kanonen auf Spatzen geschossen ^^ @klaus01 das mit dem tag wäre für meine Methode dank zweidimensionalen Array aber entwas aufwendiger, trotzdem danke für diesen Ansatz! greetZ DaSebi |
Re: "MineSweeper" - Probleme mit Rundtime-Buttons
Der Parameter Sender ist eine Referenz auf das auslösende Objekt. Der Tag erleichtert die Identifizierung des Buttons.
|
Re: "MineSweeper" - Probleme mit Rundtime-Buttons
Ja ich weiß was der Sender ist, aber ich dachte dass der Sender immer mein realer Button wäre, denn alle OnClick-Ereignisse hatte ich auf seines umglenkt...
Hier aber mal der funktionierende Code für alle Interessierten:
Delphi-Quellcode:
Vielen Dank nochmal!
procedure TFrmMS.MineBtnDadClick(Sender: TObject);
var x, y: integer; i, z: integer; Found: boolean; begin i:=0; Found := FALSE; while ((i < ColsForLevel) and not (Found)) do begin z:=0; while ((z < RowsForLevel) and not (Found)) do begin if(MineBtn[i, z] = Sender) then Found := TRUE else z := z+1; end; if not (Found) then i := i+1; end; x := (MineBtn[i, z].Left - MineBtn[0, 0].Left) div MineBtn[0, 0].Width; y := (MineBtn[i, z].Top - 50) div MineBtn[0, 0].Height; Aufdecken(x, y); end; |
Re: "MineSweeper" - Probleme mit Rundtime-Buttons
Was meinst du mit realer Button?
|
Re: "MineSweeper" - Probleme mit Rundtime-Buttons
Als real meine ich einen Button den ich mir real vorstellen kann xD
Also einen den ich per Drag&Drop auf das Formular gezogen hab, der unsichtbar ist und einfach nur dazu dient, alle OnClicks auf sich zu nehmen. Ich weiß das real ganz sicherlich nicht der richtige Begriff dafür ist, aber ich fand den iwie passend ^^ Allerdings habe ich mit meiner Variante da oben ein kleines Problem! In einem völlig unersichtlichen Muster bekomme ich Zugriffsverletzungen im Speicher. Das wird daher rühren, dass ich eine Prozedur hab, die die Buttons löscht wenn man auf sie klickt und es keine Mine ist. Dazu hier mal wieder die Prozedur (die von oben ist noch aktuell):
Delphi-Quellcode:
Weder das Rechteck noch die Schrift erscheinen obwohl sie das meiner Meinung nach egtl müssten ^^
procedure TFrmMS.SmileForUser(ACol, ARow: integer);
var TopLeft, BtmRight: TPoint; begin if not (BtnDestroyed[ACol, ARow]) then begin MineBtn[ACol, ARow].Destroy; BtnDestroyed[ACol, ARow] := TRUE; end; TopLeft.X := MineBtn[0, 0].Left + ACol*MineBtn[0, 0].Width; TopLeft.Y := MineBtn[0, 0].Top + ARow*MineBtn[0, 0].Height; BtmRight.X := TopLeft.X + MineBtn[0, 0].Width; BtmRight.Y := TopLeft.Y + MineBtn[0, 0].Height; Canvas.TextRect(rect(TopLeft, BtmRight), TopLeft.X, TopLeft.Y, MinesArround(ACol, ARow)); BtnFace.Caption := ':-)'; end; Und ab und zu bekomme ich diese Zugriffsverletzungen TROTZ meinem Schutz, dass ein Button nicht zweimal gelöscht werden kann...woran kann denn das jetzt liegen O.o |
Re: "MineSweeper" - Probleme mit Rundtime-Buttons
Und die anderen?
|
Re: "MineSweeper" - Probleme mit Rundtime-Buttons
Na die anderen werden zur Laufzeit erstellt.
Dazu habe ich eine Prozedur, die je nach Schwierigkeitsgrad 17 bis max 40 Buttons (zweidimensional) erstellt. Hier die Prozedur:
Delphi-Quellcode:
procedure TFrmMS.GenerateBtns;
var BtnIndexX, BtnIndexY: integer; begin For BtnIndexX:=0 to ColsForLevel-1 do For BtnIndexY:=0 to RowsForLevel-1 do begin MineBtn[BtnIndexX, BtnIndexY] := TSpeedButton.Create(FrmMS); MineBtn[BtnIndexX, BtnIndexY].Height := 14; MineBtn[BtnIndexX, BtnIndexY].Width := MineBtn[BtnIndexX, BtnIndexY].Height; MineBtn[BtnIndexX, BtnIndexY].Top := 50 + BtnIndexY * 14; MineBtn[BtnIndexX, BtnIndexY].Left := (ClientWidth - (ColsForLevel-1) * MineBtn[BtnIndexX, BtnIndexY].Width) div 2 + BtnIndexX * MineBtn[BtnIndexX, BtnIndexY].Width; MineBtn[BtnIndexX, BtnIndexY].Parent := FrmMS; MineBtn[BtnIndexX, BtnIndexY].OnClick := MineBtnDad.OnClick; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:38 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 by Thomas Breitkreuz