K (zu Kategorie "UserApp-Entwicklung" hinzugefügt) |
(Persönliche Anrede entfernt, Nutzer => Mitglied) |
||
Zeile 1: | Zeile 1: | ||
== Einleitung == | == Einleitung == | ||
In diesem Tutorial | In diesem Tutorial lernt man, wie man eine grafische Oberfläche in der UserApps verwenden kann, um z. B. grafische Spiele für Knuddels zu programmieren. Man sollte schon einmal etwas mit HTML und JavaScript gemacht haben, um folgen zu können. | ||
== Der Server == | == Der Server == | ||
Der Server-Code | Der Server-Code der UserApp steht in der '''main.js'''. Wenn man nur in der '''main.js''' programmiert, läuft der ganze Code der UserApp ausschließlich auf den Servern von Knuddels.<br> | ||
Damit kann man zwar schon viel machen, aber für mehr Interaktionsmöglichkeiten | Damit kann man zwar schon viel machen, aber für mehr Interaktionsmöglichkeiten braucht man eine grafische Oberfläche. | ||
== Der Client == | == Der Client == | ||
Der Code für den Client befindet sich im '''www'''-Unterordner | Der Code für den Client befindet sich im '''www'''-Unterordner der UserApp. | ||
Den Einstieg bildet eine HTML-Datei, die | Den Einstieg bildet eine HTML-Datei, die man nennen kann, wie man will. Dort kann man dann auch JavaScript-Dateien einbinden, um Code auf dem Gerät des Besuchers auszuführen. | ||
Die Struktur | Die Struktur der UserApp könnte dann so aussehen: | ||
<!-- | <!-- | ||
Zeile 57: | Zeile 57: | ||
</pre> | </pre> | ||
Während der Entwicklung | Während der Entwicklung wird man allerdings oft Änderungen an dem Script machen. Da Knuddels das Script zwischenspeichert, wenn man es einfach mit dem '''<script>'''-Tag einbindet, werden die Änderungen oft nicht übernommen. Um Knuddels dazu zu zwingen immer die aktuellste Version des Scripts zu laden, muss man das Knuddels stattdessen mit [https://developer.knuddels.de/docs/classes/Client.html#method_includeJS Client.includeJS()] mitteilen: | ||
<!-- | <!-- | ||
Zeile 88: | Zeile 88: | ||
=== AppContent senden === | === AppContent senden === | ||
Die HTML-Datei und der restliche Inhalt des '''www'''-Unterordners wird [https://developer.knuddels.de/docs/classes/AppContent.html AppContent] genannt. Das ist die grafische Oberfäche | Die HTML-Datei und der restliche Inhalt des '''www'''-Unterordners wird [https://developer.knuddels.de/docs/classes/AppContent.html AppContent] genannt. Das ist die grafische Oberfäche der UserApp.<br> | ||
Der AppContent erscheint aber nicht automatisch bei dem Besucher | Der AppContent erscheint aber nicht automatisch bei dem Besucher des Channels! Man muss den AppContent erst an den Besucher (den Client) senden. | ||
In der Regel macht man das direkt wenn der Besucher den Channel betritt, also in '''App.onUserJoined''': | In der Regel macht man das direkt wenn der Besucher den Channel betritt, also in '''App.onUserJoined''': | ||
Zeile 119: | Zeile 119: | ||
Hinweis: [https://developer.knuddels.de/docs/classes/HTMLFile.html new HTMLFile()] sucht die angegebene Datei im '''www'''-Unterordner. | Hinweis: [https://developer.knuddels.de/docs/classes/HTMLFile.html new HTMLFile()] sucht die angegebene Datei im '''www'''-Unterordner. | ||
'''Damit ist dieses Tutorial eigentlich fertig:''' | '''Damit ist dieses Tutorial eigentlich fertig:''' Die Besucher sehen jetzt eine grafische Oberfläche, wenn sie den Channel betreten und man kann wie auf Webseiten Scripts einbinden. Ein paar wichtige Hinweise kommen aber noch!<br> | ||
<br> | <br> | ||
Der AppContent kann verschiedene '''ViewModes''' annehmen, je nachdem welche Methode | Der AppContent kann verschiedene '''ViewModes''' annehmen, je nachdem welche Methode man verwendet: | ||
* '''Overlay''' mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_overlayContent AppContent.overlayContent()] | * '''Overlay''' mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_overlayContent AppContent.overlayContent()] | ||
Zeile 130: | Zeile 130: | ||
<br> | <br> | ||
'''Tipp:''' Nicht alle Geräte können jeden '''ViewMode''' anzeigen. Daher ist es gute Praxis, wenn | '''Tipp:''' Nicht alle Geräte können jeden '''ViewMode''' anzeigen. Daher ist es gute Praxis, wenn man mit [https://developer.knuddels.de/docs/classes/User.html#method_canSendAppContent User.canSendAppContent()] entscheidet, welchen AppContent man sendet: | ||
'''Beispiel:''' | '''Beispiel:''' | ||
Zeile 186: | Zeile 186: | ||
=== Events senden === | === Events senden === | ||
Der Code auf dem Server und der Code auf dem Client laufen jetzt praktisch unabhängig voneinander. Meistens ist es aber hilfreich, wenn Server und Client miteinander kommunizieren können. | |||
==== Client → Server ==== | ==== Client → Server ==== | ||
''' Beispiel:''' Wenn | ''' Beispiel:''' Wenn das Mitglied auf der grafischen Oberfläche einen Knopf drückt, soll der AppBot eine öffentliche Nachricht in den Channel schreiben.<br> | ||
Man kann aber nur von der '''main.js''' (also vom Server aus) Chat-Nachrichten schicken. [https://developer.knuddels.de/docs/classes/BotUser.html#method_sendPublicMessage BotUser.sendPublicMessage()] funktioniert im Client nicht.<br> | |||
Der Client muss also dem Server mitteilen, dass | Der Client muss also dem Server mitteilen, dass das Mitglied einen Button gedrückt hat. Das ist mit [https://developer.knuddels.de/docs/classes/Client.html#method_sendEvent Client.sendEvent()] möglich: | ||
<pre> | <pre> | ||
Zeile 238: | Zeile 238: | ||
''' Beispiel:''' In der '''main.js''' wird eine zufällige Zahl generiert. Diese Zahl soll an alle Besucher des Channels geschickt werden, sodass diese dann in der HTML-UI angezeigt werden kann.<br> | ''' Beispiel:''' In der '''main.js''' wird eine zufällige Zahl generiert. Diese Zahl soll an alle Besucher des Channels geschickt werden, sodass diese dann in der HTML-UI angezeigt werden kann.<br> | ||
Mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_sendEvent AppContent.sendEvent()] | Mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_sendEvent AppContent.sendEvent()] kann man ein Event an alle Besucher schicken, bei denen dieser AppContent aktiv ist: | ||
<pre> | <pre> | ||
Zeile 245: | Zeile 245: | ||
</pre> | </pre> | ||
Im Client | Im Client kann man mit [https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener Client.addEventListener()] auf die Events vom Server reagieren: | ||
<!-- | <!-- | ||
Zeile 269: | Zeile 269: | ||
==== Server → ein bestimmter Client ==== | ==== Server → ein bestimmter Client ==== | ||
'''Beispiel:''' | '''Beispiel:''' Man wählt einen Besucher zufällig aus und möchte, dass sich bei diesem Besucher die Farbe der HTML-UI ändert.<br> | ||
Dazu | Dazu muss man vom Server aus (also in der '''main.js''') diesem Client ein Event senden.<br> | ||
Man kann aber nicht einfach ''User.sendEvent()'' aufrufen (diesen Befehl gibt es nicht). Eine UserApp kann nämlich verschiedene '''ViewModes''' auf einmal verwenden (sogenannte '''AppContentSessions'''). Man muss der API also sagen, an welche '''AppContentSession''' man das Event senden möchte.<br> | |||
Wenn | Wenn man weiß, welchen '''ViewMode''' der Besucher verwendet (z.B. weil man sowieso immer nur ein Popup sendet), kann man einfach mit dem Befehl [https://developer.knuddels.de/docs/classes/User.html#method_getAppContentSession User.getAppContentSession] die AppContentSession erhalten und dann das Event senden. '''Beispiel:''' | ||
<pre> | <pre> | ||
Zeile 283: | Zeile 283: | ||
<br> | <br> | ||
Wenn | Wenn der Client allerdings gleichzeitig mehrere aktive '''AppContentSessions''' haben könnte (z.B. eine Headerbar und ein Popup), kann man eine Liste aller aktiven AppContentSessions eines Besuchers mit [https://developer.knuddels.de/docs/classes/User.html#method_getAppContentSessions User.getAppContentSessions()] erhalten. '''Beispiel:''' | ||
<!-- | <!-- | ||
Zeile 302: | Zeile 302: | ||
</pre> | </pre> | ||
Auch hier | Auch hier kann man im Client wieder mit [https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener Client.addEventListener()] auf die Events reagieren. | ||
==== Limits ==== | ==== Limits ==== | ||
Für die Daten, die | Für die Daten, die man mit den Events zwischen Client und Server sendet, gibt es gewisse [[Limits]]. Diese Limits werden [[Limits|hier]] beschrieben. | ||
[[Kategorie:UserApp-Entwicklung]] | [[Kategorie:UserApp-Entwicklung]] |
Version vom 3. Oktober 2021, 15:52 Uhr
Einleitung
In diesem Tutorial lernt man, wie man eine grafische Oberfläche in der UserApps verwenden kann, um z. B. grafische Spiele für Knuddels zu programmieren. Man sollte schon einmal etwas mit HTML und JavaScript gemacht haben, um folgen zu können.
Der Server
Der Server-Code der UserApp steht in der main.js. Wenn man nur in der main.js programmiert, läuft der ganze Code der UserApp ausschließlich auf den Servern von Knuddels.
Damit kann man zwar schon viel machen, aber für mehr Interaktionsmöglichkeiten braucht man eine grafische Oberfläche.
Der Client
Der Code für den Client befindet sich im www-Unterordner der UserApp. Den Einstieg bildet eine HTML-Datei, die man nennen kann, wie man will. Dort kann man dann auch JavaScript-Dateien einbinden, um Code auf dem Gerät des Besuchers auszuführen.
Die Struktur der UserApp könnte dann so aussehen:
KnuddelJumper/ www/ game.html game.js player.png enemy.png main.js
Die HTML-Datei kann dann z.B. so eine Struktur haben:
<html> <head> <script src="game.js"/> </head> <body> <button>Hier klicken</button> </body> </html>
Während der Entwicklung wird man allerdings oft Änderungen an dem Script machen. Da Knuddels das Script zwischenspeichert, wenn man es einfach mit dem <script>-Tag einbindet, werden die Änderungen oft nicht übernommen. Um Knuddels dazu zu zwingen immer die aktuellste Version des Scripts zu laden, muss man das Knuddels stattdessen mit Client.includeJS() mitteilen:
<html> <head> <script> Client.includeJS("game.js"); </script> </head> <body> <button>Hier klicken</button> </body> </html>
Kommunikation zwischen Server und Client
AppContent senden
Die HTML-Datei und der restliche Inhalt des www-Unterordners wird AppContent genannt. Das ist die grafische Oberfäche der UserApp.
Der AppContent erscheint aber nicht automatisch bei dem Besucher des Channels! Man muss den AppContent erst an den Besucher (den Client) senden.
In der Regel macht man das direkt wenn der Besucher den Channel betritt, also in App.onUserJoined:
var App = (new function() { let htmlFile = new HTMLFile("game.html"); let appContent = AppContent.overlayContent(htmlFile, 640, 480); this.onUserJoined = function(user) { user.sendAppContent(appContent); } }());
Der AppContent wird so nur einmal von der App geladen und dann einfach an jeden Besucher mit User.sendAppContent() gesendet.
Hinweis: new HTMLFile() sucht die angegebene Datei im www-Unterordner.
Damit ist dieses Tutorial eigentlich fertig: Die Besucher sehen jetzt eine grafische Oberfläche, wenn sie den Channel betreten und man kann wie auf Webseiten Scripts einbinden. Ein paar wichtige Hinweise kommen aber noch!
Der AppContent kann verschiedene ViewModes annehmen, je nachdem welche Methode man verwendet:
- Overlay mit AppContent.overlayContent()
- Popup mit AppContent.popupContent()
- Headerbar mit AppContent.headerbarContent()
Tipp: Nicht alle Geräte können jeden ViewMode anzeigen. Daher ist es gute Praxis, wenn man mit User.canSendAppContent() entscheidet, welchen AppContent man sendet:
Beispiel:
var App = (new function() { let htmlFile = new HTMLFile("game.html"); let overlay = AppContent.overlayContent(htmlFile, 640, 480); let popup = AppContent.popupContent(htmlFile, 640, 480); let headerbar = AppContent.headerbarContent(htmlFile, 480); this.onUserJoined = function(user) { if (user.canSendAppContent(overlay)) { user.sendAppContent(overlay); } else if (user.canSendAppContent(popup)) { user.sendAppContent(popup); } else if (user.canSendAppContent(headerbar)) { user.sendAppContent(headerbar); } else { user.sendPrivateMessage("Die UserApp kann auf deinem Gerät leider nicht angezeigt werden."); } } }());
Events senden
Der Code auf dem Server und der Code auf dem Client laufen jetzt praktisch unabhängig voneinander. Meistens ist es aber hilfreich, wenn Server und Client miteinander kommunizieren können.
Client → Server
Beispiel: Wenn das Mitglied auf der grafischen Oberfläche einen Knopf drückt, soll der AppBot eine öffentliche Nachricht in den Channel schreiben.
Man kann aber nur von der main.js (also vom Server aus) Chat-Nachrichten schicken. BotUser.sendPublicMessage() funktioniert im Client nicht.
Der Client muss also dem Server mitteilen, dass das Mitglied einen Button gedrückt hat. Das ist mit Client.sendEvent() möglich:
Client.sendEvent("buttonPressed", {});
Dabei können noch zusätzliche Daten in Form eines JavaScript-Objekts mitgegeben werden.
Der Server kann dann in der main.js in App.onEventReceived() reagieren:
var App = (new function() { //... this.onEventReceived = function(user, type, data, appContentSession) { if (type == "buttonPressed") { let bot = KnuddelsServer.getDefaultBotUser(); bot.sendPublicMessage(user.getProfileLink()+" hat den Knopf gedrückt!"); } } }());
Server → alle Clients
Beispiel: In der main.js wird eine zufällige Zahl generiert. Diese Zahl soll an alle Besucher des Channels geschickt werden, sodass diese dann in der HTML-UI angezeigt werden kann.
Mit AppContent.sendEvent() kann man ein Event an alle Besucher schicken, bei denen dieser AppContent aktiv ist:
let randomNumber = Math.floor(10 * Math.random()); appContent.sendEvent("showNumber", {randomNumber: number});
Im Client kann man mit Client.addEventListener() auf die Events vom Server reagieren:
Client.addEventListener("showNumber", function(event) { let number = event.data.number; document.open(); document.write("Die magische Zahl heißt: "+number); document.close() });
Server → ein bestimmter Client
Beispiel: Man wählt einen Besucher zufällig aus und möchte, dass sich bei diesem Besucher die Farbe der HTML-UI ändert.
Dazu muss man vom Server aus (also in der main.js) diesem Client ein Event senden.
Man kann aber nicht einfach User.sendEvent() aufrufen (diesen Befehl gibt es nicht). Eine UserApp kann nämlich verschiedene ViewModes auf einmal verwenden (sogenannte AppContentSessions). Man muss der API also sagen, an welche AppContentSession man das Event senden möchte.
Wenn man weiß, welchen ViewMode der Besucher verwendet (z.B. weil man sowieso immer nur ein Popup sendet), kann man einfach mit dem Befehl User.getAppContentSession die AppContentSession erhalten und dann das Event senden. Beispiel:
let appContentSession = user.getAppContentSession(AppViewMode.Popup); appContentSession.sendEvent("changeColor", {red:255, green:0, blue:255});
Wenn der Client allerdings gleichzeitig mehrere aktive AppContentSessions haben könnte (z.B. eine Headerbar und ein Popup), kann man eine Liste aller aktiven AppContentSessions eines Besuchers mit User.getAppContentSessions() erhalten. Beispiel:
let appContentSessions = user.getAppContentSessions(); for (let i = 0; i < appContentSessions.length; i++) { let appContentSession = appContentSessions[i]; appContentSession.sendEvent("changeColor", {red:255, green:0, blue:255}); }
Auch hier kann man im Client wieder mit Client.addEventListener() auf die Events reagieren.
Limits
Für die Daten, die man mit den Events zwischen Client und Server sendet, gibt es gewisse Limits. Diese Limits werden hier beschrieben.