Spiele einbinden
Alle Möglichkeiten, easygames auf einer Webseite, in einer App oder auf dem TV zu zeigen – mit Beispielen zum Kopieren.
Welche Variante passt?
| Variante | Wann | Aufwand |
|---|---|---|
| Direktlink | Ein Link oder Knopf öffnet das Spiel als ganze Seite (Vollbild). Einfachste und robusteste Lösung, auch für Homepage-Menüs. | 1 Zeile |
| iframe | Ein Spiel soll mitten in einer Seite laufen. | 1 Zeile |
| easygames.js | Spiele per Attribut oder JavaScript-Variable einbauen, mit Vollbild-Knopf. Die Spieleliste kommt automatisch mit. | 2 Zeilen |
| Bibliothek | Die komplette Übersicht mit Suche, Anleitungen und Spielfenster in deine Seite einbetten. | 1 Zeile |
| App | Spiele in einer Android-, iOS- oder Hybrid-App, auch offline. | je nach App |
Code-Generator
Spiel wählen, Optionen einstellen, Code kopieren.
Direktlink
iframe
easygames.js (Attribute)
easygames.js (JavaScript mit Variable)
1. Direktlink empfohlen
Jedes Spiel liegt in einem eigenen Ordner und ist eine vollständige Seite:
<a href="zotik/">ZOTIK spielen</a>
- Das Spiel öffnet als ganze Seite. Vollbild, Zurück-Taste und Tastatur regelt der Browser bzw. das Spiel.
- Mit
target="_blank"öffnet es in einem neuen Tab. - Die Ordnernamen (Spiel-IDs) stehen in
games.jsund im Generator oben. - Direkt in die Übersicht springen und das Spiel dort öffnen:
#zotik(der Viewer öffnet es vollflächig; echtes Vollbild braucht zusätzlich einen Tipp).
2. Ein Spiel als iframe
<iframe src="zotik/" title="ZOTIK" allow="fullscreen; autoplay" allowfullscreen loading="lazy" style="width:100%;max-width:960px;aspect-ratio:16/10;border:0;border-radius:12px"></iframe>
allow="fullscreen" kann im iframe kein Vollbild gestartet werden. Ohne autoplay bleibt Ton oft stumm, bis jemand tippt.- Hochformat-Spiele:
aspect-ratio:9/16oder eine feste Höhe nehmen. - Das Spiel hat im iframe kein Menü zum Schließen. Das liefert deine Seite.
- Einfacher mit Vollbild-Knopf: easygames.js.
3. easygames.js – per Attribut oder JavaScript
Einmal einbinden. Das Script lädt die Spieleliste selbst und findet seinen Pfad automatisch.
<script src="easygames.js"></script>
Variante A – nur HTML
<div data-easygames="zotik"></div> <div data-easygames="anmacha-snake" data-ratio="4/3" data-max-width="720px"></div> <div data-easygames="all"></div> <!-- komplette Bibliothek -->
Variante B – JavaScript mit Variablen
<div id="ziel"></div>
<script>
const spielId = 'zotik'; // beliebige Spiel-ID, z. B. aus einer Datenbank oder URL
EasyGames.embed('#ziel', { game: spielId, ratio: '16/10', maxWidth: '960px' });
// Bibliothek: EasyGames.library('#alle');
</script>
Optionen
| Attribut | JS-Option | Standard | Wirkung |
|---|---|---|---|
data-easygames | game | – | Spiel-ID oder all |
data-width | width | 100% | Breite |
data-max-width | maxWidth | 960px | Maximale Breite |
data-ratio | ratio | 16/10 | Seitenverhältnis |
data-height | height | – | Feste Höhe, ersetzt das Seitenverhältnis |
data-radius | radius | 12px | Eckenrundung |
data-title | title | Spieltitel | Titel für Screenreader |
data-fullscreen="false" | fullscreen:false | Knopf an | Vollbild-Knopf ausblenden |
data-tv-link="false" | tvLink:false | Zeile an | TV-Link unter Mehrspieler-Spielen ausblenden |
Funktionen
| Aufruf | Ergebnis |
|---|---|
EasyGames.embed(ziel, optionen) | Setzt ein Spiel in das Ziel (Selektor oder Element). |
EasyGames.library(ziel, optionen) | Setzt die komplette Übersicht ein. |
EasyGames.ready(callback) | Ruft zurück, sobald die Spieleliste geladen ist. |
EasyGames.list() | Alle Spiele: id, title, desc, icon, url, card. Praktisch für eigene Menüs. |
EasyGames.get(id) / url(id) | Ein Spiel bzw. nur seine URL. |
EasyGames.guide(id, cb) | Anleitung und Bedienung als Objekt {anleitung, steuerung, tipps}. |
EasyGames.fullscreen(iframe) | Startet Vollbild; fällt auf einen neuen Tab zurück, wenn der Browser es nicht kann (z. B. iPhone). |
EasyGames.tvUrl(id) | Link für den TV (öffentliche Adresse, ggf. mit ?tv); null bei Einzelspielen, siehe TV-Link. |
EasyGames.device() | Geräteinfos (Typ, Rolle, Eingaben …), siehe Geräteerkennung. |
EasyGames.scan() | Sucht neu hinzugefügte data-easygames-Elemente (für dynamische Seiten). |
Eigenes Spielmenü bauen
<script>
EasyGames.ready(() => {
EasyGames.list().forEach(g => {
const a = document.createElement('a');
a.href = g.url; a.textContent = g.title; // Direktlink im Vollbild
document.body.appendChild(a);
});
});
</script>
4. Ganze Bibliothek einbetten
<iframe src="?embed=1" title="easygames" allow="fullscreen; autoplay" allowfullscreen style="width:100%;height:90vh;border:0"></iframe>
- Die Übersicht mit Suche und Anleitungen erscheint, ohne Kopfzeile (
?embed=1). - Ein Tipp auf ein Spiel öffnet es im Vollbild-Viewer, der den iframe ausfüllt und Vollbild anfordert. Dafür ist
allow="fullscreen"nötig. - Gib dem iframe genug Höhe (z. B.
90vh), sonst wird der Viewer klein. - Ein bestimmtes Spiel gleich öffnen:
?embed=1#zotik.
URL-Parameter der Übersicht
| Parameter | Wirkung |
|---|---|
?embed=1 | Einbettungsmodus: keine Kopfzeile, kein Footer. |
?tv=1 / ?tv=0 | TV-Modus erzwingen oder abschalten (sonst automatisch bei Smart-TV-Browsern). |
?device=tv|phone|tablet|desktop | Gerätetyp vorgeben, z. B. zum Testen. |
#spiel-id | Öffnet das Spiel direkt im Viewer. |
5. Vollbild
- Übersicht: Der Viewer ist immer vollflächig und fordert beim Öffnen Vollbild an. Die Menüleiste blendet sich nach ein paar Sekunden aus. Ein kleiner Tab oben holt sie zurück.
- iframes auf fremden Seiten: Brauchen
allow="fullscreen". Fehlt es, bleibt das Spiel in der iframe-Größe. - Nutzer-Geste: Browser erlauben Vollbild nur nach einem Tipp oder Klick. Die Übersicht fordert es deshalb beim Tippen auf ein Spiel an.
- iPhone/iPad Safari: Kein Vollbild für Elemente.
EasyGames.fullscreen()öffnet dann das Spiel als eigene Seite in einem neuen Tab. Für Handys ist ein Direktlink deshalb oft die beste Wahl. - Hoch-/Querformat: Die Übersicht erzwingt keine Ausrichtung; ob ein Spiel Quer- oder Hochformat bevorzugt, entscheidet das Spiel.
Geräteerkennung (TV, Handy, Controller)
easygames erkennt selbst, auf welchem Gerät es läuft. Die Übersicht passt sich an (TV-Layout, Hinweise, Filter), und Spiele können dasselbe nutzen.
device.js einbinden
<script src="device.js"></script>
<script>
const d = EasyGamesDevice.get();
console.log(d.type, d.role, d.input);
EasyGamesDevice.on(d => console.log('geändert:', d.orientation));
</script>
Über easygames.js steht es als EasyGames.device() bereit.
Was geliefert wird
| Feld | Werte | Bedeutung |
|---|---|---|
type | tv, phone, tablet, desktop | Gerätetyp (Browser-Kennung, Touch/Maus, Bildschirmgröße) |
role | host, controller, both | Vorschlag für Mehrspieler: TV = Gastgeber (großer Bildschirm), Handy = Controller, sonst beides |
input | touch, mouse, keyboard, remote, gamepad | Mögliche Eingaben |
os | android, ios, ipados, windows, macos, linux, chromeos, tizen, webos, androidtv | Betriebssystem |
orientation, width, height, dpr | – | Ausrichtung und Größe, wird bei Drehen aktualisiert |
app, webview, standalone | true/false | Läuft in einer App-WebView bzw. als installierte Web-App |
fullscreen | true/false | Browser kann Vollbild |
join, joined | Code / true | Wert von ?join=CODE – das Gerät wurde per QR-Code als Controller eingeladen |
how | auto, override | Erkannt oder per ?device= vorgegeben |
?device=tv (auch phone, tablet, desktop) oder EasyGamesDevice.set('tv') lässt sich der Typ vorgeben. ?tv=1 und ?tv=0 funktionieren ebenfalls.CSS-Klassen am <html>
eg-tv | eg-phone | eg-tablet | eg-desktop eg-portrait | eg-landscape eg-gamepad eg-app
/* z. B. */ html.eg-tv .menu { font-size: 150% } html.eg-phone .stick { display: block }
So funktioniert die Handy-Kopplung bei den Spielen
- Spiele mit 📱 Handy-Controller (Kart Rush, Quiz, Koffer Dealer, Hörerwahl, Frequenzrad, Preisradar, Funkparcours, Funkhaus Reality, Mach mich aus!) laufen am PC oder TV als Gastgeber und zeigen einen QR-Code.
- Das Handy öffnet über den QR-Code dieselbe Spielseite mit
?join=CODEund wird automatisch zum Controller. Dafür braucht es keine Auswahl in der Übersicht. - Am TV öffnet die Übersicht Kart Rush mit
?tv, dann erscheint direkt die Lobby mit QR-Code. - Den QR-Code erzeugt das Spiel aus seiner eigenen Adresse. Spiele im Viewer der Übersicht liefern deshalb den direkten Spiel-Link, den Handys ohne Übersicht öffnen.
Für Spiele-Entwickler: Gerät im Spiel nutzen
// A) device.js im Spiel einbinden
<script src="../device.js"></script>
if (EasyGamesDevice.joinCode()) startAsController();
else if (EasyGamesDevice.is('tv')) startAsHostWithQr();
// B) Läuft das Spiel im Viewer der Übersicht, kommt das Gerät auch per Nachricht
addEventListener('message', e => {
if (e.data && e.data.type === 'easygames:device') use(e.data.device);
});
parent.postMessage({ type: 'easygames:getDevice' }, '*'); // jetzt anfordern
// Bei gleicher Herkunft steht es auch als window.EASYGAMES_DEVICE bereit.
Filter in der Übersicht
Karten zeigen Abzeichen (📱 Handy-Controller, 🌐 Online, 👥 Mehrspieler), und Filterknöpfe zeigen nur diese Spiele. Die Zuordnung steht in modes.js.
Android-App mit Offline-Sync
Die App ist eine native Android-Hülle (Kotlin) um die easygames-Oberfläche. Sie speichert alle Spiele samt Bibliotheken auf dem Gerät und hält sie über GitHub aktuell – ohne neues APK.
So kommen Updates auf das Handy
- Push auf GitHub: Ein Spiel wird geändert oder ein neues kommt dazu.
- Manifest: Der Server-Job (
android/server/, systemd-Timer, alle 10 Minuten) holt den neuesten Stand, berechnetsync/manifest.jsonneu (Liste aller Dateien mit Prüfsumme, dazusync/catalog.jsonmit Spielen, Handbuch, Größen) und pusht es nach GitHub, falls sich etwas geändert hat. GitHub Actions werden nicht gebraucht. - Sync in der App: Sobald WLAN verbunden ist (und beim Start), lädt die App das Manifest, vergleicht Prüfsummen und lädt nur geänderte Dateien. Jede Datei wird geprüft, erst wenn alles da ist, wird der neue Stand aktiv. Ein Abbruch lässt den alten Stand unberührt.
- Aktivieren: Mitten im Spiel passiert nichts. Danach zeigt die App „Update bereit – Neu laden“, spätestens beim nächsten Start ist alles aktuell.
Offline
- Das APK enthält einen Start-Stand aller Spiele, die App läuft also sofort ohne Internet.
- Bibliotheken, die Spiele von CDNs laden (three.js, PeerJS, QR-Code, Schrift Fredoka), liegen in
vendor/. Die App fängt die Anfragen ab und liefert die lokale Datei – die Spiele selbst bleiben unverändert. Die Zuordnung steht invendor/map.json. node tools/offline-audit.jsprüft, dass jedes Spiel nur mit dem Offline-Paket lädt.node tools/build-sync.js --strictmeldet neue, noch nicht lokal vorhandene CDN-Bibliotheken.- Braucht weiter Internet: Online-Mehrspieler (PeerJS-Kopplung), Radio-Streams, Cloud-Speicherstand und Links wie das RicoReWi Radio.
Bauen
Die App wird auf eurem Server gebaut (android/build.sh, Anleitung in android/README.md). Ein neues APK ist nur für App-Änderungen nötig, nicht für Spiele-Updates.
Link für TV-Gaming (Mehrspieler)
Bei jedem Mehrspieler-Spiel (📱 Handy-Controller, 🌐 Online, 👥 Mehrspieler) zeigt easygames den richtigen Link für den TV: die öffentliche Spielseite, bei Spielen mit TV-Parameter inklusive ?tv. Der TV-Browser öffnet sie direkt als Vollbildseite, die Handys koppeln sich dann per QR-Code im Spiel.
Wo der TV-Link erscheint
- Übersicht: im Anleitungsfenster (📖) und im Teilen-Dialog jedes Mehrspieler-Spiels, mit Kopieren-Knopf.
- Eingebundene Spiele auf anderen Seiten:
easygames.jssetzt unter jedes Mehrspieler-Spiel die Zeile „📺 Am TV spielen: …“ mit Link und Kopieren-Knopf. Ausblenden mitdata-tv-link="false"bzw.tvLink: false. - Eigene Oberfläche:
EasyGames.tvUrl('anmacha-kart')liefert den Link (für Einzelspielenull).EasyGames.list()enthältmultiplayer,modesundtvUrl. - Im Spiel selbst:
EasyGamesKit.tvUrl()– zum Anzeigen oder als QR-Code für den TV.
Auch in Apps und auf anderen Seiten richtig
Ein TV kann keine Adresse einer App, von localhost oder aus dem lokalen Netz öffnen. Deshalb nimmt easygames für TV-Links immer eine öffentliche Adresse:
- Ist
window.EASYGAMES_PUBLIC_BASEgesetzt, gilt diese (z. B. deine eigene Domain). - Sonst die Adresse, unter der easygames gerade läuft, falls sie öffentlich ist (
https://…). - Sonst (App,
file://,localhost, lokale IPs) die Standardadressehttps://ricorewioriginal-collab.github.io/easygames/.
<script> // vor easygames.js bzw. device.js setzen – nur nötig, wenn die Spiele auf einer eigenen Domain liegen window.EASYGAMES_PUBLIC_BASE = 'https://spiele.meine-seite.de/'; </script>
Neues Mehrspieler-Spiel
Sobald ein Spiel in modes.js (oder am Eintrag in games.js) pad, online oder multi hat, erscheint der TV-Link überall automatisch. Hat das Spiel einen Parameter, der am TV direkt die Lobby öffnet, kommt tvParam dazu.
Neues Spiel hinzufügen
Neue Spiele erscheinen automatisch in Übersicht, Suche, Generator, Einbettung und TV-Navigation. Dafür sind nur wenige Einträge nötig:
| Schritt | Datei | Inhalt |
|---|---|---|
| 1 | mein-spiel/index.html | Das Spiel. Vorlage: tools/spiel-vorlage/index.html |
| 2 | games.js | id, title, icon oder img, bg, glow, path, desc |
| 3 | modes.js oder modes:{…} am Eintrag | pad (Handy-Controller), online, multi, tvParam |
| 4 | guides.js | anleitung, steuerung, tipps |
| 5 | node tools/check-games.js | Prüft IDs, Pfade, Bilder, Anleitungen, Modi |
Was passiert ohne Eintrag?
- Ohne
modes: Das Spiel ist ein normales Einzelspiel, ohne Abzeichen und Filter. - Ohne
guides.js-Eintrag: Das Anleitungsfenster zeigt die Kurzbeschreibung. - Ohne
img: Auf der Karte erscheint das Icon mit dem Farbverlauf. - Filterknöpfe (📱 / 🌐 / 👥) erscheinen nur, wenn mindestens ein Spiel die Art hat.
Spiel-Vertrag
- Das Spiel füllt die ganze Seite (
100vw × 100dvh, kein Scrollen) und läuft auch in einem iframe. - Es ist mit Touch, Tastatur und am TV mit Pfeiltasten und OK bedienbar.
- Handy als Controller: Das Spiel läuft am PC/TV als Gastgeber und zeigt einen QR-Code mit
…/mein-spiel/?join=CODE. Öffnet jemand die Seite mit?join=, wird das Gerät zum Controller. - TV: Optional ein Parameter (üblich:
?tv), der direkt die Lobby mit QR-Code zeigt. Dann inmodes.jstvParam: truesetzen. - Eigene Zurück-Taste (z. B. Pause-Menü)? Mit
EasyGamesKit.back(fn)übernehmen, sonst schließt die Übersicht das Spiel.
gamekit.js – fertige Bausteine
<script src="../device.js"></script>
<script src="../gamekit.js"></script>
<script>
EasyGamesKit.start({
controller: code => startPad(code), // ?join=CODE → Handy als Controller
host: () => startHost(), // TV oder ?tv → Gastgeber mit QR-Code
solo: () => startGame() // sonst normal spielen
});
// EasyGamesKit.joinUrl(raum) Adresse für den QR-Code (die Spielseite selbst)
// EasyGamesKit.onDevice(d => …) Gerät jetzt und bei Änderungen
// EasyGamesKit.fullscreenOnInput() Vollbild beim ersten Tipp/OK
// EasyGamesKit.keepAwake() Bildschirm anlassen
// EasyGamesKit.close() / menu() Übersicht bitten, das Spiel zu schließen / das Menü zu zeigen
</script>
7. postMessage – Spiele sprechen mit der Übersicht
Läuft ein Spiel im Viewer der Übersicht, kann es Nachrichten senden:
parent.postMessage({ type: 'easygames:close' }, '*'); // Spiel schließen
parent.postMessage({ type: 'easygames:menu' }, '*'); // Menüleiste zeigen
parent.postMessage({ type: 'easygames:next' }, '*'); // nächstes Spiel
parent.postMessage({ type: 'easygames:prev' }, '*'); // voriges Spiel
Nur Nachrichten aus dem Spiel-Frame der Übersicht werden beachtet.
8. In einer App (auch offline)
Was in die App muss
- Die Spielordner (je Spiel ein Ordner mit allen Dateien) – für Direktlinks reicht das.
- Für die Übersicht zusätzlich:
index.html,device.js,gamekit.js(für neue Spiele),games.js,modes.js,guides.jsund optionaleasygames.js. Fehlengames.jsundguides.js, bleibt die Übersicht leer. - Alle Pfade sind relativ. Die Ordnerstruktur darf nicht verändert werden.
- Die Dateien laden nichts aus dem Internet. Einzelne Spiele können dennoch Online-Funktionen haben (z. B. Mehrspieler per Code/QR, Speicherstand per Google).
Empfehlung
index.html) oder ein Spiel direkt in einer Vollbild-WebView – nicht als iframe in einer anderen Seite. Das vermeidet Probleme mit Vollbild und Zurück-Taste.Dateien laden: file:// oder https?
file://funktioniert für einfache Spiele. Aber: Der Browser sieht jede Datei als eigene Herkunft. Die Übersicht kann dann nicht in das Spiel hineinhören (Zurück-Taste im Spiel wird nicht abgefangen), und manche Spiele mit Modulen, Wasm oder Speicherung brauchen einen richtigen Ursprung.- Besser: ein lokaler https-Ursprung – bei Capacitor/Cordova ist das
https://localhostbzw. ein App-Schema, bei AndroidWebViewAssetLoader, bei iOS einWKURLSchemeHandler.
Beispiel Android (Kotlin)
val web = findViewById<WebView>(R.id.web)
web.settings.javaScriptEnabled = true
web.settings.domStorageEnabled = true
web.settings.mediaPlaybackRequiresUserGesture = false
// Assets unter https://appassets.androidplatform.net/assets/ ausliefern:
val loader = WebViewAssetLoader.Builder()
.addPathHandler("/assets/", WebViewAssetLoader.AssetsPathHandler(this)).build()
web.webViewClient = object : WebViewClientCompat() {
override fun shouldInterceptRequest(v: WebView, r: WebResourceRequest) = loader.shouldInterceptRequest(r.url)
}
// Vollbild aus HTML5 (onShowCustomView/onHideCustomView) im WebChromeClient umsetzen
web.loadUrl("https://appassets.androidplatform.net/assets/easygames/index.html")
// Zurück-Taste: if (web.canGoBack()) web.goBack() else finish()
Beispiel iOS (Swift)
let cfg = WKWebViewConfiguration()
cfg.allowsInlineMediaPlayback = true
cfg.mediaTypesRequiringUserActionForPlayback = []
let web = WKWebView(frame: .zero, configuration: cfg)
let dir = Bundle.main.url(forResource: "easygames", withExtension: nil)!
web.loadFileURL(dir.appendingPathComponent("index.html"), allowingReadAccessTo: dir)
// Zurück: web.allowsBackForwardNavigationGestures = true
Ton und Touch
- Ton startet erst nach einer Berührung. Deshalb
mediaPlaybackRequiresUserGesture = false(Android) bzw.mediaTypesRequiringUserActionForPlayback = [](iOS) setzen. - Hardware-Zurück der App an die WebView weitergeben, damit die Übersicht ein Spiel schließen kann.
9. Eigener Server und Pfade
- Die Ordner können auf jeden statischen Webspace kopiert werden. Alles läuft rein im Browser, ein Server wird nicht benötigt (Ausnahme: Online-Mehrspieler bei einzelnen Spielen).
- In
games.jsistpathein Ordner relativ zur Übersicht oder eine komplette URL. So lassen sich Spiele auch von woanders einbinden. - Neues Spiel? Einen Eintrag in
games.jsergänzen und optional eine Anleitung inguides.js. - Schickt dein Server
X-Frame-Options: DENYoder ein restriktivesframe-ancestors, lassen sich die Seiten nicht in iframes einbetten. GitHub Pages erlaubt das. - Auf https-Seiten dürfen nur https-Spiele eingebettet werden (sonst blockiert der Browser gemischte Inhalte).
10. Fehlerhilfe
| Problem | Ursache und Lösung |
|---|---|
| Vollbild-Knopf tut nichts | Im iframe fehlt allow="fullscreen", oder das Gerät (iPhone) unterstützt es nicht. Dann Direktlink nutzen. |
| Kein Ton | Erst nach Tippen erlaubt. In Apps die Autoplay-Einstellung der WebView anpassen. |
| Übersicht ist leer | games.js wird nicht gefunden (falscher Pfad, nicht mitgepackt, oder Browser-Konsole prüfen). |
| Keine Anleitungen | guides.js fehlt. Die Karten funktionieren trotzdem, nur das Anleitungsfenster zeigt dann die Kurzbeschreibung. |
EasyGames ist undefined | Das Script ist noch nicht geladen. EasyGames.ready(...) verwenden oder das Script vor dem eigenen Code einbinden. |
| Spiel ist zu klein/abgeschnitten | Seitenverhältnis oder Höhe anpassen (data-ratio, data-height). |
| Zurück-Taste schließt das Spiel nicht | Spiel liegt auf anderer Domain oder file://. Zurück in der App selbst an die WebView weiterreichen. |
| Bild bleibt leer | Mixed Content (http in https), Blockierung durch X-Frame-Options, oder das Spiel braucht Netz und ist offline. |
| TV zeigt falsches Layout | ?tv=1 anhängen (bzw. ?tv=0 zum Abschalten). |