Skalning i MonoGame

with No Comments

MonoGame är ett av flera bibliotek för spelutveckling i Visual Studio för bl.a. PlayStation, Windows, Linux, iOS och Android. MonoGame kan rendera grafik (genom OpenGL eller DirectX), spela ljud och ta emot användarinteraktioner från tangentbord och handkontroller. Förutom att bygga spel är MonoGame användbart för interaktiva presentationer eller animationer. Denna text presenterar två metoder för att skala upp grafiken i ett MonoGame-projekt till önskad storlek.

Ett MonoGame-projekt består av en klass som ärver från Microsoft.Xna.Framework.Game och programmets initieras av funktionen Run.

Dessutom levereras projektmallarna för MonoGame med en mgcb-fil som hanterar projektets resurser (t.ex. bilder, texturer eller ljudeffekter). Filen redigeras med det externa verktyget MonoGame Pipeline Tool (C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools\Pipeline.exe). Kodexemplen i denna text antar att mgcb-filen i projektet har en png-bild som heter McFly.

Klassen Game har tre viktiga virtuella funktioner att skriva över. LoadContent används för att läsa in resurser. (Projektmallen låter även LoadContent skapa en SpriteBatch som används för att rita sprites.) De andra två är Update som används för att implementera spelets logik och Draw som används för att rendera spelets grafik på skärmen. Detta program använder LoadContent för att läsa in bilden McFly som en 2D-textur och funktionen Draw för att presentera bilden på skärmen i ett fönster.

Ovanstående kod, som till största delen kommer från en projektmall, ger en bra bild av hur man arbetar med MonoGame.

Spelet presenteras på en yta som är 800 x 480 pixlar stor. Det är tänkbart att man skulle vilja ändra storleken på ytan, kanske för att den ska täcka hela skärmen. GraphicsDeviceManager-instansen har egenskaper för att kontrollera arbetsytans storlek (PreferredBackBufferWidth och PreferredBackBufferHeight). Den har dessutom en egenskap för fullskärmsläge som döljer fönstrets kanter. Så för att visa spelet i fullskärmsläge bör arbetsytans storlek vara lika med skärmens storlek (som kan läsas av från GraphicsAdapter.DefaultAdapter.CurrentDisplayMode).

Om man vill att spelet ska utspelas på en spelplan som alltid har en viss storlek oberoende av hårdvaran som spelet spelas på, kan man välja en strategi för att skala upp spelet. Tanken kanske är att man bygger ett retrospel som alltid ska spelas upp en 320 x 200 pixlar stor yta som rent fysiskt ska täcka skärmen. Båda följande exempel kommer att visa en 320 x 200 pixlar stor spelplan uppskalad till 640 x 400 pixlar, men användarens bildskärmsinställningar kan som sagt läsas av från egenskapen CurrentDisplayMode.

En instans av strukturen Microsoft.Xna.Framework.Matrix kan skickas till SpriteBatch-instansen som en skalningsinstruktion. Parametrarna till funktionen CreateScale anger önskad skalning i X-led, i Y-led och i Z-led.

Denna lösning gör att den virtuella upplösningen på 320 x 200 punkter täcker hela den fysiska upplösningen på 640 x 400. Om man använder helskärmsläge innebär det troligtvis att pixlarna blir avlånga eftersom skärmen förmodligen har ett annat bildförhållande.

Istället för att använda Matrix-strukturen, kan man rendera sin grafik på ett s.k. custom render target (istället för den backbuffer som man får av MonoGame). När renderingen är klar, kan man kopiera grafiken på sitt custom render target till den normala backbuffern, och i samband med det applicera skalning och justering. En custom render target kan t.ex. beskrivas av klassen Microsoft.Xna.Framework.Graphics.RenderTarget2D.

Förutom att kontrollera justering och skalning, skulle man även utnyttja denna extra buffert till att lägga på effekter, som t.ex. CRT-emulering, eller återkoppling på händelser i spelet.

Follow Anders Hesselbom:

Latest posts from

Leave a Reply