jQuery und das Canvas-Element

Simon says
Kommentare

Die Angabe von Start- und Endwinkel wird in Radiant vorgenommen, was für Nicht-Mathematiker nicht gerade intuitiv erscheint. In Abbildung 2 sehen wir die Werte für die vier Himmelsrichtungen: 0 im Osten,

Die Angabe von Start- und Endwinkel wird in Radiant vorgenommen, was für Nicht-Mathematiker nicht gerade intuitiv erscheint. In Abbildung 2 sehen wir die Werte für die vier Himmelsrichtungen: 0 im Osten, PI/2 im Süden, PI im Westen und PI*1.5 im Norden. Wird der letzte Parameter von arc() auf true gesetzt, verläuft die Richtung gegen den Uhrzeigersinn und die Werte für Norden und Süden werden getauscht. Wer doch lieber mit den „herkömmlichen“ Grad, anstelle von Radiant arbeiten will, kann diese mit einer einfachen Formel umrechnen: Radiant = Grad * PI/180.

Abb. 2: Zeichnen von Kreissegmenten mit Abb. 2: Zeichnen von Kreissegmenten mit „arc()“ (Vergrößern)

Einfacher machen wir es uns beim Zeichnen der Spielfeldtasten über die Funktion buildButton(), wo wir mit Bézierkurven arbeiten; allerdings brauchen wir hier noch ein paar andere Dinge:

context.translate(translation.x, translation.y);
context.rotate(rotation * Math.PI / 180);
context.fillStyle = color;
context.beginPath();
context.moveTo(0, 200);
context.quadraticCurveTo(22, 22, 200, 0);
context.lineTo(200, 110);
context.quadraticCurveTo(122, 122, 110, 200);
context.lineTo(0, 200);
context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
context.shadowBlur = 10;
context.shadowColor = 'black';
context.fill();
context.closePath();

Da wir diese Funktion zum Zeichnen aller vier Teile verwenden wollen, müssen wir die gezeichnete Form jeweils um das Mehrfache von 90 Grad drehen. Um dies zu erreichen, rotieren wir per translate() den gesamten Koordinatenraum (wie gesagt, einzelne Pfade sind nicht auswählbar). Um dennoch alle vier Teile an derselben Position zeichnen zu können, muss jedoch zuerst noch der Mittelpunkt (also die Werte 0,0 für x,y) verschoben werden. Standardmäßig ist dieser in der linken oberen Ecke angesiedelt; wer hier noch die Zeichnungen aus dem Matheunterricht im Kopf hat, sei gewarnt: Die positive y-Achse verläuft im Canvas abwärts statt aufwärts.

Um nun die Konturen der Tasten zu zeichnen, verwenden wir neben lineTo() die Methode quadraticCurveTo(). Ihr übergeben wir nicht nur einen Start- und Endpunkt, sondern auch einen „Kontrollpunkt“. Man könnte sagen, die gezeichnete Linie „krümmt sich dem Kontrollpunkt entgegen“ und über den Abstand des Kontrollpunktes von der Linie steuern wir die Stärke der Krümmung. Abbildung 3 macht dies anschaulich.

Abb. 3: Zeichnen einer Spieltaste über quadraticCurveTo()Abb. 3: Zeichnen einer Spieltaste über quadraticCurveTo() (Vergrößern)

Wie wir in der Tabelle weiter oben gesehen haben, gibt es für die Zeichnung gekrümmter Linien noch eine weitere Methode: bezierCurveTo(). Die Bezeichnungen sind hier etwas irreführend, da beide Funktionen so genannte Bézierkurven zeichnen, wobei mit bzierCurveTo() eine „kubische“ Bézierkuve erstellt wird, die im Gegensatz zur quadratischen mit zwei Kontrollpunkten arbeitet, wodurch die Krümmung weiter beeinflusst werden kann. Für beide Funktionen gilt jedoch, dass es relativ schwierig ist, einen Pfad rein aus dem Kopf heraus zu erstellen, es empfiehlt sich daher, diese erst in einem Vektorzeichenprogramm vorzuzeichnen. Wer genau hinsieht, wird bei der Verwendung der Bézierkurve für die Tastenkontur noch eine kleine Unschönheit bemerken: die Krümmung der Kanten stimmt nicht exakt mit der Kreiskontur der umgebenden Hintergrundfläche überein – mit Bézierkurven lassen sich nur schwer Kreisformen zeichnen, und um uns der Idealform eines Kreises anzunähern wären wesentlich mehr Kurven erforderlich. Das soll uns jedoch nicht weiter stören – es gibt nichts, dass sich nicht noch besser machen ließe.

Der Spielablauf – Interaktion und Animation

Unser Spielfeld ist vorbereitet – kommen wir nun zum Spielablauf. Für Interaktion und Animation können wir nun wieder auf jQuery zurückgreifen. Das Erste, was wir brauchen werden, ist eine Möglichkeit, mit dem Spielfeld zu interagieren – für das simple Spielprinzip von Simon müssen wir lediglich auf die vier Tasten drücken können, benötigen also weder Tastatureingaben noch Informationen zu Mausposition oder Ähnlichem. Wir könnten nun also hergehen und auf jede der Tasten einen Click-Listener setzen (also eine Funktion, die bei Mausklick ausgeführt wird) – wir wollen es uns aber einfach machen, und wenden die so genannte Event-Delegation-Technik an. Anstelle von mehreren Listenern setzen wir nur einen einzigen, und zwar auf den Container unseres Spiels, $simon. Da in JavaScript-Events von einem Element stets an sein Elternelement weitergereicht werden (bis sie schlussendlich beim document-Objekt ankommen), brauchen wir also nur zu warten, bis ein Klick auf eine der Tasten unseren Container $simon erreicht und die als Handler definierte Funktion ausgeführt wird:

$simon.click(function(e){
    if(!disableUI) {
        if(status == 'idle') initSequence();
        if(status == 'user') clickedButton($(e.target));
    }
});

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -