Wenn, dann
Bedingungen, Abprall am Rand und der erste Punktestand.
Das kannst du danach
0 von 5 abgehakt- Du kannst mit if eine Entscheidung in dein Programm einbauen.
- Du kennst die Vergleichsoperatoren und weißt, warum == etwas anderes ist als =.
- Du kannst mit else und else if zwischen mehreren Fällen unterscheiden.
- Du kannst Bedingungen mit && und || verknüpfen.
- Du lässt den Ball am Rand abprallen und zeigst einen Punktestand an.
Melde dich an, um deinen Stand zu speichern.
Der Ball ist weg
Am Ende des letzten Kapitels blieb eine Frage offen. Dein Ball rollt nach rechts — und dann ist er fort. Er kommt nicht wieder.
Schau auf die Zahl oben links. Sie wächst und wächst — 400, 900, 5000. Der Ball ist längst nicht mehr zu sehen, aber das Programm rechnet stur weiter. Es weiß ja gar nicht, dass da ein Rand ist.
Und genau das ist der Punkt: Bisher macht dein Programm bei jedem Bild exakt dasselbe. Es kann nicht auf die Lage reagieren, weil ihm die Möglichkeit fehlt, überhaupt etwas zu entscheiden.
Diese Möglichkeit heißt if — auf Deutsch „wenn".
Die Entscheidung: if
Ein if stellt eine Frage, auf die es nur zwei Antworten gibt: ja oder
nein. Lautet die Antwort ja, wird der Block in den geschweiften Klammern
ausgeführt. Lautet sie nein, wird er übersprungen.
if (x > 300) {
// passiert nur, WENN x größer als 300 ist
}
Drei Dinge gehören dazu, und alle drei sind Pflicht:
- das Wort
if - die Frage in runden Klammern
- der Block in geschweiften Klammern
Der Ball kehrt um
Jetzt reparieren wir den Ball damit. Die Idee ist verblüffend einfach: Wenn er rechts ankommt, drehen wir seine Richtung um.
float x = 40;
float tempo = 3;
void setup() {
size(360, 170);
}
void draw() {
background(250);
noStroke();
fill(70, 130, 220);
circle(x, 100, 40);
x = x + tempo;
if (x > width) {
tempo = -tempo;
}
}Die Zeile tempo = -tempo; ist der ganze Trick.
Erst überlegen
In der Zeile x = x + tempo; wird weiterhin ADDIERT — es steht ja immer noch ein Plus da. Wie kann der Ball dann rückwärts laufen?
Beide Ränder
Links läuft er allerdings immer noch hinaus. Kein Wunder — dafür haben wir ja auch keine Frage gestellt. Also stellen wir eine zweite:
float x = 40;
float tempo = 3;
void setup() {
size(360, 170);
}
void draw() {
background(250);
noStroke();
fill(70, 130, 220);
circle(x, 100, 40);
x = x + tempo;
if (x > width) {
tempo = -tempo;
}
if (x < 0) {
tempo = -tempo;
}
}Der Ball läuft jetzt endlos hin und her. Das ist — ohne Übertreibung — der Kern von Pong, Breakout und jedem Jump-and-Run der Welt.
Womit man vergleicht
In der Klammer steht eine Frage, die nur wahr oder falsch sein kann. Dafür gibt es sechs Vergleiche:
| Zeichen | Frage | Beispiel |
|---|---|---|
> | größer als | x > 300 |
< | kleiner als | x < 0 |
>= | größer oder gleich | x >= 300 |
<= | kleiner oder gleich | x <= 0 |
== | gleich | leben == 0 |
!= | ungleich | leben != 0 |
Fünf davon sind selbsterklärend. Der sechste ist die häufigste Fehlerquelle im ganzen Kapitel.
Bei boolean-Variablen brauchst du gar keinen Vergleich. Die Variable
ist ja schon wahr oder falsch:
boolean laeuft = true;
if (laeuft) { // schön
}
if (laeuft == true) { // umständlich, aber nicht falsch
}
Und für „wenn nicht" gibt es das Ausrufezeichen:
if (!laeuft) { // wenn laeuft NICHT wahr ist
}
Warum der Ball halb im Rand steckt
Schau dir den Abprall oben genau an. Der Ball ragt ein Stück über den Rand hinaus, bevor er umkehrt.
Erst überlegen
Warum ragt der Ball über den Rand hinaus, obwohl die Bedingung x > width doch genau am Rand zuschlägt?
float x = 60;
float tempo = 3;
float radius = 20;
void setup() {
size(360, 170);
}
void draw() {
background(250);
// Zwei Linien, damit man den Rand sieht
stroke(200);
line(radius, 0, radius, height);
line(width - radius, 0, width - radius, height);
noStroke();
fill(70, 130, 220);
circle(x, 100, radius * 2);
x = x + tempo;
if (x > width - radius) {
tempo = -tempo;
}
if (x < radius) {
tempo = -tempo;
}
}Jetzt berührt der Ball den Rand genau und kehrt dort um. Der Unterschied sieht winzig aus, aber bei Pong entscheidet er darüber, ob der Ball sichtbar am Schläger abprallt oder halb in der Wand verschwindet.
Sonst: else und else if
Bisher hast du gefragt: „Wenn ja, dann tu etwas." Oft willst du aber
auch sagen, was passieren soll, wenn nicht. Dafür gibt es else:
if (punkte > 10) {
fill(80, 160, 120); // grün
} else {
fill(220, 90, 90); // rot
}
Genau einer der beiden Blöcke läuft. Nie beide, nie keiner.
Und wenn es mehr als zwei Fälle gibt, hängst du weitere Fragen dazwischen:
float x = 0;
float tempo = 3;
void setup() {
size(380, 180);
}
void draw() {
background(250);
noStroke();
if (x < width / 3) {
fill(80, 160, 120);
} else if (x < width * 2 / 3) {
fill(230, 170, 60);
} else {
fill(220, 90, 90);
}
circle(x, 95, 44);
x = x + tempo;
if (x > width || x < 0) {
tempo = -tempo;
}
}Processing arbeitet die Kette von oben nach unten ab und steigt beim
ersten Treffer aus. Ist x kleiner als ein Drittel der Breite, wird grün
gefüllt — die anderen Fragen werden dann gar nicht mehr gestellt.
Die Reihenfolge in einer else if-Kette ist allerdings nicht egal.
Erst überlegen
Jemand mit 200 Punkten führt diese Kette aus. Was steht danach auf dem Bildschirm — und warum ist das ein Fehler?
Zwei Fragen auf einmal
Manchmal reicht eine Frage nicht. „Ist der Mauszeiger im Feld?" bedeutet in Wahrheit vier Fragen gleichzeitig: nicht zu weit links, nicht zu weit rechts, nicht zu weit oben, nicht zu weit unten.
Dafür gibt es zwei Verknüpfungen:
&&— und. Wahr, wenn beide Seiten wahr sind.||— oder. Wahr, wenn mindestens eine Seite wahr ist.
Die beiden senkrechten Striche tippst du mit AltGr + <.
void setup() {
size(380, 220);
rectMode(CENTER);
}
void draw() {
background(250);
noStroke();
fill(230);
rect(width / 2, height / 2, 160, 100);
// Alle vier Bedingungen müssen stimmen
if (mouseX > width / 2 - 80 && mouseX < width / 2 + 80
&& mouseY > height / 2 - 50 && mouseY < height / 2 + 50) {
fill(80, 160, 120);
} else {
fill(190);
}
circle(mouseX, mouseY, 26);
}Führ die Maus in das graue Rechteck. Der Punkt wird grün — aber nur, wenn wirklich alle vier Teilfragen mit ja beantwortet werden. Fällt eine davon aus, ist die ganze Bedingung falsch.
Beim Abprall oben passt dagegen || besser. Denn dort ist es egal,
welcher Rand erreicht wurde — umkehren soll er in beiden Fällen:
if (x > width - radius || x < radius) {
tempo = -tempo;
}
Das ersetzt die beiden einzelnen if-Blöcke von vorhin. Kürzer, und es
sagt genau das, was gemeint ist.
Der erste Punktestand
Jetzt fügt sich zusammen, was du in beiden Kapiteln gelernt hast. Ein
Punktestand ist nichts weiter als eine Variable, die sich etwas merkt —
plus ein if, das entscheidet, wann sie hochgezählt wird.
float x = 60;
float tempo = 4;
float radius = 18;
int punkte = 0;
void setup() {
size(380, 190);
}
void draw() {
background(250);
noStroke();
fill(70, 130, 220);
circle(x, 115, radius * 2);
x = x + tempo;
if (x > width - radius) {
tempo = -tempo;
punkte = punkte + 1;
}
if (x < radius) {
tempo = -tempo;
}
fill(40);
textSize(20);
text("Punkte: " + punkte, 16, 36);
}Beachte, wo die Variable steht: ganz oben, außerhalb von draw().
Stünde int punkte = 0; innerhalb von draw(), würde sie 60-mal pro
Sekunde auf 0 zurückgesetzt — die Falle aus dem letzten Kapitel.
Und beachte, wo hochgezählt wird: innerhalb des if-Blocks. Deshalb
passiert es nur beim Abprall und nicht bei jedem Bild.
Eine Falle lauert hier allerdings noch.
Erst überlegen
Dieser Code soll pro Mausklick einen Punkt geben. Du klickst einmal kurz — sagen wir, du hältst die Taste eine Drittelsekunde. Wie viele Punkte bekommst du?
Neue Werkzeuge
Werkzeuge für Entscheidungen
AufgabenÜbungen
Übung 3.1Level 1Stopp am Rand
Der Ball soll diesmal nicht abprallen, sondern am rechten Rand einfach stehen bleiben — und zwar so, dass er noch vollständig zu sehen ist.
Tipp: Strg + Eingabe führt den Code aus.
Übung 3.2Level 2Abprall nach unten
Der Ball fällt nach unten und verschwindet. Lass ihn zwischen oberem und unterem Rand hin und her springen.
Schaffst du es mit einem einzigen if?
Tipp: Strg + Eingabe führt den Code aus.
Übung 3.3Level 2Die Ampel
Der Kreis folgt der Maus, bleibt aber immer grau. Färbe ihn abhängig davon, in welchem Drittel der Fläche er sich befindet: links grün, in der Mitte gelb, rechts rot.
Tipp: Strg + Eingabe führt den Code aus.
Zu dieser Aufgabe gibt es bewusst keine Musterlösung. Es gibt mehrere richtige Wege — speichere deinen, dann kann er im Unterricht besprochen werden.
Übung 3.4Level 3Nur im Spielfeld
Führ die Maus über das graue Feld. Der Punkt soll grün werden, solange er sich innerhalb befindet, und sonst grau bleiben.
Tipp: Strg + Eingabe führt den Code aus.
Zu dieser Aufgabe gibt es bewusst keine Musterlösung. Es gibt mehrere richtige Wege — speichere deinen, dann kann er im Unterricht besprochen werden.
Übung 3.5Level 4Der Zähler, der nur einmal zählt
Klick einmal auf die Fläche. Der Zähler springt um zehn oder zwanzig
hoch, weil draw() die Bedingung 60-mal pro Sekunde prüft.
Sorg dafür, dass ein Klick genau einen Punkt gibt. Du brauchst dafür
eine zusätzliche boolean-Variable.
Tipp: Strg + Eingabe führt den Code aus.
Zu dieser Aufgabe gibt es bewusst keine Musterlösung. Es gibt mehrere richtige Wege — speichere deinen, dann kann er im Unterricht besprochen werden.
Übung 3.6★ SternaufgabeDer Knopf
Bau einen Knopf, der sich anfühlt wie ein echter: Er wird heller, sobald die Maus darüber liegt, und grün, solange man darauf drückt.
Tipp: Es hilft sehr, das Ergebnis der Positionsprüfung erst in einer
boolean-Variablen zu speichern. Dann bleibt die if-Kette lesbar.
Tipp: Strg + Eingabe führt den Code aus.
Sternaufgabe. Die zählt nicht zum Fortschritt — du verlierst also nichts, wenn du sie auslässt. Schaffst du sie, gibt es dafür einen Stern.
Zu dieser Aufgabe gibt es bewusst keine Musterlösung. Es gibt mehrere richtige Wege — speichere deinen, dann kann er im Unterricht besprochen werden.
Jetzt du
Dein SpielDas Spiel reagiertin der Processing-IDE
Bring deinem Spiel bei, auf seine eigenen Grenzen zu reagieren. Bau auf dem auf, was du in Kapitel 2 gemacht hast.
Aim Trainer: Das Ziel soll das Feld nie verlassen — halte es mit
constrain() drinnen. Zeig oben einen Punktestand an und lass ihn
hochzählen, wenn geklickt wird, während die Maus über dem Ziel ist.
Pong: Der Ball prallt oben und unten ab und läuft links und rechts noch hinaus. Der Schläger darf das Feld nicht verlassen. Zähle einen Punkt, sobald der Ball rechts hinausläuft.
Breakout: Der Ball prallt an drei Wänden ab — links, rechts, oben. Unten fällt er hinaus; zeig in diesem Fall „Verloren" an. Auch hier soll der Schläger im Feld bleiben.
Der Ball muss noch nicht am Schläger abprallen — das ist Kapitel 5. Arbeite in der Processing-IDE, du brauchst das Ergebnis dort weiter.
Ab jetzt lohnt sich Struktur: Im Spielgerüst findest du
einen fertigen Rahmen zum Kopieren, der Menü, Spiel und Game Over
sauber trennt. Er baut genau auf dem if auf, das du gerade gelernt
hast — und erspart dir später das große Umräumen.
Sichere deinen Code zusätzlich selbst — auf einem Stick oder in deiner Cloud — und lade ihn am Ende auch in den Moodle-Kurs hoch.
Sitzt das?
1 / 7Was steht in den runden Klammern eines if?
Was noch fehlt
Dein Programm kann jetzt entscheiden. Damit ist der Ball gezähmt, der Schläger bleibt im Feld, und ein Punktestand läuft mit.
Etwas anderes wird jetzt allerdings mühsam. Breakout braucht eine Mauer
aus Blöcken — sagen wir vier Reihen zu je zehn Stück. Das sind vierzig
rect()-Zeilen, und wenn du die Farbe ändern willst, änderst du sie
vierzig Mal.
Beim Aim Trainer sind es die Ringe deiner Zielscheibe, bei Pong die gestrichelte Mittellinie — beides hast du in Kapitel 1 noch Strich für Strich von Hand gezeichnet.
Dafür gibt es ein eigenes Werkzeug: die Schleife. Sie sagt „mach das zehnmal" — in drei Zeilen statt vierzig. Das ist das nächste Kapitel.