Sprites als Schauspieler


12

Ich habe keine Erfahrung mit Spielentwicklungsfragen, sondern als Programmierer. In der Sprache Scala können Sie skalierbares Multitasking mit Schauspielern haben, das, wie ich höre, sehr stabil ist. Sie können sogar Hunderttausende davon problemlos gleichzeitig ausführen.

Also dachte ich, vielleicht können Sie diese als Basisklasse für 2D-Sprites verwenden, um aus der Spielschleife auszubrechen, die es erfordert, alle Sprites zu durchlaufen und zu verschieben. Sie würden sich im Grunde genommen ereignisgesteuert bewegen.

Wäre das für ein Spiel sinnvoll? So ein Multitasking? Immerhin wird es auf der JVM laufen, obwohl das heutzutage kein großes Problem sein sollte.

BEARBEITEN:

Nach einer Weile bemerkte ich, dass diese Idee nur einen wirklichen Vorteil bietet: Multicore-Unterstützung. Eine einfache Spieleschleife läuft nur auf einem Kern und durchläuft alles nacheinander.

Da moderne Computer heutzutage sogar zu Hause über zwei oder mehr eingebaute Kerne verfügen, ist es meiner Meinung nach eine gute Idee, Spielprogrammierern die effiziente Nutzung der anderen Kerne zu ermöglichen. Schließlich denke ich, dass der Spieler normalerweise nur das Spiel auf seinem 8-Core-Rechner laufen lässt. Warum also nicht?

Der andere Vorteil, den ich sehe, ist der, den Sie in Scala haben können RemoteActors, der genauso behandelt werden kann, aber auf einem anderen Computer ausgeführt wird. Vielleicht kann dies auch das Spielen im Netzwerk vereinfachen.

Ich beabsichtige, das so schnell wie möglich in meine Scala 2D-Engine zu integrieren.


Es würde mich sehr interessieren, wie sich das entwickelt. Ich habe ein paar Mal auf Scala geschaut, bin aber noch nie darauf eingegangen.
Davy8

Viele würden argumentieren, dass Sie für explizite Multi-Core-Unterstützung eher mit Threads als mit Prozessen zurechtkommen (und mit Prozessen, die von Scala-Akteuren modelliert werden). Dies liegt daran, dass Sie den gemeinsamen Speicher in allen Threads nutzen können. Das ist natürlich in einer Weise fehleranfällig, wie es das Actor-Modell nicht ist.
Kylotan

Scala-Akteure werden über einen Thread-Pool gemultiplext, sodass sie leichter als Threads sein können. Dies bedeutet, dass sie den gemeinsam genutzten Speicher für die Kommunikation manipulieren können, sofern er ordnungsgemäß synchronisiert ist. Wenn Sie Remote-Akteure verwenden, befinden sich diese möglicherweise in unterschiedlichen Prozessen, und die einzige Möglichkeit zur Kommunikation besteht darin, Nachrichten zu senden.
Axel22

Antworten:


7

Ich habe es nicht versucht, aber ich bin ein Scala-Programmierer, und ich würde sagen, dass dies nicht der beste Ansatz ist. Sprites müssen synchron animiert werden. Schauspieler haben keine Garantie dafür, dass sie fair ausgeführt werden - einige Sprites sind möglicherweise schneller als andere, was Sie nicht wollen. Vielleicht möchten Sie eine Barriere verwenden, um sie zu synchronisieren, aber warum sollten Sie dann Schauspieler verwenden? Wenn Sie sich nur auf die Nachrichtenübermittlung verlassen, ist die Implementierung dieser Art der Synchronisierung (Implementierung einer Barriere für mehr als 1000 Akteure) ein Overkill.

Ein weiteres Problem ist - wofür würden Sie die Nachrichtenübermittlung verwenden? Benötigst du deine Sprites, um zu kommunizieren? Sie könnten vom Hauptdarsteller eine Nachricht senden, in der Sie jedem Sprite mitteilen, dass er zum nächsten Frame wechseln soll. In Bezug auf die Leistung sind dies jedoch mehr als das direkte Aufrufen von Methoden und das Durchlaufen einer Reihe von Sprites.

