| Autor |
Beitrag |
Maa83
      
Beiträge: 160
Win XP Pro
D6 Ent
|
Verfasst: 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
      
Beiträge: 526
WinXP Home & Professional
C, C++, Delphi
|
Verfasst: 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
      
Beiträge: 260
|
Verfasst: 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:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| TCreature = class X, Y : Integer; ImageIndex : Integer;
end;
Creatures : array of TCreature;
for i:= 0 to high(Creatures) do begin drawImage(ImageIndex, Creatures[i].X, Creatures[i].Y); end; |
|
|
Maa83 
      
Beiträge: 160
Win XP Pro
D6 Ent
|
Verfasst: 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
      
Beiträge: 389
|
Verfasst: 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
      
Beiträge: 31
|
Verfasst: 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
      
Beiträge: 178
|
Verfasst: 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
      
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: 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....
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
      
Beiträge: 260
|
Verfasst: 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
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: 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
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
      
Beiträge: 129
|
Verfasst: 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
      
Beiträge: 31
|
Verfasst: 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 
      
Beiträge: 160
Win XP Pro
D6 Ent
|
Verfasst: 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
      
Beiträge: 56
|
Verfasst: 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
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: 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
      
Beiträge: 56
|
Verfasst: 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
      
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: 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.
| 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.:
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  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  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
|
|
|