Dies ist eine Folgefrage zu dieser anderen .
Ich würde gerne wissen, ob es ein gemeinsames / typisches / bestes Muster gibt, um meine Darstellung der Welt (derzeit 160 km x 160 km) so zu skalieren , dass sie in den Zeichenbereich (derzeit 800 x 600 Pixel) passt .
Ich kann mir mindestens vier verschiedene Ansätze vorstellen:
Naiv (so wie ich es bisher gemacht habe). Ich habe eine globale Funktion implementiert sc(vector)
, die einfach eine verkleinerte Kopie des übergebenen Vektors zurückgibt. Dies funktioniert natürlich, verpflichtet mich jedoch, Code wie folgt zu schreiben:
drawCircle(sc(radius), sc(position))
Verpackungsfunktionen . Ich könnte mehrere Funktionen definieren, von denen jede die ursprüngliche Middleware umschließt. Zum Beispiel könnte ich definieren, myDrawCircle
dass zuerst die Argumente skaliert werden, die skaliert werden müssen, und dann drawCircle
mit letzterem aufgerufen werden . Dies würde meinen Code vielleicht lesbarer und leichter zu pflegen machen, aber ich sollte viele Wrapping-Funktionen schreiben, die albern klingen.
Funktionsdekorateur . Ich könnte einfach die vorhandenen Middleware-Funktionen dekorieren und eine automatische Skalierung für alle Parameter bereitstellen, die eine Instanziierung der Klasse darstellen Vector3D
. Das Problem ist jedoch, dass diese Funktionen auch mit denselben Parametern funktionieren list
oder Vector2D
auch, und der Dekorateur hätte keine Möglichkeit, dies zu wissen Welche Listen müssen skaliert werden (z. B. der Radius) und welche nicht (die RGB-Werte).
Oberflächeninitialisierung . Bei der Definition der Oberfläche, auf die ich zeichnen werde, könnte ich den Skalierungsfaktor definieren (so dass ich dann Meter und nicht Pixel als Parameter verwenden würde). Dies würde für mich transparent funktionieren und wäre meine bevorzugte Lösung, aber natürlich sollte es in der Middleware implementiert werden, daher ist es keine echte Option.
... jedenfalls: Da dies ein sehr häufiges Problem ist, frage ich mich, ob es ein etabliertes Muster gibt, das dieses Problem, das ich nicht gefunden habe, elegant löst.
PS: Für dieses Projekt verwende ich Python (mit Pygame ), aber - obwohl eine Python / Pygame-spezifische Antwort sehr geschätzt wird, interessiert mich eher die allgemeine / allgemeine Beschreibung des Musters als dessen konkrete Implementierung.
Vielen Dank im Voraus für Ihre Zeit und Ihr Fachwissen.
quelle
Normalerweise versuchen Benutzer nicht, eine Laufzeitskalierung in 2D-Spielen durchzuführen. Ich stimme nicht zu, dass es ein häufiges Problem ist. Wenn Benutzer eine Minikarte oder eine andere feste Neuskalierung wünschen, werden häufig neue Grafiken für diesen Zweck erstellt. Es ist selten, dass Sie eine einzelne Routine benötigen, um in einem 2D-Spiel mit 2 verschiedenen Zoomstufen zu arbeiten.
Wenn Sie eine 3D-API verwenden, können Sie diese Funktionalität kostenlos nutzen - ändern Sie einfach die Kamera- / Ansichtsfenster-Parameter.
PyGame ist eine sehr alte API und leider nur für 2D geeignet. Selbst wenn Sie geeignete Skalierungssysteme für die verschiedenen Zoomstufen ausarbeiten könnten, ist die Leistung nicht gut genug und das Erscheinungsbild ist wahrscheinlich inakzeptabel schlecht.
Ich würde empfehlen, dass Sie, wenn Sie viel vergrößern und verkleinern möchten, so schnell wie möglich auf eine moderne 3D-API umsteigen. Ich würde Pyglet empfehlen, aber es gibt wahrscheinlich auch andere.
quelle
pyglets
in der Vergangenheit für eine 3D-Simulation verwendet. Es ist sicherlich leistungsfähiger alspygame
, aber die Unterstützung für 2D ist ziemlich niedrig als die inpygame
. Die verfügbaren Dokumentationen / Beispiele sind auch weniger detailliert, was für mich als Anfänger in der Spieleentwicklung ein Nachteil ist und ich die Grundlagen der am häufigsten durchgeführten Operationen wirklich verstehen muss. :) Was das "Alter" von Pygame betrifft: Du hast recht. Eine Modernisierung ist jedoch im Gange! :)pygame.sprite.LayeredUpdates
zum Beispiel) nicht sofort replizieren . Was das unveränderliche Verhältnis betrifft: Ich habe verstanden, was du meinst. Das Verhalten, das Sie beschreiben, möchte ich nicht wiederholen, aber ich habe verstanden, was Sie meinen, danke für die Klarstellung! :)