Mir scheint, dass Sie hier eine Art sehr leichtes Multitasking benötigen und überhaupt keine Nachricht weitergeben. Wenn Sie dies sicherstellen möchten, ist es wahrscheinlich der beste Weg, eine eigene schauspielerähnliche Implementierung zu implementieren, die Fairness gewährleistet, aber das ist zu viel Arbeit für zu wenig Gewinn. Eine andere Sache, die man sich ansehen sollte, ist die funktionale reaktive Programmierung, und scala.reactich glaube, das passt besser zu diesem Anwendungsfall.

Ich habe in Scala eine isometrische 2D-Spiel-Engine implementiert. Ich habe nur 1 globalen Schauspieler verwendet, um sichtbare Sprites zu aktualisieren, die animiert wurden.

Möglicherweise möchten Sie Ihre Spielelogik mithilfe von Akteuren implementieren - zum Beispiel, um Berechnungen auf verschiedenen Teilen Ihrer Spielekarte an verschiedene Akteure zu verteilen, damit diese den Spielstatus parallel aktualisieren - und einen Leistungsgewinn erzielen. Ich würde nicht einen einzelnen Schauspieler pro Spielobjekt verwenden, sondern einen Schauspieler pro Region. Wenn Sie zu feinkörnig arbeiten, leidet die Leistung.

Wenn ich Sie wäre, würde ich es trotzdem versuchen, nur um zu sehen, was passiert.


1

Also dachte ich, vielleicht können Sie diese als Basisklasse für 2D-Sprites verwenden, um aus der Spielschleife auszubrechen, die es erfordert, alle Sprites zu durchlaufen und zu verschieben. Sie würden sich im Grunde genommen ereignisgesteuert bewegen.

Was würde das Ereignis sein, das sie bewegt?

Wäre es ein Event, das Sie einmal pro Frame ausstrahlen?

Und wenn ja, wie hat dies das System in praktischer Hinsicht verändert?

Als ich ursprünglich die Objektorientierung im Kontext von C ++ studierte, stellte ich fest, dass einige Leute gerne an eine Aussage denken xyz.doThis(x), die beispielsweise "Sende die doThis-Nachricht an xyz (mit der Nutzlast x) und warte auf eine sofortige Antwort" bedeutet. Auf dieser Ebene gibt es keinen wesentlichen Unterschied zwischen einem ereignis- oder nachrichtenbasierten System und einem normalen prozeduralen System.


Schauspieler sind eine Multithread-Lösung. Die Kommunikation ist nicht synchron. Scala-Schauspieler (Konzept von Erlang) ermöglichen eine einfache Multi-Core-Programmierung.
Ellis

Sie haben einen Punkt dort, aber der Unterschied hier wäre, dass das Actor-basierte Sprite die Spielschleife nicht blockiert, während die Aktion ausgeführt wird, während der methodische Ansatz wartet, bis xyz.doThis(x)dies abgeschlossen ist. Ich denke, dies könnte sogar dazu beitragen, die Spielelogik zu beschleunigen, insbesondere auf Mehrkernsystemen.
Lanbo

Dies erleichtert die Verteilung des Entity-Handlings auf mehrere Kerne. Die Kosten dafür sind jedoch, dass Sie ohne zusätzliche Nachrichten oder zusätzliche Daten, die in den Nachrichten gesendet werden, nicht einfach von einem Akteur auf einen anderen verweisen können. Sie stellen also schnell fest, dass Ihnen der naive Ansatz hier nicht hilft - können Sie eine akteursbasierte Methode für die Durchführung der Updates formulieren?
Kylotan

Derzeit experimentiere ich mit einer Art verteilter Aktualisierung: Meine Akteure sind wie Knoten in einer Baumstruktur, und die Aktualisierung des Stamms aktualisiert die untergeordneten Elemente durch Nachrichtenverteilung. Der wahre Vorteil wird auch in der Vernetzung liegen: In Scala können ein Akteur und ein RemoteActor (Akteur auf einem anderen System) auf dieselbe Weise über dieselben Nachrichten angesprochen werden.
Lanbo

Ja, aber das Problem ist nicht das Auslösen des Updates als solches, es stellt sicher, dass der Empfänger der Nachricht über alle Informationen verfügt, die er benötigt, um darauf zu reagieren.
Kylotan

0

Das ist ein cooler Ansatz, um über die Aktualisierung Ihrer Spielobjekte nachzudenken. Ich kenne Scala nicht, aber ich sage, probieren Sie es aus und sehen Sie, wie es ausgeht, und veröffentlichen Sie noch besser Ihre Ergebnisse!

