Frage
Was machst du, wenn du ein 2D-Spiel hast, das sehr große Bilder verwendet (die größer sind, als deine Hardware unterstützt)? Vielleicht gibt es eine interessante Lösung für dieses Problem, die mir noch nie zuvor aufgefallen ist.
Im Grunde arbeite ich an einer Art Grafik-Adventure-Game-Maker. Meine Zielgruppe sind Leute mit wenig bis gar keiner Erfahrung in der Spieleentwicklung (und Programmierung). Wenn Sie mit einer solchen Anwendung arbeiten, möchten Sie nicht, dass sie das Problem intern löst, anstatt Ihnen mitzuteilen, dass Sie "Ihre Bilder aufteilen" sollen?
Kontext
Es ist allgemein bekannt, dass Grafikkarten eine Reihe von Beschränkungen hinsichtlich der Größe der Texturen auferlegen, die sie verwenden können. Wenn Sie beispielsweise mit XNA arbeiten, sind Sie auf eine maximale Texturgröße von 2048 oder 4096 Pixel beschränkt, je nachdem, welches Profil Sie auswählen.
In 2D-Spielen ist dies normalerweise kein großes Problem, da die meisten Level aus kleineren Einzelstücken (z. B. Kacheln oder transformierten Sprites) aufgebaut werden können.
Denken Sie jedoch an einige klassische Point'n'Click-Grafik-Abenteuerspiele (z. B. Monkey Island). Räume in grafischen Abenteuerspielen sind in der Regel als Ganzes gestaltet, mit wenigen oder keinen wiederholbaren Abschnitten, genau wie ein Maler, der an einer Landschaft arbeitet. Oder vielleicht ein Spiel wie Final Fantasy 7, das große vorgerenderte Hintergründe verwendet.
Einige dieser Räume können ziemlich groß werden und häufig drei oder mehr Bildschirme mit einer Breite von bis zu 30 cm umfassen. Wenn wir diese Hintergründe nun im Kontext eines modernen High-Definition-Spiels betrachten, überschreiten sie leicht die maximal unterstützte Texturgröße.
Die naheliegende Lösung besteht nun darin, den Hintergrund in kleinere Abschnitte zu unterteilen, die den Anforderungen entsprechen, und diese nebeneinander zu zeichnen. Aber sollten Sie (oder Ihr Künstler) derjenige sein, der alle Ihre Texturen aufteilt?
Wenn Sie mit einem High-Level-API arbeiten, sollte es dann nicht vielleicht darauf vorbereitet sein, mit dieser Situation umzugehen und die Texturen intern aufzuteilen und zusammenzusetzen (entweder als Vorprozess wie die Inhaltspipeline von XNA oder zur Laufzeit)?
Bearbeiten
Hier ist, was ich dachte, aus der Sicht der XNA-Implementierung.
Meine 2D-Engine benötigt nur einen kleinen Teil der Funktionen von Texture2D. Ich kann es tatsächlich auf diese Schnittstelle reduzieren:
public interface ITexture
{
int Height { get; }
int Width { get; }
void Draw(SpriteBatch spriteBatch, Vector2 position, Rectangle? source, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
}
Die einzige externe Methode, die ich verwende und die auf Texture2D basiert, ist SpriteBatch.Draw (), sodass ich eine Brücke zwischen ihnen erstellen kann, indem ich eine Erweiterungsmethode hinzufüge:
public static void Draw(this SpriteBatch spriteBatch, ITexture texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
{
texture.Draw(spriteBatch, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
}
Auf diese Weise kann ich eine ITexture austauschbar verwenden, wenn ich zuvor eine Texture2D verwendet habe.
Dann könnte ich zwei verschiedene Implementierungen von ITexture erstellen, z. B. RegularTexture und LargeTexture, wobei RegularTexture einfach eine reguläre Texture2D umschließt.
Andererseits würde LargeTexture eine Liste von Texture2Ds führen, die jeweils einem der aufgeteilten Teile des Vollbilds entsprechen. Der wichtigste Teil ist, dass das Aufrufen von Draw () in der LargeTexture in der Lage sein sollte, alle Transformationen anzuwenden und alle Teile so zu zeichnen, als wären sie nur ein zusammenhängendes Bild.
Um den gesamten Prozess transparent zu machen, würde ich eine einheitliche Texture Loader-Klasse erstellen, die als Factory-Methode fungieren würde. Es würde den Pfad der Textur als Parameter nehmen und eine ITexture zurückgeben, die entweder eine RegularTexture oder eine LargeTexture ist, abhängig davon, ob die Bildgröße die Grenze überschreitet oder nicht. Der Benutzer musste jedoch nicht wissen, um welches es sich handelte.
Ein bisschen übertrieben oder klingt es okay?