Hallo,
ich versuche gerade sehr detaillierte dreidimensionale Wände für einen Shooter zu programmieren. Ich möchte simulieren, dass wenn die Wand beschossen wird, Löcher von der korrekten Tiefe und im korrekten Winkel entstehen. Die Wand soll sich außerdem statisch korrekt verhalten, das heißt ein Teil soll herausfallen, sobald er nicht mehr ausreichend gestützt wird.
Das Ganze soll von der Laufzeit her möglichst konstant bleiben, deshalb kann ich nicht die Anzahl der Löcher mit ihren jeweiligen Winkeln und Tiefen abspeichern, sonst wird das irgendwann ab zigtausend Löchern hakig...
Deshalb hab ich mich jetzt erstmal dafür entschieden, die Wand in 2x2x2cm-Würfel einzuteilen, die entweder intakt oder kaputt sein können. Dann kann ich die Löcher noch halbwegs akkurat (halt auf 2 cm genau) darstellen. 1x1x1cm-Würfel würden mir natürlich besser gefallen, aber ich glaube, da gehen mir RAM und Prozessor zur Laufzeit in Flammen auf...
Die Generierung der Wand sieht jetzt folgendermaßen aus:
(1) Es wird ein 3D-Byte-Array erstellt. Dabei geben die Zahlen die "Integrität" an. Alles über 0 ist "intakt", alles darunter "kaputt".
(2) Dann bekommt die unterste Schicht der Wand (z0-Ebene) den maximalen "Integritätswert", z.Bsp. 200.
(3) Nun werden iterativ für jeden Block der Ebene, beginnend vorne links, Reihe für Reihe bis hinten rechts gehend, folgende Schritte durchgeführt:
(3.1) Der Block über dem aktuellen Block bekommt (Integrität des aktuellen Blocks - 5) zugeteilt, falls sein aktueller Wert höher als 0 und niedriger als der Wert, den er bekommen würde ist.
(3.2) Jeder horizontale Nachbar bekommt (Integrität des aktuellen Blocks - 20) zugeteilt, falls sein aktueller Wert höher als 0 und niedriger als der Wert, den er bekommen würde ist.
(4) Schritt (3.2) Wird für die Ebene wiederholt, diesmal jedoch beginnend hinten rechts, Reihe für Reihe bis vorne links gehend.
(5) Schritte (3) und (4) werden für jede Ebene von unten bis oben wiederholt.
Dies sollte eine ausreichend akkurate Statiksimulation für meine Zwecke abgeben.
Nun kommen wir zum eigentlichen Problem:
Wenn ein Block direkt getroffen (und damit zerstört wird), würde ich am Liebsten seinen Wert einfach auf 0 setzen, und die obengenannten Schritte ab der betroffenen Ebene erneut ausführen. Dabei ergeben sich 2 Probleme:
(1) Die Ebenen sind sehr groß. Die komplette Ebenen + alle darüberliegenden neu zu berechnen, frittiert den Prozessor, das Ganze sollte möglichst in <100ms durchlaufen.
(2) Man überlege folgendes Szenario: Ein Block wird von unten gestützt und hat 20 HP. Sein horizontaler Nachbar wird nur von ihm gestützt und hat demzufolge 15 HP. Dessen Nachbar wird wieder nur vom ersten Nachbar gestützt und hat 10 HP. Nun wird der erste Block zerstört. Für den zweiten Block wird jetzt neu berechnet und da sein Nachbar ja 10 HP hat, wird er von diesem gestützt und hat noch 5 HP. Also habe ich je nach Implementierung die Wahl, eine Endlosrekursion zu machen oder am Ende zwei Blöcke zu haben, die in der Luft schweben...
Entschuldigung, dass meine Fragen immer zu solchen Romanen ausarten, ich fürchte, ich denke einfach viel zu kompliziert...Falls jemandem ein einfacherer Algorithmus oder eine andere Lösung einfällt, bin ich ganz offen, ich zermartere mir hier seit Tagen das Hirn :O
LG Max
ich versuche gerade sehr detaillierte dreidimensionale Wände für einen Shooter zu programmieren. Ich möchte simulieren, dass wenn die Wand beschossen wird, Löcher von der korrekten Tiefe und im korrekten Winkel entstehen. Die Wand soll sich außerdem statisch korrekt verhalten, das heißt ein Teil soll herausfallen, sobald er nicht mehr ausreichend gestützt wird.
Das Ganze soll von der Laufzeit her möglichst konstant bleiben, deshalb kann ich nicht die Anzahl der Löcher mit ihren jeweiligen Winkeln und Tiefen abspeichern, sonst wird das irgendwann ab zigtausend Löchern hakig...
Deshalb hab ich mich jetzt erstmal dafür entschieden, die Wand in 2x2x2cm-Würfel einzuteilen, die entweder intakt oder kaputt sein können. Dann kann ich die Löcher noch halbwegs akkurat (halt auf 2 cm genau) darstellen. 1x1x1cm-Würfel würden mir natürlich besser gefallen, aber ich glaube, da gehen mir RAM und Prozessor zur Laufzeit in Flammen auf...
Die Generierung der Wand sieht jetzt folgendermaßen aus:
(1) Es wird ein 3D-Byte-Array erstellt. Dabei geben die Zahlen die "Integrität" an. Alles über 0 ist "intakt", alles darunter "kaputt".
(2) Dann bekommt die unterste Schicht der Wand (z0-Ebene) den maximalen "Integritätswert", z.Bsp. 200.
(3) Nun werden iterativ für jeden Block der Ebene, beginnend vorne links, Reihe für Reihe bis hinten rechts gehend, folgende Schritte durchgeführt:
(3.1) Der Block über dem aktuellen Block bekommt (Integrität des aktuellen Blocks - 5) zugeteilt, falls sein aktueller Wert höher als 0 und niedriger als der Wert, den er bekommen würde ist.
(3.2) Jeder horizontale Nachbar bekommt (Integrität des aktuellen Blocks - 20) zugeteilt, falls sein aktueller Wert höher als 0 und niedriger als der Wert, den er bekommen würde ist.
(4) Schritt (3.2) Wird für die Ebene wiederholt, diesmal jedoch beginnend hinten rechts, Reihe für Reihe bis vorne links gehend.
(5) Schritte (3) und (4) werden für jede Ebene von unten bis oben wiederholt.
Dies sollte eine ausreichend akkurate Statiksimulation für meine Zwecke abgeben.
Nun kommen wir zum eigentlichen Problem:
Wenn ein Block direkt getroffen (und damit zerstört wird), würde ich am Liebsten seinen Wert einfach auf 0 setzen, und die obengenannten Schritte ab der betroffenen Ebene erneut ausführen. Dabei ergeben sich 2 Probleme:
(1) Die Ebenen sind sehr groß. Die komplette Ebenen + alle darüberliegenden neu zu berechnen, frittiert den Prozessor, das Ganze sollte möglichst in <100ms durchlaufen.
(2) Man überlege folgendes Szenario: Ein Block wird von unten gestützt und hat 20 HP. Sein horizontaler Nachbar wird nur von ihm gestützt und hat demzufolge 15 HP. Dessen Nachbar wird wieder nur vom ersten Nachbar gestützt und hat 10 HP. Nun wird der erste Block zerstört. Für den zweiten Block wird jetzt neu berechnet und da sein Nachbar ja 10 HP hat, wird er von diesem gestützt und hat noch 5 HP. Also habe ich je nach Implementierung die Wahl, eine Endlosrekursion zu machen oder am Ende zwei Blöcke zu haben, die in der Luft schweben...
Entschuldigung, dass meine Fragen immer zu solchen Romanen ausarten, ich fürchte, ich denke einfach viel zu kompliziert...Falls jemandem ein einfacherer Algorithmus oder eine andere Lösung einfällt, bin ich ganz offen, ich zermartere mir hier seit Tagen das Hirn :O
LG Max