Die wichtigsten Fragen, die mir in den Sinn kommen, sind: Wie können Sie steuern, wie oft einige Spielobjekte im Vergleich zu anderen aktualisiert werden? Müssen Sie sich Sorgen machen, dass die Sprite-Darsteller zu viele Zyklen in Anspruch nehmen, sodass das Rendering-System nicht alle 1/60 | 30 | 24 Sekunden Zeit hat, einen Frame zu zeichnen?

Eine andere zu berücksichtigende Sache ist, wie sich dies auf die Auflösung von Spieler- gegen KI-Interaktionen auswirkt, die von der Reihenfolge einer Abfolge sehr schneller Ereignisse abhängen. Je nach Art des Spiels, das nicht kann wahrscheinlich nicht viel Materie.


Das Tolle an Scala Actors ist, dass sie auf Nachrichten basieren. Jeder von ihnen hat eine eigene Nachrichten- / Ereigniswarteschlange. Ich bin nicht sicher, ob "Zeichnen" eine Nachricht oder eine Methode zum Aufrufen sein soll. Ich denke, es wird das letztere sein, so dass ein Sprite jederzeit gezeichnet werden kann, unabhängig vom Status seiner Ereigniswarteschlange. Und sie können sich gegenseitig Nachrichten senden, um sicherzustellen, dass die Dinge in einer bestimmten Reihenfolge erledigt werden.
Lanbo

Seien Sie vorsichtig, ich denke nicht, dass es nützlich wäre, jedes Sprite mit einer Draw-Methode oder einem Draw-Ereignis auszustatten, außer vielleicht als Flag, um die Sichtbarkeit umzuschalten. In der Renderphase einer Spieleschleife hat die Reihenfolge, in der Sprites auf dem Bildschirm gerendert werden, einen großen Einfluss auf das Ergebnis. Wenn Sie ein Sprite haben, das sich vor dem anderen befindet (die Abmessung befindet sich in Richtung des Monitors), möchten Sie, dass dieses Sprite als zweites gezeichnet wird. Ich sehe Scalas Schauspieler als nützlich für den Update- / Logikteil der Spieleschleife.
michael.bartnett

Normalerweise gibt es dort nur eine Zeichenmethode. Wenn Sie sie also so implementieren, sollte es keinen großen Unterschied zur normalen Art des Umgangs mit Sprites geben.
Lanbo

Ah okay, ich habe falsch verstanden, was Sie beschrieben haben. Irgendwie stellte ich mir Sprites vor, die sich selbst rendern, wann und wie es ihnen gefällt. Lassen Sie uns wissen, wie es ausgeht!
michael.bartnett

0

Nun, ich bin auch kein großer Programmierer, aber ich sehe kein Problem in Ihrem Vorschlag. Ich dachte nicht einmal an eine solche Art, Schauspieler zu entwickeln.

Es mag eine ziemliche Herausforderung sein, da die Folgenabschätzung sehr genau sein muss, um nicht beachtetes Verhalten zu vermeiden, aber im Übrigen halte ich es für einen guten Vorschlag


0

Wenn mit Sprite Spieleinheit gemeint ist , dann sicher.

Spieleinheiten sollten sich niemals selbst zeichnen. Sie sollten ein Grafikhandle aktualisieren, das beschreibt, wo und wie sie gezeichnet werden müssen. Das Rendersystem oder das Szenendiagramm oder was auch immer für die eigentliche Zeichnung verwendet wird. Es gibt eine Grafikkarte, die alle 16ms synchronisiert werden muss. Ein solches Setup funktioniert einfach nicht gut für die verteilte asynchrone Verarbeitung.

Das Rendersystem sollte ein Schauspieler sein (oder möglicherweise ein Paar, wenn Sie schwierig sind). Wenn Spieleinheiten das Grafikhandle aktualisieren, werden Nachrichten an das Rendersystem gesendet. Mit dem Rendering-System können sie alle möglichen Entscheidungen und / oder Optimierungen treffen, z. B. Batch-Rendering, Okklusion, Physik-Jitter-Glättung usw.

Ich bin kein Scala-Entwickler, aber ich habe ziemlich viel mit Erlang gemacht. Also, wenn einige meiner Scala-Begriffe falsch sind, bitte vergib mir.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.