Unterlagen zur Veranstaltung Einführung in die Objektorientierte Programmierung Mit Processing Alexis Engelke Sommer 2012
Alexis Engelke Inhalt Level 1: Geometrie Hintergrundfarben Punkte, Linien und deren Größe Kantenglättung Umrandungsfarben Füllfarben Dreiecke, Rechtecke, Vierecke und Ellipsen als geometrische Formen Die Modi von Rechtecken und Ellipsen Level 2: Animation und Interaktion Variablen und deren Operatoren Fall-Unterscheidungen Debug-Möglichkeit durch Ausgeben Setup-Draw-Konzept Verwendung von Maus und Tastatur Verschiebungen und Drehungen Methoden und Funktionen Kontrollstrukturen Level 3: Objekte Einführung Instanzen Definition Verwendung und Interaktion Vererbung und Erweiterung Level 4: Dateien, Zeiten und Listen Listen Zeitmessungen Bilder und Texte Mathematische Funktionen Level 5: Shapes & Vertices Einfache Shapes und Vertices wird nicht vorgetragen by Alexis Engelke 2012 Seite 2
by Alexis Engelke 2012 Seite 3
Grafisch LEVEL 1 by Alexis Engelke 2012 Seite 4
by Alexis Engelke 2012 Seite 5
by Alexis Engelke 2012 Seite 6
by Alexis Engelke 2012 Seite 7
by Alexis Engelke 2012 Seite 8
by Alexis Engelke 2012 Seite 9
by Alexis Engelke 2012 Seite 10
by Alexis Engelke 2012 Seite 11
by Alexis Engelke 2012 Seite 12
by Alexis Engelke 2012 Seite 13
by Alexis Engelke 2012 Seite 14
Animiert LEVEL 2 by Alexis Engelke 2012 Seite 15
Datentypen: Ganze Zahlen (int): int i; i = 12; Gleitkomma Zahlen (float) float f = 12.3; Hinweis: Komma ist hier der Punkt Zeichen (char) char c; c = '5'; Zeichenketten (String) String s; s = "Hallo Welt"; Wahrheitswerte (Boolean) boolean b; b = false; Werte sind nur true und false! Zahlen (Ganze und Gleitkomma) + Addition i = k + 10; - Subtraktion * Multiplikation / Division % Modulo (Divisionsrest) ++ Inkrement (+1) i++ entspricht i = i + 1 -- Dekrement (-1) i-- entspricht i = i - 1 += Addition zur Variable i += 10 entspricht i = i + 10 -= Subtraktion zur Variable *= Multiplikation zur Variable /= Division zur Variable %= Modulo der Variable Zeichen + Addition zum ASCII-Wert i = k + 10; - Subtraktion vom ASCII-Wert += Addition zum ASCII-Wert des Zeichens i += 'a' entspricht i = i + 'a' -= Subtraktion vom ASCII-Wert des Zeichens Zeichenketten + Zusammenfügen s = k + "1"; += Zur Zeichenkette Anfügen s += "H" entspricht s = s + "H" Boolean && true, wenn beide Seiten true sind (Und) if (a && b) true, wenn min. eine Seite true ist (Oder) if (a b)! true, wenn der Wert false ist (Negation) if (!a) by Alexis Engelke 2012 Seite 16
by Alexis Engelke 2012 Seite 17
by Alexis Engelke 2012 Seite 18
Probiere den Code doch mal aus und wandle ihn ab! Hiermit kannst du schon eine Menge machen: Dieses Wissen reicht aus, um z.b. ein Ball-Spring-Programm oder um ein Diagramm zu zeichnen. by Alexis Engelke 2012 Seite 19
Translation und Rotation Wie sieht es aus, wenn wir gedrehte Rechtecke zeichnen wollen? Der Schlüssel zur Lösung ist die Translation (Verschiebung) und Rotation (Drehung). Der Befehl zur Translation lautet translate(xtrans, ytrans). Hiermit wird der Null-Punkt des Koordinatensystems um xtrans und ytrans verschoben. Diese Werte können auch negativ sein. Bogenmaß Winkelmaß QUARTER_PI 45 HALF_PI 90 PI 180 TWO_PI 360 Um das Koordinatensystem um seinen Nullpunkt zu drehen, gibt es die Funktion rotate(winkel), wobei der Winkel im Bogenmaß angegeben wird. Um dies umzuwandeln, kann man das auch so schreiben: rotate(radians(winkel)), wobei hier der Winkel in unserem bekannten Winkelmaß (0 bis 360 ) angegeben wird. Auch dieser Wert kann negativ sein, dies wird jedoch nicht benötigt, da -90 270 entsprechen. Die Funtkion float radians(float deg) wandelt die Winkel-Zahl deg in das radial- System um. Um Werte wieder in unser Winkel-System umzurechnen, gibt es die Funktion float degrees(float rad). Wenn man Translation und Rotation mischt, sieht dies zum Beispiel so aus: Translation Rotation In diesem Fall wurde erst eine Translation nach rechts durchgeführt, dann eine Rotation und anschließend erneut eine Translation nach rechts. Damit wir uns die Reihenfolge der Änderungen nicht merken müssen, kennt Processing zwei sehr wertvolle Methoden: pushmatrix() speichert den aktuellen Zustand, popmatrix() stellt den gespeicherten Zustand wieder her. Diese Aufrufe können auch verschachtelt werden. by Alexis Engelke 2012 Seite 20
this ist das Objekt selbst ( ich ) by Alexis Engelke 2012 Seite 21
Zur For-Schleife: Der Übergang kann auch i += 23 oder i *= 6 oder i-- oder i -= 12 heißen. Auch die sogenannte Zählvariable muss nicht i heißen (dabei ist es üblich einen Ein-Buchstaben- Namen zu nehmen). by Alexis Engelke 2012 Seite 22
Objekte LEVEL 3 by Alexis Engelke 2012 Seite 23
by Alexis Engelke 2012 Seite 24
Variablen in einer Klasse heißen Feld. Der Code der Klasse wird direkt ins Programm geschrieben. Klassen können auch andere Klassen verwenden. by Alexis Engelke 2012 Seite 25
Definition und Verwendung einer Klasse class Name { // Felder der Klasse hier! // Methoden der Klasse hier! } Durch diesen Code definieren wir eine Klasse Name. Hier ein Beispiel für eine Klasse Raumschiff: class Raumschiff { int x; int y; void setposition(int x, int y) { this.x = x; this.y = y; } void draw() { ellipse(x, y, 100, 10); rect(x + 5, y - 20, 15, 15); ellipse(x + 30, y - 20, 90, 10); rect(x - 40, y - 20, 15, 15); ellipse(x - 50, y - 15, 70, 5); } } Diese Klasse hat zwei Felder: x und y. Diese dienen zur Speicherung der Position. Darüber hinaus besitzt diese Klasse die Methoden setposition(int,int) zum Setzen der Position und eine Methode draw, die an die Stelle von (x,y) ein Raumschiff malt. Dieser Code funktioniert jedoch noch nicht, wir benötigen noch das übliche setup/draw. Dies könnte so aussehen: Raumschiff meinraumschiff; void setup() { size(400,300); stroke(255); fill(255,255,0); smooth(); meinraumschiff = new Raumschiff(); } void draw() { background(0); meinraumschiff.setposition(mousex, mousey); meinraumschiff.draw(); } In der ersten Zeile wird gesagt, dass es ein Objekt Raumschiff mit dem Namen meinraumschiff gibt, welches jedoch noch nicht initialisiert ist. In Setup wird dann ein Raumschiff erzeugt: meinraumschiff = new Raumschiff(); Ab diesem Moment steht uns das Raumschiff zur Verfügung, wir haben es instanziiert. In der Draw-Methode setzen wir das Raumschiff an die Position (x,y), in dem wir die Methode setposition aufrufen, und zeichnen es durch den Aufruf von draw. by Alexis Engelke 2012 Seite 26
Sichtbarkeit Als das Setup-Draw-Konzept eingeführt wurde, wurde gesagt, dass die Variable, die außerhalb einer Methode definiert wurde, überall sichtbar ist. Wenn wir jetzt eine Klasse definieren, gilt etwas Ähnliches: Alle Felder, die in einer Methode definiert werden, sind nach wie vor sicher. Alle Felder, die wir in einer Klasse außerhalb von Methoden definieren, sind innerhalb der Klasse sichtbar. Auch kann man auf diese zugreifen (objekt.feld). Dies ist jedoch nicht empfohlen! Stattdessen sollte man eine Methode zum Setzen eines bzw. mehrerer Felder definieren (Mutator, Setter) und eine Methode zum Lesen eines Feldes (Akzessor, Getter). Wenn man ein Feld nicht verändern soll, wird kein Setter definiert. Ähnliches gilt für das Auslesen eines Feldes. Für Getter und Setter gibt es Konventionen, an die wir uns halten wollen: Alle Setter beginnen mit set-, alle Getter mit get-. Feld Feld Feld Feld Methode Sieht alles Feld Feld Klasse Das Programm Sieht Methoden der Klasse und eigene Variablen by Alexis Engelke 2012 Seite 27
Erweiterung von Klassen (Vererbung) Ziel der Erweiterung ist es, denselben Code nicht fünfmal zu schreiben, sondern nur ein einziges mal. by Alexis Engelke 2012 Seite 28
Listen, Dateien und Mathematik LEVEL 4 by Alexis Engelke 2012 Seite 29
Ein Beispiel für dist: println(dist(2,2,5,4)) gibt die Distanz zwischen den Punkten (2,2) und (5,4) aus. Hinweis: Um Zahlen in Listen zu speichern, kann man eine eigene Klasse Zahl schreiben, die ein Feld var o.ä. hat (eine sogenannte Wrapper-Klasse). by Alexis Engelke 2012 Seite 30
Dieser Level wird auch aus zeitlichen Gründen nicht vorgetragen und dient zum Selbststudium. Shapes & Vertices LEVEL 5 by Alexis Engelke 2012 Seite 31
In diesem Level wird es darum gehen, eigene Figuren, wie man z.b. einen Stern oder andere nichtvorgegebene Objekte zeichnen kann. Die Lösung dazu sind die sogenannten Vertices. Der Befehl, um eine solche Figur zu beginnen lautet beginshape(). Einzelne Eckpunkte, die miteinander verbunden werden, legt man mit dem Befehl vertex(x,y) fest. Wenn alle Eck-Punkte festgelegt sind, wird die Figur mit dem Befehl endshape() beendet. Soll der letzte Punkt wieder mit dem ersten verbunden werden, so lautet der Befehl nicht endshape(), sondern endshape(close). Hier ein Beispiel: void setup() { size(400, 300); smooth(); fill(255, 120, 0); stroke(0); } void draw() { background(255); beginshape(); vertex(20, 20); vertex(80, 95); vertex(50, 90); vertex(250, 200); endshape(close); } Ohne die Figur abzuschließen, also ohne das Argument CLOSE bei endshape, würde dies das Resultat sein: by Alexis Engelke 2012 Seite 32