Tutorial: Eine eigene Uhr im Channel

In unserem heutigen Blogbeitrag geht es um die Darstellung einer kleinen Uhr. Immer wieder wurde bei den Entwicklerrunden mitgeteilt, dass es immer noch für Anfänger schwierig ist, zu verstehen wie man eine User App in ein separates Fenster bekommt. Diese Fragen möchte ich mit dem heutigen Blogbeitrag klären.

Aufgabenstellung:
TippWir möchten eine User App in einem OverlayFenster und in einem PopupFenster darstellen. Hierbei handelt es sich um die selbe User App, bei der sich lediglich die Darstellungsform ändert.

 

Damit wir eine User App überhaupt darstellen können, benötigen wir natürlich mehrere Sachen. Um das ganze nicht unnötig aufzublähen, begrenze ich mich hier auf ein Minimum, damit nicht unnötiger Schnickschnack uns ablenkt.

Wir benötigen für die Darstellung also unbedingt folgendes:

  • app.config
  • main.js
  • www-Ordner
    • HTML-Datei, die unsere User App verkörpert

app.config

Zum Thema app.config brauche ich nicht mehr wirklich viel schreiben. Alles bezüglich der Konfiguration einer User App wurde bereits von mir in diesem sowie in diesem Beiträgen erklärt.

main.js

Neben der app.config ist auch die main.js eine sehr wichtige Datei, die jede User App benötigt. In dieser main.js müssen alle wichtigen Dateien die für eine User App gebraucht werden, enthalten sein. Bei kleineren User Apps, reicht es, wenn man alles in die main.js packt. Wenn eine User App allerdings umfangreicher wird, sollte man sich überlegen ob es nicht sinnvoll ist, einige Bestandteile der User Apps auszulagern (in separate JavaScript-Dateien) und diese einfach in der main.js mit Hilfe von require(‚PFAD/DATEINAME.js‘); einmalig mit zuladen.

www-Ordner

Ebenfalls ein sehr wichtiger Bestandteil von User Apps ist der www-Ordner. Diesen Ordner braucht es nicht zwangsläufig. Solltet ihr euch entscheiden eine User App zu bauen, die lediglich mit Text auskommt und kein Overlay benötigt, so kann dieser Ordner entfallen. In 90% der Fällen gibt es aber immer Grafiken, Sounds oder HTML-Dateien die eine User App erst richtig lebendig machen – und diese Dateien kommen in diesen Ordner. Viele Funktionen der Knuddels-API greifen automatisch auf diesen Ordner zu. Allerdings nur dann, wenn dieser Ordner auch wirklich nur www heißt.

HTML-Datei

Das letzte wichtige, für unsere User App ist die HTML-Datei. Diese Datei ist auch nur dann notwendig, wenn wir wie bei unserer jetzigen Aufgabenstellung eine User App haben, die als Popup oder Overlay dargestellt werden soll. Der Namen einer HTML-Datei ist erstmal irrelevant – ihr solltet aber darauf achten, dass ihr sinnvolle Namen verwendet die euch auch zu einem späteren Zeitpunkt auf die Sprünge helfen was sich hinter dieser HTML-Datei versteckt. In unserem Beispiel habe ich die Datei einfach home.html genannt.


Nachdem wir geklärt haben, was wir unbedingt benötigen, kann es auch schon los gehen!

  • Als erstes verbinden wir uns mit dem FTP-Programm unserer Wahl mit dem FTP-Server auf dem unsere User Apps geladen werden. Wie man sich das FTP-Programm einrichtet, könnt ihr im Entwickler-Wiki nachlesen.
  • Wenn das erledigt ist, erstellt ihr einen neuen Ordner. Diesen nennt ihr wie ihr wollt. Ich habe mir angewöhnt, dass ich den Ordner so nenne, wie ich später auch die User App benenne. Lediglich Leerschritte lasse ich weg. In meinem Fall soll die User App BlogClock heißen. Also erstelle ich auch einen Ordner mit diesem Namen.
  • Wenn das gemacht wurde, erstelle ich eine app.config in der ich ebenfalls den appName als BlogClock definiere. Unserem Beispiel sollte nun wie folgt aussehen:
