Autor Beitrag
Maa83
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 160

Win XP Pro
D6 Ent
BeitragVerfasst: Do 08.01.04 12:04 
Hallo,
ich bin gerade dabei ein 2D-Spiel zu entwickeln...

Und zwar mach ich das nach folgendem Prinzip:

Ein 2-Dimensionales Array für die Landschaft (da stehen Zahlen drin und je nachdem zeichne ich ein anderes Landschaftsbitnmap) ich habe hier im Forum gesehen das das viele genauso machen.

so und jetzt zu den Figuren/Monstern/Artefakten/Waffen...

ich habe für jedes dieser Dinge wiederrum ein 2-Dimensionales Array in denen Zahlen drinstehen...
Funktionieren tut das ganze auch so nur wollte ich fragen ob dieser Weg gut ist oder ob das grauenhafter Programmierstiel ist...

hab nämlich noch keinerlei Erfahrung mit Spieleprogrammierung.

mfg
Maa
DaRkFiRe
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 526

WinXP Home & Professional
C, C++, Delphi
BeitragVerfasst: Do 08.01.04 14:03 
Solange der Speicherbereich nicht zu groß wird (beispielsweise sind 128x128 Felder okay, je nachdem, was man darin speichert), ist das okay, zumal Du gleich alles 2D-assoziieren kannst, quasi schnell Bezug zwischen Quellcode und Spiel selbst hergestellt werden kann (sinnvoll beim Debugging).

_________________
Lang ist der Weg durch Lehren - kurz und wirksam durch Beispiele! Seneca
Nightmare_82
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 260



BeitragVerfasst: Do 08.01.04 14:58 
wenn ich dich richtig verstanden habe, solltest du das auf jeden Fall anders machen. Eine Kreatur bewegt sich doch pixleweise. Wie willst du das denn in einem 2D-Array-speichern, pro Pixel ein Array-Feld ?
Wenn du das Array genauso groß machst wie das Feld-Array, könntest du dir evtl. den Bereich merken, aber es können ja 2 Kreaturen im selben Feld sein und eine Kreatur kann ja auch zwischen 2 Feldern sein.
Also nimm besser ein normales Array für deine Kreaturen, z.B. so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
TCreature = class{oder Record, was dir lieber ist}
X, Y : Integer;
ImageIndex : Integer;
{...}
end;

Creatures : array of TCreature; // hier ist die Liste deiner Kreaturen

{... beim Zeichnen gehst du so den Array durch:}
for i:= 0 to high(Creatures) do
begin
  drawImage(ImageIndex, Creatures[i].X, Creatures[i].Y);
end;
Maa83 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 160

Win XP Pro
D6 Ent
BeitragVerfasst: Do 08.01.04 20:44 
Ok danke erstmal ich werd das mit dem Arrays ändern (bin schon dabei) und dann noch ne Frage:

Ist es besser wenn sich das Feld merkt welche Figur(en) auf ihr stehen oder ist es besser wenn sich die Figur merkt in welchem Feld sie sich befindet... Also bei TEinheit die Eigenschaften für die Feldkoordinaten oder bei TFeld ein Array der Figuren die auf ihm stehen... ?
umpani
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 389



BeitragVerfasst: Do 08.01.04 21:16 
Die Frage ist ganz einfach beamtwortet.

Du wirst zu einem späteren Zeitpunkt eine Procedure haben, die die Bewegung der Figuren steuert.

Wenn du die x,y Wert aus dem Feld-Array nimmst, muß die Figut z.B. 80x80 Felder durchgehen. Das sind 6400 Vorgänge.
Da du z.B. nur 2 Figuren hast, sind das 6398 unnötige If-Abfragen.

Da ist es doch einfacher, den x,y Wert in einem Figuren Array zu haben, welches genauso groß ist, wie die ANzahl an figuren.
Dann hast du nämlich nur 2 If-Abfragen.

Gruß Umpani

_________________
Lernen, ohne zu denken, ist eitel; denken, ohne zu lernen, ist gefährlich. Konfuzius
Ben
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 31



BeitragVerfasst: Fr 09.01.04 18:06 
Einspruch !

