Ok, also habe ich eine große Liste aller meiner Entitäten, die ich durchschleife und aktualisiere. In AS3 kann ich dies als Array (dynamische Länge, untypisiert), als Vektor (typisiert) oder als verknüpfte Liste (nicht nativ) speichern. Im Moment verwende ich Array, aber ich plane, zu Vector oder Linked List zu wechseln, wenn es schneller ist.
Wie soll ich meine Frage, wenn eine Entität zerstört wird, von der Liste entfernen? Ich könnte seine Position aufheben, es herausspleißen oder einfach eine Flagge darauf setzen, um zu sagen: "Überspringe mich, ich bin tot." Ich fasse meine Entitäten zusammen, sodass eine Entität, die tot ist, wahrscheinlich irgendwann wieder am Leben ist. Was ist meine beste Strategie für jede Art von Sammlung und welche Kombination aus Sammlungstyp und Entfernungsmethode funktioniert am besten?
Antworten:
Ich würde alle hinzugefügten / entfernten Elemente in separaten Listen speichern und diese Operationen ausführen, nachdem ich die Update-Schleife durchlaufen habe.
quelle
Das Flixel-Framework verwendet das Dead-Flag (tatsächlich mehrere Flags, die festlegen, ob es gezeichnet, aktualisiert usw. werden soll). Ich würde sagen, wenn Sie Entitäten wiederbeleben wollen und Leistung ein Problem darstellt, verwenden Sie die Dead-Flagge. Nach meiner Erfahrung ist das Instanziieren neuer Entitäten in dem von Ihnen beschriebenen Anwendungsfall die teuerste Operation, und das Herausspleißen oder Aufheben der Werte von Elementen kann bei Flashs mitunter sehr unruhiger Speicherbereinigung zu einer Aufblähung des Speichers führen.
quelle
dead
hilft wirklich bei der Leistung.Während einige Techniken von Natur aus effizienter sind als andere, spielt es nur eine Rolle, wenn Ihnen auf Ihrer Zielplattform die Zyklen ausgehen. Verwenden Sie die Technik, mit der Sie Ihr Spiel schneller erledigen können. Versuchen Sie, sich in der Zwischenzeit nicht auf die spezifische Implementierung Ihrer Container-Datenstrukturen zu verlassen, und optimieren Sie diese anschließend, wenn Sie sie benötigen.
Nur um einige der Techniken anzusprechen, die bereits von anderen hier besprochen wurden. Wenn die Reihenfolge der Entitäten wichtig ist, können Sie mit einem Dead-Flag während der Aktualisierungsschleife den nächsten Frame verbinden. z.B. sehr einfacher Pseudocode:
Dies sind die Merkmale dieses Schemas:
quelle
In Bezug auf meine allgemeine Programmiererfahrung ist das Spleißen normalerweise ein langsamer Vorgang, bei dem alle vorhandenen Elemente um eins nach oben verschoben werden. Ich würde denken , es auf null zu setzen, wäre die beste Lösung hier ; Eine tote Flagge würde funktionieren, aber Sie müssten darauf achten, dass Ihr Code nicht durcheinander kommt.
Wir sprachen eigentlich nur über das Zusammenlegen von Ressourcen im Chatroom. Es ist eine sehr gute Übung, und es ist gut zu hören, dass Sie das tun. :)
quelle
Persönlich würde ich eine verknüpfte Liste verwenden. Das Durchlaufen einer Favoritenliste ist schnell und das Hinzufügen und Entfernen von Elementen ist möglich. Die Verwendung eines Arrays oder Vektors ist eine gute Wahl, wenn Sie direkten Zugriff auf Elemente in der Struktur benötigen (z. B. Zugriff auf einen Index), dies hört sich jedoch nicht so an.
Wann immer Sie ein Element aus der verknüpften Liste entfernen, können Sie es einem Pool von Objekten hinzufügen, die dann wiederverwendet werden können, um Speicherzuweisung zu sparen.
Ich habe die polygonalen Datenstrukturen in mehreren Projekten verwendet und war sehr zufrieden mit ihnen.
Bearbeiten: Tut mir leid, ich denke die Antwort war in Bezug auf die Entfernungsstrategie nicht sehr klar: Ich würde vorschlagen, das Element aus der Liste zu entfernen, sobald es tot ist und es direkt zur Poolstruktur hinzuzufügen (recyceln). Da das Entfernen eines Elements aus einer verknüpften Liste sehr leistungsfähig ist, sehe ich darin kein Problem.
quelle
next
Zeiger nach einem gelöschten Knoten mit dem Knoten verknüpfen . Wenn Sie dies nicht mühsam selbst erledigen möchten, ist eine doppelt verknüpfte Liste die DataStructure Ihrer Wahl."Setzen Sie einfach eine Flagge darauf und sagen Sie:" Überspringen Sie mich, ich bin tot. "Ich fasse meine Entitäten zusammen, so dass eine Entität, die tot ist, sehr wahrscheinlich irgendwann wieder am Leben ist."
Ich denke, Sie haben Ihre eigene Frage zu dieser speziellen Anwendung beantwortet. Ich würde Arrays meiden, wenn Sie jemals vorhaben, andere Arbeiten als Push-and-Pop auszuführen. Verknüpfte Listen sind eine intelligentere Methode, wenn Sie umfangreiche Operationen durchführen möchten. Wenn Sie jedoch vorhaben, dieselbe Entität wieder in das Spiel zu integrieren, ist es sinnvoll, nur eine boolesche Variable festzulegen und diese während der Spieloperationsschleifen zu überprüfen.
quelle
Eine saubere und allgemeine Lösung, die ich in einer von mir verwendeten Bibliothek gefunden habe, war die Verwendung einer abschließbaren Karte.
Sie haben zwei Operationen
lock()
undunlock()
, während Sie Iterierte über die Karte , werden Sielock()
nun von diesem Punkt jede Operation , die die Karte ändert nicht wirksam werden, wird es nur in eine geschoben ,CommandQueue
die ausgeführt wird , wenn Sie anrufenunlock()
.Das Entfernen einer Entität hätte also den folgenden Pseudocode:
und wenn du
unlock()
Sie müssen nur berücksichtigen, dass Sie die Entität erst nach der Schleife entfernen.
EDIT: Dies ist die von Simon vorgeschlagene Lösung.
quelle
Hier ist eine Antwort von Liosan :
/gamedev//a/46765/24633
quelle
Ich habe zwei Methoden.
Wenn Sie ein zu löschendes Objekt aufrufen, setzt es tatsächlich zwei Flags:
1. Sie müssen dem Container mitteilen, dass ein Objekt gelöscht wurde
2. Sie müssen dem Container mitteilen, welche Objekte gelöscht werden sollen
Eins Verwenden eines Objektvektors
Überprüfen Sie dann in der Aktualisierungsfunktion, ob ein Objekt gelöscht wurde, und durchlaufen Sie in diesem Fall alle Objekte und entfernen Sie die Objekte, die ein Löschkennzeichen aufweisen
Zwei Verwenden eines (Zeigers auf einen) Vektor von Objekten.
Wenn in der Aktualisierungsfunktion ein Objekt gelöscht werden soll, iterieren Sie durch die Objekte und fügen Sie diejenigen, die nicht gelöscht werden sollen, zu einem neuen Vektor hinzu. Löschen Sie den Objektvektor und setzen Sie den Zeiger auf den neuen Vektor
quelle