Autor Beitrag
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Mo 07.02.11 19:20 
Hallo!

Ich bin gerade dabei, ein Spiel zu programmieren und achte dabei auf Trennung von Daten und Darstellung. Klappt bisher auch bestens.
Dabei bietet es sich aber öfter an, ein und dieselbe Schleife, die zB. ein Array befüllt, gleich auch zum Zeichnen zu nutzen, statt eine separate Schleife dafür zu schreiben.

Meine Frage an euch: Wie macht ihr das?
So:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
  {Füllt das Array und zeichnet auf's Board}
  for x := 0 to High(aBoard) do
    for y := 0 to High(aBoard) do
  begin
    aBoard[x, y] := tmpObj;
    DrawBoard(x, y, iIndex, tmpBitmap);
  end;

Oder so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
  {Füllt das Array}
  for x := 0 to High(aBoard) do
    for y := 0 to High(aBoard) do
  begin
    aBoard[x, y] := tmpObj;
  end;

  {Zeichnet auf's Board}
  for x := 0 to High(aBoard) do
    for y := 0 to High(aBoard) do
  begin
    DrawBoard(x, y, iIndex, tmpBitmap);
  end;

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Crombo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 54
Erhaltene Danke: 8

Windows 7, Windows Vista, Windows XP
Delphi XE Architect, Visual Studio 2010 Professional
BeitragVerfasst: Mo 07.02.11 19:26 
Hallo,

hast du einen Objektorientierten Ansatz? Ich nehme jetzt einfach mal an: JA ;)

Dann hast du auf der einen Seite die Datenhaltung in einer Map und auf der anderen Seite eine Klasse, die die ganze Darstellung übernimmt. Diese holt sich von der Map die Daten der einzelnen Felder (bearbeitet diese aber nicht eigentständig) und zeichnet das dann entsprechend auf den Screen.

Crombo

_________________
one day your life will flash before your eyes. make sure it's worth watching
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Mo 07.02.11 19:36 
user profile iconCrombo hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,

hast du einen Objektorientierten Ansatz? Ich nehme jetzt einfach mal an: JA ;)

Dann hast du auf der einen Seite die Datenhaltung in einer Map
Ich nutze ein Array, das das Spielfeld und seine Elemente hält.

user profile iconCrombo hat folgendes geschrieben Zum zitierten Posting springen:
und auf der anderen Seite eine Klasse, die die ganze Darstellung übernimmt. Diese holt sich von der Map die Daten der einzelnen Felder (bearbeitet diese aber nicht eigentständig) und zeichnet das dann entsprechend auf den Screen.
Es ist eine einfache Prozedur, der ich übergebe, an welcher Position was zu zeichnen ist.
Ich mache das zur Zeit wie oben: Zuerst ins Array, dann zeichnen, alles in ein und der selben Prozedur. Wenn die Spielerfigur zB. einen Schritt nach oben machen soll, dann zuerst das Array ändern, danach zeichnen. Ich zeichne also nicht jedesmal das gesamte Board, sondern nur die aktuelle Änderung.

Das geht recht flott voran, aber es stört mich irgendwie, dass dabei Array-Code und Code zum Zeichnen nicht völlig getrennt sind. Wenn ich mir's recht überlege, könnte das den Programmcode bei zunehmende Komplexität schwer zu warten machen.

Im Grunde sind die Daten und die Grafik voneinander getrennt, aber der Code, der das macht, steht oft in ein und derselben Prozedur.

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Crombo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 54
Erhaltene Danke: 8

Windows 7, Windows Vista, Windows XP
Delphi XE Architect, Visual Studio 2010 Professional
BeitragVerfasst: Mo 07.02.11 19:40 
Um eine saubere Trennung zustande zu bringen, würde ich auf OOP umsatteln. Dann kannst du auch Sichtbarkeiten und so weiter für alle Eigenschaften einstellen, damit alle Daten nur an jene preisgegeben werden, die auch wirklich etwas damit zu tun haben.

Crombo

_________________
one day your life will flash before your eyes. make sure it's worth watching
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 11.02.11 21:44 
Bisher klappt alles bestens mit der Trennung von Array und Darstellung, ich werde also dabei bleiben, habe es geschafft, den Code übersichtlich zu halten. Daher möchte ich nicht alles umstellen.

