Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

06.08.2017, 17:14

Grid-Based Simulation

Ich habe folgendes Problem. Auf einem Grid will ich eine Simulation von Tiles machen. Alle Tile Positionen sind diskret. Sprich ein diskrete Position wird in eine neue diskrete Position überführt.

Je step versuche ich die Simulation fortschreiten zu lassen. Entsprechend der Regeln des jeweiligen Tiles. Ein Tile kann aber in einem Simulationsstep nur ein Tile sich weiterbewegen (das betrift alle Tiles).

Ich könnte nur das In-Place machen und mit Locks der jeweiligen Zellen des Grids arbeiten. Oder In-Place mit verzögertem hinzufügen und die Bewegungen aller Tiles erst zwischenspeichern und dann am Ende ausführen lassen. Oder man macht es Non-In-Place über ein zweites Grid und swapped dann.

Aber das löst nicht das Problem was ich habe. Wenn ein Tile bei seiner Bewegung einen Freiraum für ein andere Tile schaft, und die richtige Reihenfolge der Updates nicht gegeben ist, dass das andere Tile hier in dem momentan simulationsstchritt nicht entsprechend verhält und diesen Freiraum füllt. Also ist die Simulation ja abhängig von der jeweiligen Update-Order der Tiles.

Ich müsste doch im Grunde bei den veränderten Zellen dann jeweils die Nachbar-Tiles benachrichtigen und ihnen mitteilen dass eine Änderung statt fand und diese Tiles müssten dann erst ihre Updates ausführen. Diese müssten dann wieder, wenn diese sie selbst den Zustand des Grids verändern, deren Nachbarn wieder bescheid sagen, und so weiter. Sprich rekursiv, bis alle Tiles die betroffen sind ihre Bewegnung ausgeführt haben. Die Abbruchbedingung wäre dann wenn alle Teile die betroffen sind keine Zustandsänderung mehr am Grid ausüben. Hier würde ich mit einer CloseList und OpenList arbeiten vielleicht sogar.


Die Frage wäre im Grunde, wie ist die Reihenfolge der Ausführung der Updates der Tiles auf dem Grid?
Es ist ja nicht einfach Non-In-Place gehen und bei alle Tiles einmal die Update-Methode aufrufen...

Ich hoffe ich habe mich klar ausgedrückt und man versteht mein Anliegen. Danke.

Dieser Beitrag wurde bereits 11 mal editiert, zuletzt von »TypeOverride« (06.08.2017, 17:36)


Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

06.08.2017, 18:10

Ich hoffe ich habe mich klar ausgedrückt und man versteht mein Anliegen. Danke.

Nicht so richtig :D Wenn ich dich richtig verstehe ist deine Simulation von der Reihenfolge der einzelnen Aufrufe abhängig. Was wäre wenn du die Objekte welche ihr Update noch nicht ausführen können auf eine extra Liste packst? Oder das Update für die Zellen ausführst welche das Update der aktuellen Zelle behindern. Dazu kannst du ja zusätzlich mit einer Closedlist arbeiten. Ansonsten lieferst du ja selbst eine Lösung mit. Was spricht dagegen?
Deine eigentliche Frage kann ich dir nicht beantworten. Wie die Reihenfolge ist, bzw vermutlich eher wie sie sein sollte weiß ich nicht. Das müsstest du ja selbst wissen da du weißt was deine Simulation tun soll und wie sie sich richtig verhält.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

3

06.08.2017, 19:04

Ich hoffe ich habe mich klar ausgedrückt und man versteht mein Anliegen. Danke.

Nicht so richtig :D Wenn ich dich richtig verstehe ist deine Simulation von der Reihenfolge der einzelnen Aufrufe abhängig. Was wäre wenn du die Objekte welche ihr Update noch nicht ausführen können auf eine extra Liste packst? Oder das Update für die Zellen ausführst welche das Update der aktuellen Zelle behindern. Dazu kannst du ja zusätzlich mit einer Closedlist arbeiten. Ansonsten lieferst du ja selbst eine Lösung mit. Was spricht dagegen?
Deine eigentliche Frage kann ich dir nicht beantworten. Wie die Reihenfolge ist, bzw vermutlich eher wie sie sein sollte weiß ich nicht. Das müsstest du ja selbst wissen da du weißt was deine Simulation tun soll und wie sie sich richtig verhält.


