Autor |
Beitrag |
tetris84
Beiträge: 31
|
Verfasst: Mo 24.10.11 21:22
Hallo,
ich hoffe mal das es sowas noch nicht gibt. Hab zwar bisschen die Suche benutzt aber nicht wirklich was gefunden.
Ich möchte auf ein Scrabble ähnliches Spielbrett verschiedene (auch Scrabble ähnliche) Spielsteine platzieren. Wie mach ich es, dass die Spielsteine das Feld vom Spielbrett genau besetzen? Ich habe mir das so vorgestelle das wenn man einen Spielstein zwischen zwei Felder legt das er sich automatisch auf das dichtere Feld "legt". Es sollte auch leicht zu prüfen sein wo der Stein liegt und ob ein Feld schon belegt ist.
Lg tetris84
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mo 24.10.11 21:48
Als Spielbrett würde ich sowas machen:
Delphi-Quelltext 1:
| Spielbrett: array [0..49] of array [0..49] of TCell; |
Als einzelne Zelle könnte man sich dann z.B. Speichern ob da schon was liegt:
Delphi-Quelltext 1: 2: 3: 4:
| type TCell=record Belegt: boolean; end; |
Zur Platzierung:
Angenommen unser Spielbrett soll 500x500 Pixel groß sein. Also ist eine Zelle 10 groß (500/50). Seien weiterhin X,Y die Position des Spielsteins (welches ja 10x10 groß ist).
=> round(X/10)*10, round(Y/10)*10 schnippt das Objekt ins Raster. Ist die Ecke z.B. bei 19/11 dann wird sie verschoben zu 20/10 (nähste Spielfeld-Zelle).
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Für diesen Beitrag haben gedankt: tetris84
|
|
rushifell
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: Mo 24.10.11 21:49
Das wäre mit einem zweidimensionalen Array möglich.
Delphi-Quelltext 1:
| Var Feld : Array[0..19,0..19] of TFeld; |
Die Daten eines Felds kannst Du in einem Record speichern.
Delphi-Quelltext 1: 2: 3: 4: 5:
| TFeld=record Buchstabe:Char; Besetzt:Boolean; ... end; |
Berechnen kannst Du den index vom Feld mit DIV. Wenn eine Feldbreite und Feldhöhe jeweils 20 Pixel beträgt:
Delphi-Quelltext 1: 2:
| Var aa:Char; aa:=Feld[X DIV 20,Y DIV 20].Buchstabe; |
Für das Spielfeld könnstest du ein TImage verwenden.
EDIT: Xion war einen Tick schneller
Für diesen Beitrag haben gedankt: tetris84
|
|
tetris84
Beiträge: 31
|
Verfasst: Di 25.10.11 17:09
Auf was würde sich x bzw y den Beziehen? Auf SpielBrettImage.Top bzw Left?
Lg tetris84
PS: Das Spielbrett ist 11*11 Steine groß
|
|
Yogu
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: Di 25.10.11 17:14
tetris84 hat folgendes geschrieben : | Auf was würde sich x bzw y den Beziehen? Auf SpielBrettImage.Top bzw Left? |
X und Y sind, soweit ich das vertanden habe, die Mauskoordinaten im OnMouseDown. Die werden relativ zum linken oberen Eck des Spielfeldes angegeben.
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Di 25.10.11 17:24
X und Y sind erstmal nur die Position deines Spielsteins, den du in das Gitter des Spielfeld einpassen willst.
Woher diese Position kommt ist eine andere Frage, das hängt davon ab, wie du die Steine platzieren lassen willst. Falls du sie per Drag&Drop verschieben kannst, dann funktioniert der oben genannte Code, aber X,Y ist nicht die Position der Maus, sondern die des Spielsteins (der natürlich von der Mausposition abhängt)
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
tetris84
Beiträge: 31
|
Verfasst: Di 25.10.11 17:28
Hmmm also wenn ich das da eingebe kommt immer der Fehler: [DCC Fehler] UHauptformLoopit.pas(181): E2014 Anweisung erforderlich, aber Ausdruck vom Typ 'Int64' gefunden
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure THauptformLoopit.Image2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Begin StartPunkt := ClientToScreen(Point(X,Y)); MouseDown:= True; round(X/10)*10; round(Y/10)*10; End; |
Edit: Per Drag and Drop
Moderiert von Martok: Delphi-Tags hinzugefügt
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Di 25.10.11 18:16
Natürlich geht das so nicht, und wenn es ginge, dann würde es dir nichts bringen (du speicherst ja das Ergebnis nirgends).
Du könntest schreiben:
Delphi-Quelltext 1:
| Spielstein.Left := round(X/10)*10; |
//PS:
das solltest du in OnMouseMove schreiben
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
rushifell
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: Di 25.10.11 18:23
Mit X,Y meine ich die Mauskoordinaten im OnMouseMove oder OnMouseDown des Images. Per Drag und Drop ist das ganze natürlich schöner, aber wesentlich schwieriger zu implementieren. Wesentlich einfacher wäre es, einen Spielstein zu markieren, den Maus-Cursor auf dem Feld zu platzieren auf das Du den Stein setzten möchtest und den Stein durch Druck der linken Taste zu setzen.
Du kannst ja das Drag und Drop auch später noch implementieren.
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Di 25.10.11 18:28
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
tetris84
Beiträge: 31
|
Verfasst: Di 25.10.11 18:44
Ist mir jetzt bisschen unangenehm zu Fragen aber für was steht dann DragDelta?
Also es muss auch defenitiv Drag&Drop sein. Anders sieht es einfach nicht gut aus
Lg tetris84
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Di 25.10.11 18:53
DragDelta ist einfach nur vom Typ TPoint.
Die Idee dahinter:
Du speicherst dir zu Beginn, wo du den Spielstein angeklickt hast. Du klickst ja "irgendwo" in die Mitte. Wenn du dann im OnMouseMove den Spielstein abhängig von der Mausposition verschiebst, dann sollte dieses "ungefähr in der Mitte" identisch sein, sonst ruckelt der Spielstein am Anfang. Du kannst es ja einfach mal ohne ausprobieren
//Edit:
Da fällt mir was ein:
Wie du schon in deinem Code richtig zeigst musst du mit "Screen-Koordinaten" arbeiten, weil du sonst in den Funktionen bei X,Y verschiedene Koordinatensysteme hast. Also immer erstmal ClientToScreen() verwenden.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Für diesen Beitrag haben gedankt: tetris84
|
|
tetris84
Beiträge: 31
|
Verfasst: Do 27.10.11 15:37
Also an mählig hab ich das Gefühl ich bin zu doof :/
Ich habs (meiner Meinung nach) alles richtig gemacht und es passiert garnichts
Noch irgentwelche Ideen? Oder hab ich einfach was übersehen?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| procedure THauptformLoopit.Spielstein1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Begin StartPunkt := ClientToScreen(Point(X,Y)); MouseDown:= True; End;
procedure THauptformLoopit.Spielstein1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var AktuellerPlatz: TPoint; Begin If MouseDown then with Sender as TImage do Begin AktuellerPlatz := ClientToScreen(Point(X,Y)); x := round(Y/11)*11; Left:= AktuellerPlatz.X - StartPunkt.X; y := (round(Y/11)*11); Top:= AktuellerPlatz.Y -StartPunkt.Y End; End;
procedure THauptformLoopit.Spielstein1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Begin MouseDown:=False; End; |
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Do 27.10.11 16:20
tetris84 hat folgendes geschrieben : |
Ich habs (meiner Meinung nach) alles richtig gemacht und es passiert garnichts
Noch irgentwelche Ideen? Oder hab ich einfach was übersehen?
|
Meiner Meinung nach hast du was übersehen, was sehr zum Übersehen einläd Hat also nichts mit doof zu tun.
Angenommen du hast die Maus auf deinem Spielstein und bewegst die dort weg. Dann ist diese Bewegung ja ruckartig (d.h. mehrere Pixel auf einmal). Du bist also sehr schnell nicht mehr über dem Spielstein, sondern über dem Rest der Form => Es wird das OnMouseMove der Form (oder was auch immer unter der Maus ist) ausgelöst
Du musst also für alle Objekte MouseOver setzen (auf die MouseOver-Funktion von dir). Das Problem dabei ist natürlich, dass du dann von Hand regeln musst, was gedragged wurde (nicht wie du mit Sender). Das kannst du ja beim OnMouseDown speichern.
tetris84 hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure THauptformLoopit.Spielstein1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var AktuellerPlatz: TPoint; Begin If MouseDown then with Sender as TImage do Begin AktuellerPlatz := ClientToScreen(Point(X,Y)); x := round(Y/11)*11; Left:= AktuellerPlatz.X - StartPunkt.X; y := (round(Y/11)*11); Top:= AktuellerPlatz.Y -StartPunkt.Y End; End; | |
Die markierte Stelle sollte wohl X heißen
Fällt dir an dem Code was auf? Du weißt X und Y was zu, benutzt es aber niemehr. Irgendwie sinnlos, oder Aber egal, das ist ja nur die Berechnung vom Raster.
Ein andrer Punkt ist: "AktuellerPlatz" ist in Screen-Koordinaten (d.h. vom ganzen Screen=Bildschirm). Beim setzen von Left und Top musst du diese erst in Form-Koordinaten umwandeln, falls dein Image auf einer Form liegt (bei Panel analog).
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Do 27.10.11 16:41
Ich habe es mal als Beispielprojekt gemacht, musste mit dem DragDelta jetzt auch erstmal nachdenken
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| var Clicked: boolean; DragDelta: TPoint; DragObject: TPanel;
[...]
procedure TForm1.Panel2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Clicked := true; DragDelta.X := X; DragDelta.Y := Y; DragObject := Sender as TPanel; end;
procedure TForm1.Panel2MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Clicked := false; end;
procedure TForm1.Panel2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var Pos: TPoint; begin if Clicked then begin Pos := (Sender as TWinControl).ClientToScreen( Point(X-DragDelta.X,Y-DragDelta.Y) ); Pos := Form1.ScreenToClient( Pos );
DragObject.Left := Pos.X; DragObject.Top := Pos.Y; end; end; |
Einloggen, um Attachments anzusehen!
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
tetris84
Beiträge: 31
|
Verfasst: Di 22.11.11 12:35
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Do 24.11.11 20:12
Was hast du denn nun vor?
Die Sache mit dem StringGrid find ich irgendwie nicht sehr professionell. Ich hätte eher eine Matrix (2D-Array) mit TImage verwendet.
Im wesentlichen musst du jetzt erstmal eine Reihe von Bildern anlegen mit den Steinen, die der User hat. Und dann musst du, wenn du dort einen anklickst die ID speichern und danach wenn du aufs Feld klickst den dort reinpacken (TZelle) und das Bild laden/kopieren.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
tetris84
Beiträge: 31
|
Verfasst: Do 01.12.11 09:31
Xion hat folgendes geschrieben : | Was hast du denn nun vor?
Die Sache mit dem StringGrid find ich irgendwie nicht sehr professionell. Ich hätte eher eine Matrix (2D-Array) mit TImage verwendet.
Im wesentlichen musst du jetzt erstmal eine Reihe von Bildern anlegen mit den Steinen, die der User hat. Und dann musst du, wenn du dort einen anklickst die ID speichern und danach wenn du aufs Feld klickst den dort reinpacken (TZelle) und das Bild laden/kopieren. |
Danke nochmal. Hab das fast genauso gemacht. Bin jetzt grade dabei eine Schummelfunktion ein zu bauen. Ich möchte nach doppelklick auf einen Spielstein, mit dem Mausrad scrollen und zwischen allen verfügbaren Steinen einen auswählen. Wie gehts das? Mit ScrollBox?
Lg tetris84
|
|
bummi
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 01.12.11 09:43
Häng Dich doch einfach in die MouseWheel-Events des Forms ....
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
tetris84
Beiträge: 31
|
Verfasst: Do 01.12.11 09:47
Wie meinst du das? Ich hab die Steine ja zurzeit in einem TImage
|
|
|