Jetzt stehe ich aber vor dem Problem, dass ich eine Schleife brauche, die das Array abfragt, ob ein oder mehrere bestimmte Elemente (= Spielfiguren) vorhanden ist/sind und ob der Array-Platz davor oder danach unbelegt ist, um dann das Element an diesen Platz zu zu setzen (in diesem Pseudocode soll "gesuchtesElement" versetzt werden):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  for x := 0 to High(aBoard) do
    for y := 0 to High(aBoard) do
  begin
    if (aBoard[x, y] = gesuchtesElement) and (aBoard[x, y+1] = unbelegt then
    begin
      aBoard[x, y] := unbelegt;
      aBoard[x, y+1] := gesuchtesElement;
    end;
  end;

Das klappt zwar, aber wenn ich mehrere Elemente habe, die "gesuchtesElement" sind, wird jedes einzeln nacheinander versetzt. Ich möchte aber, dass sie alle zugleich versetzt werden.
Der Sinn ist, dass ich bewegte Spielfiguren haben möchte, die aber alle gleichzeitig bewegt werden.

Ausserdem soll das alles flüssig gehen und das Programm soll Tastatureingaben akzeptieren, was aber kein Problem sein sollte. Trotzdem für mich nicht zu schaffen...

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 11.02.11 23:33 
Leider macht es Delphi nicht unbedingt einfach, Daten und Darstellung gut zu trennen (verglichen mit bspw. WPF). Wenn alles schön getrennt ist, sollte es möglich sein, die View von den Daten komplett abzuhängen und zu einem beliebigen Zeitpunkt wieder anzuhängen, oder auch zwei verschiedene Views parallel an die Daten zu hängen. So ist es bswp. auch einfach möglich, den Spielstand abzuspeichern. Da gibt es geeignete Patterns wie MVC, MVP oder MVVM, wobei nicht alles in Delphi machbar oder praktikabel ist.

Wenn Performance nicht explizit ein Problem ist, kannst du das Board auch jedesmal neu zeichnen. Mit heutiger Grafikhardware sollte das eigentlich kein Thema sein. Wenn es möglich ist, Millionen von Polygonen in eine 3D-Szene zu rendern, dürfte es doch eigentlich kein Problem sein, ein paar flache Bitmaps darzustellen ;)

Bei deinem Schleifenproblem kannst du doch einfach die Verarbeitungsreihenfolge umkehren.
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 11.02.11 23:52 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Wenn alles schön getrennt ist, sollte es möglich sein, die View von den Daten komplett abzuhängen und zu einem beliebigen Zeitpunkt wieder anzuhängen
Ist bereits realisiert.
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
So ist es bswp. auch einfach möglich, den Spielstand abzuspeichern.
Ist ebenfalls fertig.
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Wenn Performance nicht explizit ein Problem ist, kannst du das Board auch jedesmal neu zeichnen.
Wird laufend aktualisiert nach jeder Änderung im Array, es könnte aber ebensogut alles neu gezeichnet werden.
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Bei deinem Schleifenproblem kannst du doch einfach die Verarbeitungsreihenfolge umkehren.
Mein Ansatz war: gehe das gesamte Array durch, bis du das oder die Element(e) findest, überschreibe den alten Platz, setze es bzw. sie an eine anderen Platz und stelle das alles grafisch dar.
Da wird dann aber nur 1 Spielfigur bewegt, nicht mehrere.
Das verstehe ich nicht. Welche Verarbeitungsreihenfolge meinst du?

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 12.02.11 00:03 
Wie wär's wenn du alle zu bewegenden Elemente zuerst entfernst (und in eine geeignete Datenstruktur zwischenspeicherst) und dann alle neu setzst?
Ich weiss nicht, wie das Spiel aussieht aber wie wär's wenn du einfach für jeden Spieler ein Objekt mit einer Position hast, die du einfach anpasst?
Vielleicht hab ich das Problem auch falsch verstanden...
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Sa 12.02.11 08:44 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Ich weiss nicht, wie das Spiel aussieht
Ein quadratisches Spielfeld mit 28 x 28 Feldern und ein dementsprechendes Array. Also schachbrettartig aufgebaut. Da muss es doch möglich sein, dass sich bestimmte Spielfiguren bewegen!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 12.02.11 09:27 
Spieler1.X := Spieler1.X + 1; :?:
Statt das for x, for y und jedesmal ein if?
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Sa 12.02.11 12:54 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Spieler1.X := Spieler1.X + 1; :?:
Statt das for x, for y und jedesmal ein if?

Zuerst muss ich aber prüfen, ob "Spieler" (nennen wir es so) eines der Elemente im Array ist, das bewegt werden soll. Denn da gibt es ja noch andere, die an ihrem Platz fix sind.

Ich glaube, ich lasse das. Wird zu umständlich, andauernd das gesamte Array durchzugehen und womöglich 20 oder mehr Elemente zugleich(!) zu bewegen, das Spiel dabei auch noch flott und flüssig zu halten und auf Ereignisse zu reagieren, dann die jeweiligen Schleifen sauber zu verlassen - und, und, und.

Danke aber für die Tipps! Haben sie mir doch die Anregung gegeben, auf Tastatureingaben (Pfeiltasten) zu reagieren und da etwas zu machen!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!