Wie löse ich meine Auflösungsprobleme?


7

Ich entwickle ein Spiel mit XNA und habe Probleme mit Auflösungen. Im Moment habe ich nur das Hauptmenü implementiert, aber ich möchte ein Spiel machen, das unabhängig von der Auflösung ist. Da ich ein Anfänger bin, habe ich die Auflösung bisher nicht berücksichtigt. Als ich die Auflösung änderte, bekam ich echte Kopfschmerzen. Das Hintergrundbild, das ich verwende, hat eine Auflösung von 1920 x 1080, also ein Seitenverhältnis von 16: 9. Die anfängliche Auflösung betrug 800 x 600, sodass das Hintergrundbild gestreckt aussieht. Gleiches gilt für Auflösungen mit einem Seitenverhältnis von 4: 3 (z. B. 640 x 480, 1024 x 768 usw.).

Bevor ich diese Frage stellte, suchte ich im Internet nach Informationen. Ich fand "XNA 2D Independent Resolution Rendering" und andere ähnliche Lösungen. Die angebotene Lösung scheint mir zunächst perfekt zu sein, da ich nicht daran gedacht habe, zwei Auflösungen zu verwenden. eine interne zum Zeichnen und eine, die der Größe des Fensters entspricht. Ich habe jedoch einige Probleme beobachtet.


Wenn ich den Vollbildmodus aktiviere und die Auflösung niedriger als die Desktopauflösung ist, wird die Auflösung des Spiels nicht auf den gesamten Bildschirm ausgedehnt. Dadurch wird das Spiel in der Mitte des Bildschirms gezeichnet, jedoch mit einem schwarzen Rand auf beiden Seiten des Bildschirms.

Geben Sie hier die Bildbeschreibung ein


Das Seitenverhältnis meines Hintergrundbilds beträgt 16: 9. Die von mir versuchten Auflösungen haben jedoch ein Seitenverhältnis von 4: 3. Mit der Seitenlösung habe ich das gleiche Problem; Das Hintergrundbild scheint gestreckt zu sein. Ich habe den Code recherchiert, um eine Lösung zu finden, und die RecreateScaleMatrix()Funktion folgendermaßen geändert :

private static void RecreateScaleMatrix() 
{
    _dirtyMatrix = false;
    float aspect = 16.0f / 9.0f;
    _scaleMatrix =
        Matrix.CreateScale((float)_device.GraphicsDevice.Viewport.Width / _virtualWidth,
        (float)_device.GraphicsDevice.Viewport.Height / _virtualHeight, 1f) *
        Matrix.CreateScale(1, EngineManager.GameGraphicsDevice.Viewport.AspectRatio / 
        aspect, 1) * Matrix.CreateTranslation(0, (_device.GraphicsDevice.Viewport.Height - 
        (_device.GraphicsDevice.Viewport.Height / aspect)) / 4.0f, 0);
}

Dies scheint das Problem gelöst zu haben, jedoch nur bei bestimmten Auflösungen, und das Rechteck, das das Endergebnis anzeigt, weiter zu reduzieren.


Ich habe den ganzen Tag über diese Probleme nachgedacht und festgestellt, dass es fast unmöglich ist, ein Bild klar zu zeichnen, ohne die genaue Auflösung des zu zeichnenden Bildes im Voraus (unabhängig vom Seitenverhältnis) zu kennen.

Wie löse ich meine Auflösungsprobleme?

Antworten:


4

Die einfachste Antwort ist die, die Sie bereits gefunden haben: Zeichnen Sie alles intern RenderTargetmit einer festen Auflösung auf a und verwenden Sie anschließend das RenderTargetals Textur und zeichnen Sie es so groß wie möglich. Sie sollten in der Lage sein, den gesamten Bildschirm auszufüllen, wenn das Seitenverhältnis gleich ist. Verwenden Sie einfach die Spritebatch.DrawÜberladung, die ein Zielrechteck verwendet. Wenn Sie eine interne Auflösung mit einem Seitenverhältnis von 16: 9 verwenden, sollten Sie ein Rechteck wie das folgende erstellen:

//If the internal resolution and target resolution are both 16:9
Rectangle dest = new Rectangle
    (
        0,
        0,
        graphics.ViewPort.Width,
        graphics.ViewPort.Height
    );

//If the internal resolution is 16:9 and target resolution is 4:3
int height = (int)(graphics.ViewPort.Width * (16.0/9.0));
Rectangle dest = new Rectangle
    (
        0,
        graphics.ViewPort.Height - (int)(height / 2.0),
        graphics.ViewPort.Width,
        height
    );

Ein anderer Ansatz wäre, sicherzustellen, dass alle Text- und GUI-Elemente einen Safe im Render-Ziel haben, der ein Seitenverhältnis von 4: 3 hat, und dann einfach den linken und rechten Teil auf einem 4: 3-Bildschirm zu verwerfen. (Dies könnte Spielern mit einem Seitenverhältnis von 16: 9 einen Vorteil verschaffen, da sie ein größeres Sichtfeld haben.)

Tipp: Wenn Sie Ihr Spiel für die XBOX360 entwickeln, können Sie es nur für eine Auflösung entwickeln, da die XBOX die Auf- und Ab-Skalierung automatisch für Sie durchführt. Sie sollten eine interne Auflösung von 720P verwenden, da dies die höchste Auflösung ist, die der XBOX-Upscaler / Downscaler auf die alte TV-Auflösung verkleinern kann.

Bearbeiten:

Siehe die Kommentare: Die allgemeine Formel für das Zielrechteck, die für alle Seitenverhältnisse funktioniert, bei denen width> = height wäre:

double aspectratio = ((double)graphics.ViewPort.Width / (double)graphics.Viewport.Height);
    int height = (int)(graphics.ViewPort.Width * aspectratio;
    Rectangle dest = new Rectangle
        (
            0,
            graphics.ViewPort.Height - (int)(height / 2.0),
            graphics.ViewPort.Width,
            height
        );

1
Vergessen Sie nicht 16:10, was auch eine ziemlich häufige Monitorgröße ist.
Matthew Scharley

Ah du hast absolut recht! Ich habe die allgemeine Formel hinzugefügt, die für alle Seitenverhältnisse funktionieren soll, bei denen die Bildschirmbreite> = Bildschirmhöhe ist.
Roy T.
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.