Guide

Tilføj spil til din app: kør et HTML5-spil i en WebView

Sådan lægger du et færdigt HTML5-spil ind i en Android- eller iOS-app, du allerede har: lokale eller hostede filer, gemte data, tilbage-knappen og licensen.

Illustration til Deepforge-puslespillet, et HTML5-spil, der kan køre i en apps WebView.

For at tilføje spil til din app behøver du ikke en spilmotor i den. Du har brug for en WebView: komponenten Android og iOS stiller til rådighed for at vise webindhold inde i en native skærm. Du lægger en færdig HTML5-spilmappe enten i app-pakken eller på din egen HTTPS-server, peger en WebView på dens index.html, og din app får en spilsektion, der kører på samme kode som browserversionen.

Denne guide er til teams, der allerede har en app (en detailapp, en bank, en skoleplatform, en klub eller et medie-brand) og vil have spil i appen som en funktion, ikke en ny app i butikken. Den dækker valget mellem lokale og hostede filer, de WebView-indstillinger, der ødelægger spil, når de er forkerte, gemte fremskridt, tilbage-knappen, hvilke af vores skabeloner der passer, og hvordan licensen tæller apps. Platformsdetaljerne kommer fra Android Developers og Apple Developer-dokumentationen, læst 30. oktober 2026.

Tilføj spil til din app: sådan fungerer WebView-vejen

En WebView er en browsermotor uden browseren omkring sig. Din native kode opretter den, bestemmer størrelsen og indstillingerne og fortæller, hvad den skal indlæse. På Android hedder klassen WebView; på iOS hedder den WKWebView. Et HTML5-spil kan ikke se forskel: det ser en side, et canvas og lagring, ligesom i Chrome eller Safari.

Derfor er vejen populær til spil i apps. Spilteamet arbejder i HTML, CSS og JavaScript, app-teamet tilføjer én skærm og nogle få indstillinger, og den samme spilmappe kan også ligge på hjemmesiden. Der er tre bevægelige dele at planlægge:

  1. Hvor filerne ligger: pakket ind i appen eller serveret fra din HTTPS-server.
  2. Hvordan WebView'en er sat op: JavaScript, lagring, den adresse spillet kører fra.
  3. Hvordan spillet og appen taler sammen: åbning, pause, tilbage-knappen, lukning.

Vores skabeloner passer til denne form, fordi hver enkelt leveres med en færdig mappe game/ med en index.html, bygget til statisk hosting, uden PHP eller database til selve spillet. Det ingen af dem indeholder, er den native del. Hver udgave lister native apps eller app-store-builds under "Ikke inkluderet i denne udgave", så WebView-skærmen er dit teams arbejde eller en opgave, vi giver tilbud på separat.

Se HTML5-spilskabelonerne

Lokalt eller hostet: hvor spilfilerne skal ligge

Lokalt: spillet følger med i appen

Androids vejledning til indhold i apps siger, at webindhold kompileret ind i appen ikke kræver internetadgang og ikke bruger brugerens datatrafik. Du kopierer mappen game/ ind i appens assets og indlæser den derfra. Prisen er størrelsen: spillet lægger sig oveni downloaden, og hver spilopdatering betyder en ny app-udgivelse gennem butikkens review.

Hostet: appen henter spillet fra din server

WebView'en åbner en HTTPS-adresse på dit eget domæne. Du kan opdatere spillet uden en ny app-build, og appen forbliver lille. Prisen er, at spillet kræver forbindelse, og et langsomt netværk viser sig som en langsom første indlæsning.

Apple har en særlig regel her. Retningslinje 4.7 i App Review Guidelines dækker HTML5- og JavaScript-minispil, der ikke er indlejret i den kompilerede app. Blandt betingelserne må appen ikke udvide eller eksponere native platformsAPI'er for den software uden Apples tilladelse, og den skal levere et indeks over den software, den tilbyder, med universal links. Læs 4.7 i sin helhed, før du vælger den hostede vej til iOS.

  • App-størrelse: lokalt lægger spillets vægt oveni; hostet lægger næsten intet til.
  • Opdateringer: lokalt kræver en app-udgivelse; hostet ændres, når du uploader.
  • Forbindelse: lokalt kan starte uden netværk, når appen er installeret; hostet kræver et.
  • Review: lokale spil gennemgås som en del af appen; hostede spil på iOS falder under retningslinje 4.7.