appName = BlogClock
appVersion = 1.0
mayBeInstalledBy.1 = *
autoUpdate = knuddelsDEV
  • Als nächstes kümmern wir uns um die Hauptdatei – der main.js. Da wir eine sehr kleine User App schreiben, habe ich mich entschlossen alle notwendigen API-Funktionen direkt in diese Datei rein zu schreiben. Dafür überlege ich mir eben kurz, was wir machen möchten und packe die notwendigen API-Funktionen dementsprechend in die main.js.
Was soll unsere App überhaupt können?
Tipp– Mitteilen, dass die User App wieder funktioniert.
– Bei Userbetritt die User App automatisch im Overlay anzeigen
– Bei einem Chatcommand die Uhr zusätzlich in einem Popup öffnen.

Wie ihr seht, haben wir 3 Aufgaben, die wir abarbeiten müssen und überlegen sollten, welche Methoden der Knuddels-API für uns nützlich sind und diese Aufgaben ermöglichen.

Damit wir öffentlich mitteilen können, dass die User App wieder funktionsfähig ist, benötigen wir die API-Methode onAppStart(), für das Darstellen der Uhr bei einem Channelbeitritt, benötigen wir die onUserJoined()-Methode und für das Ausführen von selbst erstellten Chatbefehlen, benötigen wir die Eigenschaft chatCommands(). Diese packen wir nun auch schon mal in die main.js.

App = {};
App.onAppStart = function(user){};
App.onUserJoined = function(user){};
App.chatCommands = {};

Jetzt haben wir zwar schon die Methoden und Eigenschaften erstellt, doch mit Leben ist die User App noch nicht gefüllt. Da wir öffentlich mitteilen möchten, dass die User App bereit ist, müssen wir dafür dem Bot ermöglichen eine öffentliche Nachricht zu schreiben. Hierfür definieren wir einmal den BotUser als Variable bot global und geben die Meldung vor, die erscheinen soll (Zeile 4+5).

Hinweis: Jetzt, da wir die Variable bot als globale Variable definiert haben – können wir bot jederzeit im serverseitigen Script verwenden!

Die nächste Aufgabe die wir abzuarbeiten haben, ist die Darstellung der User App als Overlay, wenn ein User den Channel betritt. Hierfür nehmt ihr am besten diesen Blogbeitrag zur Hilfe. Ebenfalls mit Hilfe des eben genannten Blogbeitrages fügen wir nun noch ein Chatbefehl hinzu, dieser sollte am besten openclock lauten. Hierbei müsst ihr allerdings darauf achten, dass wir ein Popup öffnen möchten. Dazu müsst ihr lediglich AppContent.overlayContent(….) umändern in AppContent.popupContent(…).

 
App = {};
App.onAppStart = function(user){
    bot = KnuddelsServer.getDefaultBotUser();
    bot.sendPublicMessage('Die App wurde erfolgreich gestartet.');
};
/* Spieler betritt den Raum */
App.onUserJoined = function(user){
    var htmlFile = new HTMLFile('home.html', {});
    appContentEdit = AppContent.overlayContent(htmlFile, 430, 430);
    if(user.canSendAppContent(appContentEdit)===true){
        user.sendAppContent(appContentEdit);
    }
};
/* Funktionen die verwendet werden können */
App.chatCommands = {
    openclock: function(user, params){
        var htmlFile = new HTMLFile('home.html', {});
        appContentEdit = AppContent.popupContent(htmlFile, 430, 430);
        if(user.canSendAppContent(appContentEdit)===true){
            user.sendAppContent(appContentEdit);
        }
    }
}
  • CHACKA! Wir haben nun schon den größten Teil unserer Arbeit hinter uns gebracht. Alles was der KnuddelsServer für unsere User App zu erledigen hat, ist soweit erledigt. Jetzt geht es aber noch darum, auch etwas anzeigen zu lassen. Wenn ihr jetzt eure User App starten würdet und die Befehle verwendet, würde folgendes erscheinen:

Datei nicht gefunden - FehlermeldungJetzt nur nicht in Panik geraten. Wir haben ja noch gar nicht die home.html angelegt! Daher kann der Server diese auch noch nicht anzeigen. Das erledigen wir jetzt.

  • Wir erstellen eine neue Datei und nennen diese home.html. Da wir eine Uhr haben möchten, die in diesem Fenster angezeigt wird, müssen wir erstmal schauen wo wir eine Uhr herbekommen. Ihr könnt natürlich eine selbst erstellen – oder aber z.B. von diversen Tutorialseiten eine übernehmen. Ich habe mich für eine Uhr von der Seite w3school.com entschieden. Das komplette Tutorial zu dieser Uhr, beginnt hier und könnt ihr zum besseren Verständnis natürlich auch selbst nochmal durcharbeiten.
 