Es sollte auf jeden Fall für jedes Feld gespeichert werden welche Figuren sich dort befinden. Am besten sollte beides gemacht werden, in der Figur und im Feld.

1. Wenn du das Feld zeichnest müstest du sonst alle Figuren durchgehen um die zu finden die sichtbar sind, falls aber im Feld steht welche Figuren dort stehen fällt diese Suche Weg.

2. Kollision ! Du müßtest für jede Figur prüfen ob sie mit einer anderen kollidiert, das wäre vom Aufwand her ein klassischer n² Algorithmus. Wenn aber in den Feldern steht wer sich dort befindet dann müssen nur die umliegenden Felder getestet werden.
Das gleiche gilt auch für das Problem der Zielsuche und die KI.


Achja, technisch läßt sich das ganz gut über Listen und Zeiger realisieren, dann braucht die Figur nur einmal als Variable existieren, kann aber mehrfach in verschiedenen Strukturen verlinkt sein.
G-McKree
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 178



BeitragVerfasst: Fr 09.01.04 20:33 
wenn ihr für jedes pixel speichern wollt wer oder was daruaf steht, dann nehmt doch einfach eine zweider bitmap (nicht sichtbar und genauso groß wie das spielfeld) und ordnet den feldern eine farbe zu, je nach dem was auf dem feld steht

aussederm kann man so eine bitmap dann auch einfach speichern und laden. für einen array bräuchte man da schon eine for-schleife
MathiasH
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 699

WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
BeitragVerfasst: Fr 09.01.04 21:09 
ob sich das mit dem Bitmap rentiert....
wen überhaupt, dann erst bei Mengen von sagen wir 500 Leuten auf der Karte, denn die Pixeloperationen sind realtiv langsam (auch scanline ist nicht unbedingt ein geschwindigkeitswunder außer im Vergleich zu Pixels[x, y] ;)

ich würde auf jeden Fall für die Figuren etc ein 1D array machen, bestehend aus records oder sonstwas, wo dann jedes element seine eigene, exakte position auf der Karte kennt und beim bewegen mit allen anderen figuren und der Karte geprüft wird, ab das neue Feld frei ist

auf das Argument ein Bitmap wäre leichter zu speichern gehe ich jetzt mal nicht ein.... 8)
das wär nichtmal was, wenn du mit dyn arrays nicht zurechtkommen soltest weil du dann halt einen Schritt später mit den Schleifen werkeln musst

MathiasH

_________________
"Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
Nightmare_82
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 260



BeitragVerfasst: Sa 10.01.04 19:27 
Ben hat folgendes geschrieben:
Einspruch !

Es sollte auf jeden Fall für jedes Feld gespeichert werden welche Figuren sich dort befinden. Am besten sollte beides gemacht werden, in der Figur und im Feld.

1. Wenn du das Feld zeichnest müstest du sonst alle Figuren durchgehen um die zu finden die sichtbar sind, falls aber im Feld steht welche Figuren dort stehen fällt diese Suche Weg.

2. Kollision ! Du müßtest für jede Figur prüfen ob sie mit einer anderen kollidiert, das wäre vom Aufwand her ein klassischer n² Algorithmus. Wenn aber in den Feldern steht wer sich dort befindet dann müssen nur die umliegenden Felder getestet werden.
Das gleiche gilt auch für das Problem der Zielsuche und die KI.


Achja, technisch läßt sich das ganz gut über Listen und Zeiger realisieren, dann braucht die Figur nur einmal als Variable existieren, kann aber mehrfach in verschiedenen Strukturen verlinkt sein.


er hatte doch nur ein 2D-Array, in dem Indexe für Kreaturen und so drinstanden, also hatte er noch nicht mal die Pixel-Position gespeichert. Deshalb meine Antwort. Wenn es um Optimierungen bei KI und beim Zeichnen geht, wäre dein Vorschlag natürlich gut aber ich glaube an dem Punkt ist er noch nicht.
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: So 11.01.04 16:12 
Hi.

Also ich muss Ben voll und ganz zu stimmen. Da jedes spiel früher oder später so etwas wie eine KI braucht, macht es durch aus sinn diese von anfang an ins konzept mit aufzunehmen.