Android WebView-indstillinger, der gør eller ødelægger et spil

De fleste rapporter om, at "spillet viser en hvid skærm", skyldes tre standardindstillinger. Alle tre er dokumenteret på Android Developers.

  1. JavaScript er slået fra. WebView-vejledningen siger, at JavaScript er deaktiveret i en WebView som standard. Hvert HTML5-spil har brug for det, så slå det til i WebSettings.
  2. Lagring er slået fra. WebSettings-referencen siger, at standardværdien for setDomStorageEnabled er false. Spil, der gemmer fremskridt i localStorage, skal have den slået til, ellers starter hver session fra nul.
  3. file:// er den forkerte adresse. Androids vejledning til indhold i apps forklarer, at file://-adresser er uigennemsigtige oprindelser, der ikke kan bruge API'er som fetch() eller XMLHttpRequest, og den anbefaler ikke at slå workaround-filadgangene til. Vores produktsider siger det samme fra spillets side: udgaver som Gridspark og Twirldrop kører ikke fra file://.

Løsningen på det tredje punkt er WebViewAssetLoader fra AndroidX Webkit-biblioteket. Den serverer filer fra appens assets over en HTTPS-adresse, og Androids eget eksempel indlæser https://appassets.androidplatform.net/assets/index.html. For spillet ligner det en almindelig hjemmeside, så ES-moduler, fetch og lagring opfører sig, som de gør på din server.

iOS: WKWebView, lokale filer og datalageret

På iOS hedder komponenten WKWebView. Apple dokumenterer loadFileURL(_:allowingReadAccessTo:) til lokalt indhold: det andet argument er den fil eller mappe, WebKit må læse, og hvis du sender en mappe, kan siden indlæse filerne omkring den.

Fordi vores udgaver ikke understøtter åbning fra file://, så test den vej omhyggeligt, eller spring den over. Apple tilbyder også WKURLSchemeHandler, en protokol til at indlæse ressourcer med URL-skemaer, WebKit ikke selv håndterer, så din app kan servere spilmappen under sit eget skema. Capacitor gør det for dig: dets standardskema på iOS er capacitor.

Lagring ligger i WKWebsiteDataStore. Apples side siger, at standardlageret gemmer webdata vedvarende på disken, og at et ikke-vedvarende lager kun gemmer data i hukommelsen, hvilket er tænkt til privat browsing. Hvis nogen på dit team sætter et ikke-vedvarende lager, mister spillerne deres fremskridt, hver gang appen lukker.

iOS har ingen systemtilbage-knap, så din spilskærm skal have sin egen vej ud: en luk-knap i din native bjælke, eller en knap spillet kalder via en beskedhåndtering.

Gem fremskridt inde i appen

Vores spil gemmer i spillerens browserlager, ikke på en server. Solitaire Links og Deepforge siger det tydeligt på deres sider: fremskridt gemmes i localStorage, uden konto eller cloud-synkronisering. Inde i en app har det tre konsekvenser.

  • Adressen er en del af gemmen. Browserlager hører til en oprindelse. Flytter du fra ét skema eller én vært til et andet, for eksempel fra et testdomæne til appassets.androidplatform.net, starter spillerne forfra. Vælg adressen én gang.
  • Gemmenøglen er en del af gemmen. Tenguins produktside beder købere om at holde gemmenøglen uændret i et live-spil, ellers mister spillerne deres fremskridt. Flere TypeScript-udgaver har gemmenøglen i brand.ts. Ændr den bevidst, før lancering, aldrig efter.
  • Sletning af appens data sletter spillet. Afinstallation eller tømning af appens lager fjerner gemmen, ligesom tømning af en browser gør.

Hvis fremskridt skal følge brugeren på tværs af enheder, er det en serverfunktion, som ingen af vores udgaver indeholder. Hver udgave lister cloud-gemme eller konti som ikke inkluderet. Deepforge er det venligste udgangspunkt: dens side beskriver eksport og import af gemmen i menuen, og et lille window.DeepForge-API, der lader værtssiden sætte pause, genoptage, læse gemmen og lytte efter gemme-hændelser.

Se Deepforge og dets API til værtssiden

Tilbage-knappen, pause og at forlade spillet