<!DOCTYPE html>
<html>
<head>
    <title>BlogClock</title>
</head>
<body>
<style type="text/css">
<!--
    body, html, canvas {
       background: #ccc;
       padding: 0px;
       margin:  0px;
    }
-->
</style>
<canvas id="canvas" width="430" height="430">
</canvas>

<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90
setInterval(drawClock, 1000);

function drawClock() {
  drawFace(ctx, radius);
  drawNumbers(ctx, radius);
  drawTime(ctx, radius);
}

function drawFace(ctx, radius) {
  var grad;
  ctx.beginPath();
  ctx.arc(0, 0, radius, 0, 2*Math.PI);
  ctx.fillStyle = '2e2e2e';
  ctx.fill();
  grad = ctx.createRadialGradient(0,0,radius*0.95, 0,0,radius*1.05);
  grad.addColorStop(0, '#000');
  grad.addColorStop(0.5, '#fff');
  grad.addColorStop(1, '#000');
  ctx.strokeStyle = grad;
  ctx.lineWidth = radius*0.1;
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI);
  ctx.fillStyle = '#777';
  ctx.fill();
}

function drawNumbers(ctx, radius) {
  var ang;
  var num;
  ctx.font = radius*0.15 + "px arial";
  ctx.textBaseline="middle";
  ctx.textAlign="center";
  for(num = 1; num < 13; num++){
    ang = num * Math.PI / 6;
    ctx.rotate(ang);
    ctx.translate(0, -radius*0.85);
    ctx.rotate(-ang);
    ctx.fillText(num.toString(), 0, 0);
    ctx.rotate(ang);
    ctx.translate(0, radius*0.85);
    ctx.rotate(-ang);
  }
}

function drawTime(ctx, radius){
    var now = new Date();
    var hour = now.getHours();
    var minute = now.getMinutes();
    var second = now.getSeconds();
    //hour
    hour=hour%12;
    hour=(hour*Math.PI/6)+
    (minute*Math.PI/(6*60))+
    (second*Math.PI/(360*60));
    drawHand(ctx, hour, radius*0.5, radius*0.07);
    //minute
    minute=(minute*Math.PI/30)+(second*Math.PI/(30*60));
    drawHand(ctx, minute, radius*0.8, radius*0.07);
    // second
    second=(second*Math.PI/30);
    drawHand(ctx, second, radius*0.9, radius*0.02);
}

function drawHand(ctx, pos, length, width, type) {
    ctx.beginPath();
    ctx.lineWidth = width
    if(type=='sekunde'){
        ctx.strokeStyle = '#ff0000';
    } else if(type=='minute'){
        ctx.strokeStyle = '#00ff00';
    } else {
        ctx.strokeStyle = '#0000ff';
    }
    ctx.lineCap = "round";
    ctx.moveTo(0,0);
    
    ctx.rotate(pos);
    ctx.lineTo(0, -length);
    ctx.stroke();
    ctx.rotate(-pos);
}
</script>

</body>
</html>

Wenn ihr das alles erledigt habt, habt ihr eure erste eigene User App programmiert und könnt jetzt nachvollziehen, wie die verschiedenen AppContent geöffnet werden. Solltet ihr Fragen oder Probleme zu diesem Tutorial haben, so wendet euch per /m an mich im Chat oder schreibt es unten in die Kommentare.

Download:
Du kannst auch das ganze Tutorial als Download im Entwickler-Wiki finden. Klicke dazu einfach nur hier. Der Download sollte automatisch starten.

 

2 Gedanken zu “Tutorial: Eine eigene Uhr im Channel

  1. Ich würde empfehlen, das Öffnen des UIs in eine extra Funktion auszulagern, die als Parameter die Information bekommt, ob die Uhr um Popup oder als Overwatch geöffnet werden soll. Damit vermeidet man doppelte Code und spart sich einen unnötigen Mehraufwand, wenn man die Uhr beispielsweise vergrößern oder verkleinern möchte.

    Gefällt mir

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s