08/02/2023
Kan et mobilspil fungere på alle enhedsstørrelser?
At lancere et mobilspil i dagens fragmenterede marked præsenterer en unik udfordring: at sikre, at spillet ser lige så godt ud på en lille telefon med lav opløsning som på en stor tablet med høj opløsning. Dette var en lektie, jeg lærte hårdt med mit første spil, Ludo's Quest. Dengang brugte jeg billedsprites, og når de skulle skaleres dynamisk for at passe til forskellige skærme, mistede de deres skarphed og blev uskarpe. Med mit seneste spil, Miam Boom!, var jeg fast besluttet på at løse dette problem en gang for alle.

Mange enheder, mange skærmstørrelser
Mobilmarkedet er et sandt kludetæppe af enheder med vidt forskellige fysiske dimensioner og skærmopløsninger. Min iPad Mini har en fysisk opløsning på 768x1024 pixels, mens min iPhone 6 har 750x1334 pixels, og min Nexus 7 kan prale af 1080x1920 pixels. At håndtere disse forskelle er afgørende for at levere en ensartet visuel oplevelse.
I Ludo's Quest forsøgte jeg at låse spillets bredde til 1024 pixels ved hjælp af viewport meta-tagget:
<meta name="viewport" content="width=1024, user-scalable=no"/> Dette fungerede fint på min iPad Mini, men på andre enheder resulterede den dynamiske skalering i uskarpe billeder. Løsningen er ikke at tvinge en bestemt bredde, men derimod at udnytte enhedens faktiske fysiske bredde og indlæse forudskalerede sprites baseret på opløsningen. Viewporten bør i stedet sættes til:
<meta name="viewport" content="user-scalable=no"/> Bemærk: Mange kilder anbefaler at sætte `width=device-width`. Dette sætter viewportens bredde til enhedens CSS-bredde, ikke den fysiske bredde. For en iPhone 6 giver dette 375x667 pixels i stedet for de faktiske 750x1334 pixels – hvilket ikke er ønskeligt.
Fastlæggelse af spritestørrelser
Udfordringen ligger i at definere sprite-arkene i flere opløsninger. I Miam Boom! brugte jeg monstrene som udgangspunkt. Ved en minimumsopløsning på en iPhone 3 uden Retina, svarende til 180 pixels (en fjerdedel af enhedens højde på 480 pixels), skalerer grafikken op med 2x, 3x eller 4x, efterhånden som opløsningen stiger.
Her er et eksempel på, hvordan katten, et af monstrene i spillet, ser ud på forskellige enheder med korrekt skalering:
iPhone 4 (640x960) scale=2x, iPhone 6 (750x1334) scale=2x, og iPad Air (1536x2048) scale=3x
Det er vigtigt at bemærke, at katten kan virke mindre på visse skærme. Dette er acceptabelt, men det har konsekvenser for brugergrænsefladen (GUI) og selve spillets gang. For at imødekomme dette måtte jeg gøre spillet responsivt og positionere elementer proportionelt til viewportens bredde og højde. Knapper centreres for eksempel eller justeres til venstre og højre, etiketter forankres til top og bund, og monsteret er altid forankret i forhold til bunden. Disse strategier fungerer uanset højde eller billedformat.
Vektorgrafik er nøglen
Den absolutte nøgle til at opnå skarp grafik på alle skærme er brugen af vektorgrafik. I Ludo's Quest kombinerede jeg vektorgrafik med pixelbaserede billeder, hvilket altid resulterer i uskarpe billeder, når de skaleres op. Denne lektie blev lært, og i Miam Boom! brugte jeg udelukkende vektorgrafik. Jeg har nu mestret Adobe Illustrator til dette formål.
Jeg definerede mine sprite-ark i Adobe Illustrator og eksporterede billederne i de korrekte skaleringsfaktorer. Her er et eksempel på det primære sprite-ark til spillet:
Miam Boom! artefakt sprite-ark
Sprite-arket indeholder 4 forskellige versioner, én for hver skaleringsfaktor:
- artifacts.png (990x360) scale=1x
- artifacts2.png (1980x720) scale=2x
- artifacts3.png (2970x1080) scale=3x
- artifacts4.png (3960x1440) scale=4x
Tricket er at indlæse de korrekt skalerede billeder baseret på enhedens skærmstørrelse. Denne metode sikrer, at billederne altid er skarpe og klare, uanset hvor meget de skaleres.
Dynamisk indlæsning af grafik
I Ludo's Quest blev al grafik forudindlæst direkte i HTML-filen på denne måde:
<body> <img id="gui" src="img/gui.png" style="display:none;" /> <img id="artifacts" src="img/artifacts.png" style="display:none;" /> ... </body> I Miam Boom! var denne tilgang ikke længere mulig. I stedet bestemmer jeg skaleringsfaktoren ved kørselstidspunktet for at indlæse de korrekte sprites. Jeg indlæser dem dynamisk ved hjælp af JavaScript. Backbone Game Engine tilbyder en praktisk funktion til dette:
function loadImage(url, callback) { var img = document.createElement("img"); img.src = url; if (callback) { img.onreadystatechange = callback; img.onload = callback; } } Backbone.SpriteSheet har en `imageUrl` egenskab til dynamisk indlæsning af billeder og bruger denne funktion, så du ikke behøver at bekymre dig om detaljerne.
Bemærk: På iOS indlæses billeder meget hurtigt. På Android ser det ud til at være langsommere. For at undgå at vise en skærm uden billeder er det vigtigt at vente, indtil alle billeder er indlæst. Backbone.SpriteSheetCollection har `event allSpawnImg` til at håndtere dette.
Før jeg indlæser billeder, skal jeg bestemme størrelsen på de billeder, der skal indlæses, baseret på enhedens fysiske pixelstørrelse.
var screenWidth = Math.max(window.screen.width * window.devicePixelRatio, window.innerWidth); var factor = screenHeight >= 960 ? 2: 1; if (screenHeight >= 960*2) factor = 3; if (screenHeight >= 960*2.5) factor = 4; Billed-URL'erne modificeres derefter for at indlæse den korrekte størrelse:
imgUrl.replace(".png", factor + ".png"); Tilpasning af gameplay
Da skærmstørrelser og billedformater varierer fra enhed til enhed, var det nødvendigt at sikre, at gameplayet kunne tilpasses alle situationer. Igen måtte jeg justere mine heuristikker til at forankre elementer til top og sider. Desuden, da spillet måler afstand i pixels, var det nødvendigt at skalere hastighed og acceleration tilsvarende. Dette sikrer en konsistent spiloplevelse, uanset hvilken enhed spilleren anvender.
iPad Mini (768x1024) og iPhone 6 Plus (1080x1920)
Overvejelser omkring ydeevne
Oprindeligt frygtede jeg, at indlæsning af større billeder ville påvirke ydeevnen negativt og øge hukommelsesforbruget. Et billede skaleret til 2x kræver fire gange så meget hukommelse, og skaleret til 4x kræver 16 gange så meget. Heldigvis viste det sig ikke at være tilfældet.
Det ser ud til, at der er rigelig processorkraft og hukommelse i nyere iPads og iPhones til at håndtere de ekstra pixels. Selv min Nexus 7 med en opløsning på 1080p ydede godt. Jeg var positivt overrasket over den gode ydeevne, selv med højopløselige grafikker.
Konklusion
Jeg er meget tilfreds med resultatet. Miam Boom! ser krystalklar ud på enhver enhed. Dette er en markant forbedring i forhold til Ludo's Quest. De erfaringer og metoder, jeg har anvendt her, vil helt sikkert tjene mig godt i mit næste spil. Jeg opfordrer dig til selv at opleve forskellen.
Miam Boom! er tilgængelig i App Store og på Google Play.
Ofte Stillede Spørgsmål
Q1: Hvad er den bedste metode til at håndtere forskellige skærmstørrelser i mobilspil?
A1: Brug af vektorgrafik og dynamisk indlæsning af forudskalerede billeder baseret på enhedens fysiske opløsning er den mest effektive metode. Tilpas også spillets UI-elementer og gameplay-mekanikker til at være responsive.
Q2: Vil vektorgrafik altid resultere i skarpere billeder end pixelbaserede billeder?
A2: Ja, vektorgrafik kan skaleres uendeligt uden tab af kvalitet, hvilket sikrer skarpe billeder på alle opløsninger. Pixelbaserede billeder bliver uskarpe, når de forstørres ud over deres oprindelige opløsning.
Q3: Hvilken indvirkning har dynamisk indlæsning af billeder på spillets ydeevne?
A3: Mens indlæsning af flere billedversioner kan øge hukommelsesforbruget, har moderne mobile enheder tilstrækkelig processorkraft og hukommelse til at håndtere dette uden væsentlig ydeevnepåvirkning, især når det implementeres korrekt.
Q4: Hvad er forskellen på `width=device-width` og `user-scalable=no` i viewport meta-tagget?
A4: `width=device-width` refererer til enhedens logiske eller CSS-bredde, som kan være anderledes end den fysiske pixelbredde. `user-scalable=no` deaktiverer brugerens mulighed for at zoome, hvilket kan være nyttigt for at bevare den tilsigtede layout, men det er vigtigere at forstå forskellen på den logiske og fysiske bredde for korrekt skalering af grafik.
Q5: Hvordan sikrer man, at spillets UI er responsivt?
A5: Brug proportionale positioneringsmetoder, såsom at forankre elementer til kanterne af skærmen eller centrere dem. Skaler også elementer som knapper og tekst baseret på skærmens dimensioner for at opnå et ensartet udseende på tværs af enheder.
Hvis du vil læse andre artikler, der ligner Mobilspil: Skarp grafik på alle skærme, kan du besøge kategorien Teknologi.
