Autor Beitrag
tetris84
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31



BeitragVerfasst: Mo 24.10.11 22: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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Mo 24.10.11 22:48 
:welcome:

Als Spielbrett würde ich sowas machen:

ausblenden Delphi-Quelltext
1:
Spielbrett: array [0..49of array [0..49of TCell;					


Als einzelne Zelle könnte man sich dann z.B. Speichern ob da schon was liegt:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
type TCell=record
  Belegt: boolean;
//BelegtDurch: TSpielstein;
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 14



BeitragVerfasst: Mo 24.10.11 22:49 
Das wäre mit einem zweidimensionalen Array möglich.
ausblenden Delphi-Quelltext
1:
Var Feld : Array[0..19,0..19of TFeld;					


Die Daten eines Felds kannst Du in einem Record speichern.
ausblenden 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:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31



BeitragVerfasst: Di 25.10.11 18: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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 25.10.11 18:14 
user profile icontetris84 hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Di 25.10.11 18: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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31



BeitragVerfasst: Di 25.10.11 18: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



ausblenden 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));           //Drag & Drop 
  MouseDown:= True;                                   //Drag & Drop
round(X/10)*10; round(Y/10)*10;
End;


Edit: Per Drag and Drop

Moderiert von user profile iconMartok: Delphi-Tags hinzugefügt
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Di 25.10.11 19: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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 14



BeitragVerfasst: Di 25.10.11 19: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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Di 25.10.11 19:28 
Meiner Erfahrung nach ist Drag&Drop nicht so kompliziert.

OnMouseDown:

ausblenden Delphi-Quelltext
1:
2:
  DragDelta.X := X-Spielstein.Left; //Y analog
  MouseDown := true;


OnMouseUp:
ausblenden Delphi-Quelltext
1:
  MouseDown := false;					


OnMouseMove:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  if MouseDown then
     begin
       Spielstein.Left := X-DragDelta.X;  //PS: hier brauchen wir zusätzlich den round-Code von oben für die Rasterung.
     end;

_________________
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31



BeitragVerfasst: Di 25.10.11 19: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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Di 25.10.11 19: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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31



BeitragVerfasst: Do 27.10.11 16: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?



ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Do 27.10.11 17:20 
user profile icontetris84 hat folgendes geschrieben Zum zitierten Posting springen:

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.


user profile icontetris84 hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden 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 :mrgreen: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Do 27.10.11 17:41 
Ich habe es mal als Beispielprojekt gemacht, musste mit dem DragDelta jetzt auch erstmal nachdenken :D

ausblenden volle Höhe 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:
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.X := round(Pos.X/55)*55;      //RasterungX
      //Pos.Y := round(Pos.Y/15)*15;      //RasterungY

      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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31



BeitragVerfasst: Di 22.11.11 13:35 
So ich hoffe mir schreibt jetzt noch jemand nach der langen Zeit. Ich hab das jetzt weiter versucht und bin dann von Drag and Drop weggegangen und habe mir überlegt das ich das ganze mit einem SGField mache.

Ich hab mir vorgestellt das man einmal auf einen Spielstein klickt und dann auf das Feld wo der Stein liegen soll und in die Zelle wird dann das Bild geladen. Nun hab ich aber keinen Anhaltspunkt mehr wie ich weiterkommen soll. Mein Code sieht bisher so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
type
    TZelle=record
      Beleget : boolean;
      BelegtDuch:String;
    end;
    Spielbrett= array [0..10of array [0..10of TZelle;


var MouseDown:boolean;
    StartPunkt: TPoint;
    path : string;
    DragDelta: TPoint;
    DragObject: TPanel;
    Bild:TBitmap;
Begin
   Bild := TBitmap.Create;
   SpielsteinPfad := 'Spielsteine\'+Zufallsstein;
   path := ExtractFilePath(Application.ExeName) + SpielsteinPfad;
End;







ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure THauptformLoopit.SGFieldDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
var Tester:Tzelle;
begin
  if (ACol = 5and (ARow=5then
     BEGIN
       Bild.LoadFromFile(path);
       SGField.Canvas.StretchDraw(Rect, Bild);
     END;
end;

procedure THauptformLoopit.SGFieldMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var col, row : integer;
begin
  SGField.MouseToCell(X, Y, col, row);
  SGField.refresh;
end;
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Do 24.11.11 21: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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31



BeitragVerfasst: Do 01.12.11 10:31 
user profile iconXion hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Do 01.12.11 10:43 
Häng Dich doch einfach in die MouseWheel-Events des Forms ....

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
tetris84 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31



BeitragVerfasst: Do 01.12.11 10:47 
Wie meinst du das? Ich hab die Steine ja zurzeit in einem TImage