Und pixelmaps würd ich auf garkeinen fall verwenden...ne schöne matrix hat sich doch sehr bewährt und wenn sich eine figur nicht genau auf dem mittelpunkt eines feldes steht, so befindet sie sich trotzdem auf dem feld! Und dies sollte man durchaus in das feld eintragen, da man sich dann zB. mit dem A* algo sämtliche kollision, durch kostenvergabe, sparen kann.

Ich würde jedes feld einen Anker-pointer auf eine einfach-gelinkte-liste geben, die dann direkt in den figur-objekten implmentiert wird. Das ist sehr effizient und bietet optimalen zugriff, da so nicht extra alle figuren überprüft werden müssen. Dieses vorgehen wird übrigens auch von namhaften profis empfohlen :wink:

cu.
max.

//edit//
PS: dieses konzept ist natürlich für maps, wo mehrere figuren gleichzeitig auf einem feld sein können.

_________________
mfg.
mâximôv
Gandalfus
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 129



BeitragVerfasst: So 11.01.04 18:12 
Ich schlage folgendes vor:

Die einheiten hat man in einem normalen array. (oder Dynamisch)
Jetzt makiert man die Felder auf denen die Einheit steht als nicht passierbar. Wenn eine Einheit beweg werden soll berechnet man einmal den Weg. Prüfft bei der anschliessenden bewegung aber auf Kollision und wenn eine Kollision dann weg neuberechnen.

Beim zeichen muss dann nochmal der gesamte Array durchgegangen werden aber ich denke das ist akzeptabel.

_________________
Wennn man feststellt, dass es drei Moeglichkeiten gibt, die einen Vorgang schiefgehen lassen koennen und man diese ausschaltet, entstehen automatisch drei neue Moeglichkeiten.
Ben
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 31



BeitragVerfasst: So 11.01.04 18:29 
Zitat:
Jetzt makiert man die Felder auf denen die Einheit steht als nicht passierbar.


Wodurch man automatisch festlegt das auf jedem Feld nur eine Einheit stehen oder gehen darf. Das führt zu einem zum Teil recht merkwürdigen Bewegungsverhalten der Einheiten, siehe die ersten Teile von C&C.
Maa83 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 160

Win XP Pro
D6 Ent
BeitragVerfasst: Mo 12.01.04 09:28 
Ok vielen Dank erst mal
ich werd jetzt mal ein paar Sachen ausprobieren und falls ich weitere Fragen habe meld ich mich wieder :)
ShiKai
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 56



BeitragVerfasst: Mo 12.01.04 13:30 
Ben hat folgendes geschrieben:
Einspruch !
Es sollte auf jeden Fall für jedes Feld gespeichert werden welche Figuren sich dort befinden. Am besten sollte beides gemacht werden, in der Figur und im Feld.


hier muss ich einspruch erheben.
sauberer programmierstil ist es, wenn jede information in einem programm nur ein mal gespeichert wird, da u.a. vergessen werden kann, die daten überall zu aktualisieren

Ben hat folgendes geschrieben:
Einspruch !
1. Wenn du das Feld zeichnest müstest du sonst alle Figuren durchgehen um die zu finden die sichtbar sind, falls aber im Feld steht welche Figuren dort stehen fällt diese Suche Weg.

2. Kollision ! Du müßtest für jede Figur prüfen ob sie mit einer anderen kollidiert, das wäre vom Aufwand her ein klassischer n² Algorithmus. Wenn aber in den Feldern steht wer sich dort befindet dann müssen nur die umliegenden Felder getestet werden.
Das gleiche gilt auch für das Problem der Zielsuche und die KI.


damit hat er recht. und wenn du ganz "platzsparend" sein willst, kannst du ja gleich ein record definieren, wo mögliche figuren-positionen UND gegenstands-positionen drin gespeichert werden...
ich denke aber, dass das pathfinding damit nur unbemerklich "vereinfacht" wird...

Ben hat folgendes geschrieben:
Einspruch !
Achja, technisch läßt sich das ganz gut über Listen und Zeiger realisieren, dann braucht die Figur nur einmal als Variable existieren, kann aber mehrfach in verschiedenen Strukturen verlinkt sein.


