Hauptinhalt
Programmierung
Interaktive Szenen
Jetzt wo wir wissen, wie man schicke animierte Szenen gestaltet, kümmern wir uns noch um die andere Art von nicht-statischen Szenen: solche die auf Nutzerinteraktion reagieren. Zum Beispiel wollen wir eine Szene zeichnen, bei der Winston Babies bekommt (natürlich nach der Rockstar-Phase) - wir wollen es dem Nutzer aber auch ermöglichen, mit einem Klick mehr Babies hinzuzufügen. Immerhin kann es in dieser Welt gar nicht genug Klein-Winstons geben, oder?
Als eigenständiges Programm würde die Szene so aussehen. Das Programm zeichnet den statischen Teil der Szene, und innerhalb von
mouseClicked
zeichnet es Bilder von Baby Winston genau dort, wo man hinklickt, wobei das bestehende Bild überlagert wird.Wie würden wir das in unser Programm aus mehreren Szenen integrieren? Also, wir würden damit beginnen, dass wir den statischen Zeichencode in eine Szenenzeichnungsfunktion
drawScene5()
packen und mouseClicked
noch eine Szenenwechselfunktion hinzufügen:var drawScene5 = function() {
currentScene = 5;
background(173, 239, 255);
fill(7, 14, 145);
textSize(39);
text("Winston has babies!", 10, 47);
...
};
mouseClicked = function() {
if (currentScene === 1) {
drawScene2();
} else if (currentScene === 2) {
drawScene3();
} else if (currentScene === 3) {
drawScene4();
} else if (currentScene === 4) {
drawScene5();
} else if (currentScene === 5) {
drawScene1();
}
};
So sieht das dann aus:
Aber wie integrieren wir jetzt die Funktion
mouseClicked
? Wir haben in unserem Code schon einmal mouseClicked
definiert, und wir können es nicht zwei Mal definieren. In JavaScript "gewinnt" die letzte Funktionsdefinition und überschreibt damit die vorhergehenden Definitionen. Das bedeutet, dass wir einen guten Ort finden müssen, an dem wir die Zeile zum Zeichnen des Babys in der bestehenden mouseClicked
unterbringen können. Es gibt hier unterschiedliche Möglichkeiten:1. Wir könnten die Zeile an den Anfang der Funktion stellen:
mouseClicked = function() {
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
...
};
Dann wird sie JEDES Mal aufgerufen, wenn der Nutzer mit der Maus klickt, selbst wenn wir nicht in der Szene sind, wo Winston Babys bekommt (und es wäre komisch, wenn Baby-Winston selbst Babys hätte). Nicht gut.
2. Wir könnten die Zeile in den If-Block
currentScene === 4
packen:mouseClicked = function() {
if (currentScene === 1) {
drawScene2();
} else if (currentScene === 2) {
drawScene3();
} else if (currentScene === 3) {
drawScene4();
} else if (currentScene === 4) {
drawScene5();
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
} else if (currentScene === 5) {
drawScene1();
}
};
Dort rufen wir immerhin auch
drawScene5()
auf, und die Babys sollen ja der fünften Szene hinzugefügt werden. Aber denk mal genauer nach: Das würde bedeuten, dass wir jedes Mal ein zusätzliches Baby zeichnen würden, wenn wir die Szene zeichnen. Außerdem würden dann nie noch mehr Babys gezeichnet werden, weil currentScene
auf 5 gesetzt würde und der Code in diesem If-Block nicht mehr ausgeführt werden würde.3. Wir können die Zeile in den If-Block
currentScene === 5
packen:mouseClicked = function() {
if (currentScene === 1) {
drawScene2();
} else if (currentScene === 2) {
drawScene3();
} else if (currentScene === 3) {
drawScene4();
} else if (currentScene === 4) {
drawScene5();
} else if (currentScene === 5) {
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
drawScene1();
}
};
Das würde bedeuten, dass wir erst mit dem ersten Klick nach dem ersten Zeichnen der Szene die Babys zeichnen würden. Aber wie aus der Zeile danach zu erkennen ist, würde das Baby sofort durch die erste Szene ersetzt werden.
Hier bemerken wir einen fatalen Fehler bei unserer Idee, die Baby-Klick-Szene in unsere Szenen integrieren zu wollen: Wir verwenden genau dieselbe Interaktion – einen Mausklick auf eine beliebige Stelle auf dem Bildschirm – sowohl zum Szenenwechsel als auch zur Interaktion innerhalb der Szene. Nun stehen wir wirkich vor einem Rätsel und müssen zur Integration der Szene über drastischere Maßnahmen nachdenken.
4. Wir könnten das Neuzeichnen der Szene 1 unterbrechen und dem Nutzer mitteilen, dass er das Programm selbst neu starten muss. Das würde sicherlich funktionieren, aber nur dann, wenn unsere durch Klicken gesteuerte Szene wirkich die letzte ist. Was wäre, wenn wir diese Szene schon früher einbauen wollten? Dann würde unsere Lösung scheitern.
5. Wir könnten eine andere Interaktionsart verwenden – wie etwa
mouseDragged.
Das würde funktionieren, weil Ziehen nicht gleichzeitig auch ein Klick-Ereignis erzeugt. Wir müssen allerdings prüfen, dass currentScene === 5
erfüllt ist, damit nicht auch in anderen Szenen Babys gezeichnet werden:mouseDragged = function() {
if (currentScene === 5) {
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
}
};
Probiere es unten aus und achte darauf, das Ziehen auf der letzen Szene auszuführen:
Das funktioniert also irgendwie, obwohl ich mir Sorgen über die vielen Babys mache, mit denen Winston am Ende dasteht. Allgemein ist es keine optimale Lösung, weil wir so nur Szenen gestalten können, die nicht auf Mausklicks reagieren. Wenn wir nicht mit dieser Einschränkung leben möchten, muss es einen besseren Weg geben.
Was wäre, wenn wir stattdessen die Mausklicks nach dem Ort unterscheiden könnten, so dass ein Klick an einer Stelle einen Szenenwechsel auslöst und Klicks an einer anderen Stelle für die Interaktion innerhalb der Szene verwendet werden können? Du weißt schon, wie bei einem Button! Tatsächlich wird das Problem bei vielen Programmen mit mehreren Szenen auf diese Art gelöst, und deshalb besprechen wir das als Nächstes.
Willst du an der Diskussion teilnehmen?
Noch keine Beiträge.