Die Tiles (Particle nenn ich sie auch) sollen sich ähnlich wie so ein BoulderDash verhalten. Aber es gibt einige Fallen hier. Und BoulderDash müsste die Update-Schritte strikt trennen. Also erst das fallen der Boulder (beginnend alle updaten von links unten vom Grid). Dann erst die Boulders updaten die nach rechts abdriften. Dann kommen die Gegner Tiles. Und etc.

Aber ich will dass ich jegliches Verhalten simulieren kann. Nicht nur die paar vordefinierten.

Bei BoulderDash bekommen die Boulders ja ein Attribut "isFalling", so muss man ja gucken ob der darunter auch fällt (das ist dann nicht mehr so relevant mit der Tiefensuche wenn sie wieso nur nach unten fallen können - dann fängt man unten links auf dem grid an zu updaten). Der obere darf sich nicht dann nach Rechts bewegen anhand der Logic des Tiles, sondern mitfallen natürlich. Das funktioniert ja nur wenn die Reichenfolge richtig ist. Und wenn die Regeln nicht so einfach sind, wie zum Beispiel, dass die Gravity bei einigen Tiles sie nach oben bewegt, anstatt nach unten, so kann man die updates ja nicht mehr von unten links am grid anfangen lassen.

Im Grunde könnte man auch die updatephasen (mehrere pässe) vielleich machen (also erstmal gucken ob alle Tiles fallen können und sie fallen lassen, und dann erst deren anderen Verhalten ausführen im zweiten Pass). Dann priorisiert man schon dass Gravity vorrang hat. Aber im Grunde drehe ich mich im Kreis und die Reihenfolge ist wichtig. Um eine Tiefensuche komme ich ja garnicht herum oder?

Ich müsste erstmal gucken ob der Tile in der sich das andere Tile bewegt sich mit in die selbe Richtung bewegt oder schon im Stillstand ist (eine Hindernis erreicht hat und daher als Bewegungslos gilt (isFalling = false - oder eher isMoving = false)). Aber auch hier müsste ich eine Tiefensuche machen. Im Grunde komme ich doch garnicht um eine Tiefensuche herum oder? Damit ich bei den enden Anfange zu updaten. Vielleicht in der Richtung in der die Tiles sich bewegen. Daher brauche ich ein Attribut (Vector2 movedir]) die die Richtung des Falls beschreiben, pro updateschritt. Und dieses Attribute lenkt dann die Tiefensuche.

Gibt es irgendwelche Links wo man sowas nachlesen kann wie man das macht. Sonst muss ich eine eigene Lösung anstreben obwohl es vielleicht sogar schon bewehrte und nicht so rechenintesive Lösungen gibt. Im Grunde muss ich eine Tiefensuche machen ständig. Das kostet Leistung.

Ich glaube ich denke zu kompliziert hier. Boulder Dash ist hingegen kein wirkliches gutes Beispiel glaube ich. Hier wird denke ich auch ein State gemacht, wo "isFalling" relevant ist. Aber meine Tiles sollen jegliches Verhalten annehmen können und auch die Richtung der Gravity kann sich unterscheiden pro Tile. Können also auch nach oben sich bewegen.

Meine Simulaton hat eher Attribute wie "Gravity (Schwerkraft)" und "Density (Dichte)".

Dieser Beitrag wurde bereits 15 mal editiert, zuletzt von »TypeOverride« (06.08.2017, 19:30)


4

06.08.2017, 20:57

Im Grunde müsste ich eigentlich einen "Solver" basteln, wenn ich das richtig sehe.

5

07.08.2017, 16:05

So sieht das nun aus (falls es einen interessiert):


Renegade

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

6

08.08.2017, 09:52

Hallo TypeOverride,
wenn ich dein Problem richtig verstehe, suchst du das Pattern Double Buffer. Der Abschnitt Artificial unintelligence beschreibt die Anwendung des Patterns anhand einer Serie von Akteuren die mit einander interagieren, aber für den Benutzer simultan erscheinen.
Liebe Grüße,
René

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Renegade« (08.08.2017, 10:46)


Werbeanzeige