HTML5-spil er typisk én side. Det betyder noget på Android, hvor tilbage-knappen går igennem WebView'ens historik. Androids WebView-vejledning viser mønstret: tjek canGoBack() og kald goBack(), eller lad systemet håndtere hændelsen; med AndroidX registrerer du den samme logik hos OnBackPressedDispatcher. I et spil på én side er historikken ofte tom, så tilbage lukker din spilskærm med det samme, midt i et niveau.

Beslut, hvad tilbage skal gøre, og skriv det ned:

  • Første tryk åbner spillets pausemenu; andet tryk forlader spilskærmen.
  • Eller tilbage forlader altid, efter spillet har gemt. Hver udgave gemmer lokalt, men tjek hvornår: ved slutningen af et niveau eller undervejs.
  • Når appen går i baggrunden, sæt spillet på pause. Uden pausen kører timere videre bag appens andre skærme.

Vores udgaver følger ikke med en app-bro. Nogle tilbyder en indgang fra siden: Gridspark og Ricopop har en skærm til tryk-for-start og en fuldskærmsknap, du slår til eller fra i en konfigurationsfil, og Deepforge eksponerer pause og genoptag over for siden. Alt andet, såsom en besked til native kode, når et niveau slutter, er en lille ændring i kildekoden, som dit team eller en opgave, vi giver tilbud på, tilføjer.

Se Gridspark, ren JavaScript uden build-trin at spille

Licens: ét spil, én app, og hvad du spørger om først

Vores vilkår giver en evig, ikke-eksklusiv licens til at bruge udgaven i ét slutprodukt, for dig eller for én kunde. Din app med spilsektionen er det slutprodukt. Spillerne må få adgang gratis eller gennem annoncemonetisering. Du må ændre koden, kunsten og lyden, og white label er tilladt: dit brand erstatter vores.

Tre situationer kræver et nærmere kig.

  • Flere apps. Et bureau, der lægger det samme spil ind i tre kunders apps, har brug for tre licenser. Køber du flere skabeloner i én ordre, får du pakkerabat: 5 % for to, 10 % for tre, 15 % for fire og 20 % for fem eller flere.
  • Android- og iOS-versioner af samme app. Én licens lader dig udgive spillet, hvor du vil, inklusive Google Play og App Store. Det er stadig én licens pr. slutprodukt.
  • Et spil-SDK til andre udviklere. Vilkårene forbyder videresalg af skabelonen eller dens kode i et andet produkt, der er tænkt til udviklere. Et spilmodul, du sælger til andre app-udviklere, er den slags produkt.

Hvis din app tager betaling for spilsektionen eller sælger ting inde i den, så spørg os også først. Vilkårene nævner gratis adgang og annoncemonetisering, og flere udgaver lister køb for rigtige penge som ikke inkluderet. På iOS siger retningslinje 3.1.1, at oplåsning af funktioner eller indhold, herunder spilniveauer, skal ske via køb i appen.

Licenser, fakturaer og tilbud til virksomheder

Ofte stillede spørgsmål

Kan jeg lægge et HTML5-spil ind i en Android- eller iOS-app?

Ja. Indlæs spilmappen i en WebView (WebView på Android, WKWebView på iOS), enten pakket ind med appen eller fra din HTTPS-server. Slå JavaScript og lagring til, og server filerne fra en HTTPS-lignende adresse i stedet for file://.

Virker spillene offline inde i appen?

Kun hvis du pakker filerne ind, og udgaven ikke henter noget fra netværket. Flere af vores udgaver har kunst, lyd og skrifttyper lokalt; Ricopops side siger, at det kræver forbindelse. Test i flytilstand, før du lover det.

Mister spillerne fremskridt, når jeg opdaterer appen?

Ikke hvis adressen og gemmenøglen forbliver de samme. Gemmer ligger i WebView'ens lager for den oprindelse. Ændrer du skema, vært eller lagernøgle, starter alle forfra.

Hvor mange licenser har jeg brug for til min app?

Én pr. slutprodukt. Én app med ét spil er én licens; det samme spil i apps for tre kunder er tre. Den samme app på Google Play og App Store kræver ingen anden licens: du må udgive det licenserede spil, hvor du vil.

Næste skridt

Vælg et spil, spil dets demo på en telefon, og læs derefter listen "Ikke inkluderet i denne udgave" og manualens kapitel om gemmer. Hvis du hellere vil have, at vi bygger spilskærmen ind i din app, så send os appen, platformene og det spil, du kan lide, og vi svarer med omfang, pris og tidsplan.

Se alle spilskabeloner

Bed om et tilbud på app-integration