ob das so ist, mag ich bezweifeln, da man dort das problem hat, dass man jedesmal das zielfeld aus der liste suchen muss und gucken muss, ob dort eine figur steht.


wfg,
ShiKai
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Mo 12.01.04 13:50 
ShiKai hat folgendes geschrieben:
Ben hat folgendes geschrieben:
Einspruch !
Es sollte auf jeden Fall für jedes Feld gespeichert werden welche Figuren sich dort befinden. Am besten sollte beides gemacht werden, in der Figur und im Feld.


hier muss ich einspruch erheben.
sauberer programmierstil ist es, wenn jede information in einem programm nur ein mal gespeichert wird, da u.a. vergessen werden kann, die daten überall zu aktualisieren

wfg,
ShiKai


Wo bitte ist dort eine information zweimal gespeichert? Gehen wir mal davon aus das wir OOP benutzen und somit unsere figuren objekte sind!:

Die figur muss ja ihre X,Y position kennen (denke da sind wir uns einig).
Das feld muss die figur kennen (da sind wir uns nicht einig), dafür ist auf dem feld ein pointer zu dem figur-objekt vorgesehen, der von der figur selbst aktualisert wird (dh. nicht, dass das feld der owner ist).

Nacht diesem modell kann man von beiden seiten addressieren, was zeit spart (da man nicht suchen muss) und zeit ist das höchste Gut in der spieleprogrammierung.

cu.

_________________
mfg.
mâximôv
ShiKai
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 56



BeitragVerfasst: Mo 12.01.04 14:38 
nach meinen verständnis meinter er, dass die position der figur in der figur gespeichert wird, und in dem feld (per pointer) gespeichert wird, welche figur dort ist, das ist unnötig, weil das feld nicht unbedingt wissen muss, wo sich die fugur befindet (es sein man will es sich einfach machen).
stattdessen kann man aber die position nur in die fur schreiben und das feld komplett leer lassen (vielleicht auf ein boolean-array reduzieren um platz zu sparen) und von den figuren her auslesen, wo sich was befindet...

man kann es aber auch andersrum machen, nur in dem array die position (als pointer) speichern und dafür nicht in der figur (beides ist möglich).


wfg,
ShiKai
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Mo 12.01.04 16:13 
ShiKai hat folgendes geschrieben:
nach meinen verständnis meinter er, dass die position der figur in der figur gespeichert wird,...


Normal! Die figur weiss ja wo sie steht.

Zitat:
... und in dem feld (per pointer) gespeichert wird, welche figur dort ist, das ist unnötig, weil das feld nicht unbedingt wissen muss, wo sich die fugur befindet (es sein man will es sich einfach machen).,...


Genau darum geht es ja. Der einfachste weg ist meist der beste und gerade dieser weg liefert die nötigen voraussetzung für optimierung, der performance und bewegungsverhalten durch A* pathfindig etc. :wink:

Zitat:
...
stattdessen kann man aber die position nur in die fur schreiben und das feld komplett leer lassen (vielleicht auf ein boolean-array reduzieren um platz zu sparen),...


Ich würd garcht mit mehreren arrays arbeiten. Ein array of record wäre da sehr viel praktischer. zB.:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
type
  TTile = record
    tileType:Cardinal;
    entityAnker:PEntity;
  end;

  TTileMap = array of array of TTile;



Zitat:
... und von den figuren her auslesen, wo sich was befindet...
,...


Herzlichen glückwunsch 8) Sagen du hast 200 entities auf der map und um festzustellen wer sich auf dem benachbarten tile befindet willst du diese immer alle abfragen? Dh. du musst X und Y position prüfen; damit wären wir schon 400 abfragen. Dann will dies jede einheit machen, dann haben will 200*400 abfragen = 80000 abfragen! etc.

Dann doch lieber 'ne map, die einen pointer zu viel hat :wink: Mit dem beispiel-typ von oben und einer 128x128er map sind das grad mal 128kb.

Zitat:
...

man kann es aber auch andersrum machen, nur in dem array die position (als pointer) speichern und dafür nicht in der figur (beides ist möglich).


wfg,
ShiKai


"Keep it simple" gilt beim spiele-programmieren mehr denn je.

cu.

_________________
mfg.
mâximôv