Das Programmieren mit Objekten und Klassen nennt man objektorientiertes Programmieren. Es bietet den Vorteil einer viel besseren Übersicht bei längeren Programmen und ist hier auch dringend anzuraten.
Grundlegendes:
Eine Klasse ist eine allgemeine Vorlage für ein Objekt. Nehmen wir als Beispiel ein Auto. Die Vorstellung von einem Auto wäre dann die Klasse. Die Eigenschaften eines Autos sind in der Klasse definiert (Bsp.: Auto hat 4 Räder, 4 Lichter, ein Lenkrad usw.). Manche Eigenschaften können aber auch variieren, so dass z.B. manche Autos unterschiedlich viele Sitze oder Türen aufweisen (oder auch eine aktuelle Geschwindigkeit und Richtung). Diese Eigenschaften übermittelt man der Klasse, wenn nach ihrer Vorlage ein Objekt erstellt werden soll. Ein Auto hat aber nicht nur Eigenschaften, die in der Programmierung in Form von Variablen verarbeitet werden, sondern auch Funktionen. Man nennt diese Methoden. Mit Hilfe dieser Methoden kann man ein Objekt manipulieren. Das Auto könnte beispielsweise beschleunigen und somit ändert sich die aktuelle Geschwindigkeit. Es könnte auch nach links lenken und somit die Fahrtrichtung ändern.
Klasse: Auto
class Auto {
}
Eigenschaften: Farbe, Türen, Leistung usw.
class Auto {
color farbe;
int tueren;
float leistung;
}
Methoden: Lenken, Beschleunigen, Bremsen usw.
class Auto {
void lenken() {
// Funktion lenken
}
void beschleunigen() {
// Funktion beschleunigen
}
}
Objekt: VW Käfer (blau, 2 Türen, 32 PS uws.)
Ein Beispiel: Wir wollen ein Programm schreiben, das Ameisen erzeugt, die sich auf zufälligen Bahnen bewegen und Futter sammeln. Dabei sollten ganz einfache Regeln gelten: Findet eine Ameise Futter und trägt gerade kein Futter, soll sie das gefunden Futter aufnehmen. Das trägt sie dann, bis sie wieder auf Futter stößt. Hier soll sie das Futter, das sie gerade trägt fallen lassen.
Wir werden also diesmal objektorientiert vorgehen und brauchen für unser Projekt 2 Objekte: das Futter und die Ameisen. Wie müssen diese Objekte nun beschrieben werden? Fangen wir der Einfachheit halber mit der Beschreibung des Futters an. Dieses hat in unserem Beispiel eine sehr passive Rolle und sollte somit leicht zu beschreiben sein.
Wie wir wissen nennt man die Beschreibung eines Objektes Klasse (class). Die sieht nun bei unserem Futter so aus:
class Food {
float xPos;
float yPos;
float radius;
int traeger;
int frame=0;
color clr;
Food (float axPos, float ayPos, float aradius, int atraeger, color aclr) {
xPos = axPos;
yPos = ayPos;
radius = aradius;
traeger = atraeger;
clr = aclr;
}
Dabei werden im oberen Teil die benötigten Variablen definiert. Unten haben wir den sog. Konstruktor. Dieser weist den Variablen xPos, yPos usw. von uns definierte Werte zu. Der Konstruktor gibt im Gegensatz zu einer Funktion nichts zurück, nicht einmal void und wird immer, wenn ein neues Objekt erstellt wird automatisch aufgerufen. Somit ist die Definition der Klasse abgeschlossen.
Um ein Objekt der Klasse Food zu generieren müssen wir noch folgendes machen:
1. Wir erzeugen eine Variable der Klasse Food mit dem Namen Futter.
Food Futter; </em>
2. Wir rufen eine Funktion mit dem Namen der Klasse auf und befüllen die Variable Futter mit einem Objekt der Klasse Food.
Futter=new Food();
3. Jetzt enthält unsere Variable Futter lauter Nullen für alle int, float und color – Variablen, die in ihr enthalten sind. Indem wir jetzt unseren Konstruktor aufrufen, befüllen wir unser Objekt mit den von uns gewünschten Werten. Dafür schreiben wir der besseren Übersichtlichkeit halber eine eigene Funktion.
void gibFutter() {
Futter = new Food[50];
int border = 50;
for (int f=0; f<Futter.length; f++) {
float xPos = random(border, width-border);
float yPos = random(border, height-border);
float radius = random(5, 5);
int traeger = 500;
color clr = color(50,200,0,120);
Futter[f] = new Food(xPos, yPos, radius, traeger, clr);
}
}
Diese Funktion nennen wir gibFutter. Sie erstellt in diesem Fall 20 Futterobjekte, die mit zufälligen Koordinaten versehen werden (und 50px Abstand zum Rand, damit sie auch von den Ameisen aufgenommen werden können).
Das wärs dann eigentlich. Fast das gleiche, aber mit ein wenig mehr Eigenschaften machen wir mit den Ameisen. Die Klasse inkl. dem Konstruktor sieht bei den Ameisen dann so aus:
class Animals {
PVector position;
PVector direction;
float spin = 0.10;
float radius;
boolean loaded;
int blocked;
int traegt;
color clr;
Animals (float theX, float theY,
float aradius, boolean aloaded, int ablocked, int atraegt, color aclr) {
position = new PVector (theX, theY);
direction = new PVector (10,10);
direction.x = random (-1, 1);
direction.y = random (-1, 1);
radius = aradius;
loaded = aloaded;
blocked = ablocked;
traegt = atraegt;
clr = aclr;
}
}
Methoden:
Um unseren Objekten jetzt noch sagen zu können, was sie machen sollen, müssen wir in den Klassendefinitionen noch etwas ergänzen. Und zwar sog. Methoden. Das sind Funktionen in der Klassendefinition, die Eigenschaften der Objekte ändern können. Z.B. sollten sich die Ameisen fortbewegen und am Bildschirm dargestellt werden können. Dafür haben wir 2 Methoden, nämlich die Methode render und die Methode move.
//Methode des Objekts Ameise
void render() {
fill(clr);
//der Code ab hier dient dem Zeichnen der Ameise
PVector normVector = new PVector(1,0);
float angle = direction.heading2D();
pushMatrix();
translate(position.x,position.y);
rotate(angle-PI);
strokeWeight(2);
line(0-radius/2,0-radius, 0+radius/2, 0+radius);
line(0+radius/2,0-radius, 0-radius/2, 0+radius);
line(0,0-radius, 0, 0+radius);
ellipse(0,0,radius*0.5,radius*0.5);
ellipse(0+radius-1,0,radius*1.5,radius);
ellipse(0-radius*0.7,0,radius,radius);
//ellipse(position.position.x, position.position.y, radius*2, radius*2);
popMatrix();
}
//Methode des Objekts Ameise
void move() {
direction.x += random (-spin, spin);
direction.y += random (-spin, spin);
direction.normalize ();
position.add (direction);
if (position.x < radius || position.x > (width-radius)) {
direction.x *= -1;
}
if (position.y < radius || position.y > (height-radius)) {
direction.y *= -1;
}
}
Der Aufruf einer solchen Methode sieht dann so aus:
Ameise[i].move();
Ameise[i].render();
Außerdem können zu jedem Zeitpunkt alle Variablen eines Objekts abgerufen werden. Ein Beispiel für eine Abfrage kommt im gesamten Quellcode unten vor.
Unser Beispiel ist bewusst eher einfach gehalten und könnte noch um viele nette Features erweitert werden.
Beispiel Ameisen: starte Applet

Animals [] Ameise;
Food [] Futter;
//Der Aufruf einer solchen
//Methode sieht dann so aus:
void setup() {
size(400, 400,P2D);
gibFutter();
buildAmeise();
frameRate(120);
}
void draw() {
background(180);
//die erste Schleife geht in jedem Frame alle Ameisen durch
for (int i=0; i<Ameise.length; i++) {
//damit weichen die Ameisen einader aus
for (int u=0; u<Ameise.length; u++) {
if ((Ameise[i].position.x < Ameise[u].position.x+20 && Ameise[i].position.x > Ameise[u].position.x-20
&& Ameise[i].position.y < Ameise[u].position.y+20 && Ameise[i].position.y > Ameise[u].position.y-20) && u!=i) {
Ameise[i].direction.x *= -1;
Ameise[i].direction.y *= -1;
}
}
Ameise[i].move();
Ameise[i].render();
Ameise[i].blocked-=1;
//die zweite Schleife alle Futterpakete
for (int f=0; f<Futter.length; f++) {
if (Ameise[i].position.x < Futter[f].xPos+6 && Ameise[i].position.x > Futter[f].xPos-6
&& Ameise[i].position.y < Futter[f].yPos+6 && Ameise[i].position.y > Futter[f].yPos-6) {
//hierhin kommt man nur, wenn eine Ameise auf Futter gestoßen ist
if(Ameise[i].loaded && Ameise[i].traegt!=f) {
//hier kommt hin, was passiert, wenn eine schon beladene Ameise auf Futter trifft
Ameise[i].blocked=30; //Anzahl der Frames, bevor die Ameise wieder Futter aufnehmen kann
Ameise[i].loaded = false;
Futter[f].traeger=500;
}
else {
//das passiert, wenn die Ameise auf Futter gestoßen ist, nichts trägt und nicht gesperrt ist.
if (Ameise[i].blocked<1) {
Ameise[i].traegt= f;
Futter[f].traeger= i;
Futter[f].dragged();
Ameise[i].loaded = true;
}
}
}
Futter[f].render();
println(Futter[f].traeger);
}
}
}
//diese Funktion erzeugt die Ameisen
void buildAmeise() {
Ameise = new Animals[5];
int border = 50;
for( int i =0;i<Ameise.length; i++) {
float X = random(border, width-border);
float Y = random(border, height-border);
float theX = random(border, width-border);
float theY = random(border, height-border);
float radius = random(15, 15);
boolean loaded = false;
int blocked = 0;
int traegt = 50;
color clr = color(120,100);
Ameise[i] = new Animals(theX, theY, radius, loaded, blocked, traegt, clr);
}
}
//hier beginnt die Definition des Objekts Ameise
void gibFutter() {
Futter = new Food[50];
int border = 50;
for (int f=0; f<Futter.length; f++) {
float xPos = random(border, width-border);
float yPos = random(border, height-border);
float radius = random(5, 5);
int traeger = 500;
color clr = color(50,200,0,120);
Futter[f] = new Food(xPos, yPos, radius, traeger, clr);
}
}
class Animals {
PVector position;
PVector direction;
float spin = 0.10;
float radius;
boolean loaded;
int blocked;
int traegt;
color clr;
Animals (float theX, float theY,
float aradius, boolean aloaded, int ablocked, int atraegt, color aclr) {
position = new PVector (theX, theY);
direction = new PVector (10,10);
direction.x = random (-1, 1);
direction.y = random (-1, 1);
radius = aradius;
loaded = aloaded;
blocked = ablocked;
traegt = atraegt;
clr = aclr;
}
//Methode des Objekts Ameise
void render() {
fill(clr);
//der Code ab hier dient dem Zeichnen der Ameise
PVector normVector = new PVector(1,0);
float angle = direction.heading2D();
pushMatrix();
translate(position.x,position.y);
rotate(angle-PI);
strokeWeight(2);
line(0-radius/2,0-radius, 0+radius/2, 0+radius);
line(0+radius/2,0-radius, 0-radius/2, 0+radius);
line(0,0-radius, 0, 0+radius);
ellipse(0,0,radius*0.5,radius*0.5);
ellipse(0+radius-1,0,radius*1.5,radius);
ellipse(0-radius*0.7,0,radius,radius);
//ellipse(position.position.x, position.position.y, radius*2, radius*2);
popMatrix();
}
//Methode des Objekts Ameise
void move() {
direction.x += random (-spin, spin);
direction.y += random (-spin, spin);
direction.normalize ();
position.add (direction);
if (position.x < radius || position.x > (width-radius)) {
direction.x *= -1;
}
if (position.y < radius || position.y > (height-radius)) {
direction.y *= -1;
}
}
}
//hier beginnt die Definition des Objekts Futter
class Food {
float xPos;
float yPos;
float radius;
int traeger;
int frame=0;
color clr;
Food (float axPos, float ayPos, float aradius, int atraeger, color aclr) {
xPos = axPos;
yPos = ayPos;
radius = aradius;
traeger = atraeger;
clr = aclr;
}
//Methode des Objekts Futter
void render() {
fill(clr);
ellipse(xPos, yPos, radius*2, radius*2);
}
//Methode des Objekts Futter
void dragged() {
if (Ameise[traeger].blocked<1) {
xPos=Ameise[traeger].position.x;
yPos=Ameise[traeger].position.y;
}
}
}
Aufgabe: Programmiere basierend auf dem Ameisen-Beispiel ein kleines Autorennspiel.
Pingback: Processing – Über dieses Weblog « processing – tutorial
Pingback: Variablen und Datentypen « processing – tutorial
Pingback: Strings « processing – tutorial
Programm Race von Simon:
int spielstatus =0;
int x=110;
int zeit =5;
float farbe1=random(100,255);
float farbe2=random(100,255);
float farbe3=random(100,255);
float punkte=0;
int fehler=0;
float time=0;
int endpunkte=0;
void setup(){
size(500,500);
PFont font = loadFont(“text.vlw”);
textFont(font,20);
noStroke();
}
void draw(){
background(50);
time=time+1;
//startfeld
if(spielstatus==0){
text(“Drücken Sie eine beliebige Taste”,width/2-140,height/2);
}
//spielstart
if(keyPressed){
spielstatus=1;
}
if(spielstatus==1){
/// gras
fill(10,230,10);
rectMode(CORNER);
rect(0,0,100,height);
rect(400,0,100,500);
/////
// spieler
fill(farbe1,farbe2,farbe3);
rectMode(CORNERS);
rect(x,370,x+80,480);
rectMode(CORNER);
h1.update();
h2.update();
h3.update();
h4.update();
g1.update();
g2.update();
g3.update();
punkte();
crash();
if(fehler<10){
text("Fehler",420,160);
text(fehler,440,200);
}
if(x400){
punkte=punkte-30/frameRate;}
}
}
void keyPressed(){
if(keyPressed){
if(key==CODED){
if(keyCode==LEFT && x>50){
x=x-100;
}
if(keyCode==RIGHT && x height+0) {
ypos = -100;
}
//weiße linien
fill(255);
rect(198, ypos,4, 100);
rect(298, ypos,4, 100);
}
}
////////////////// gegner ///////
Gegner g1 = new Gegner(110,random(-200,0),random(2,6),zeit);
Gegner g2 = new Gegner(210,random(-600,0),random(2,6),zeit);
Gegner g3 = new Gegner(310,random(-400,0),random(2,6),zeit);
class Gegner {
float xpos,ypos,speed,timer;
Gegner (float x,float y, float s,float t) {
xpos=x;
ypos = y;
speed = s;
timer=t;
}
void update() {
ypos=ypos+speed;
fill(10,150,200);
rect(xpos,ypos,80,110);
if(ypos>height){
ypos=random(-height,-100);
speed=random(3,7);
}
}
}
void punkte(){
punkte=punkte+0.1666;
fill(0);
text(“Punkte”,420,70);
text(round(punkte),440,100);
}
void crash(){
if((x==110) && g1.ypos>260 && g1.ypos 60){
fehler=fehler+1;
time=0;
}
if((x==210) && g2.ypos>260 && g2.ypos 60){
fehler=fehler+1;
time=0;
}
if((x==310) && g3.ypos>260 && g3.ypos 60){
fehler=fehler+1;
time=0;
}
if(fehler>9){
endpunkte=round(punkte);
punkte=endpunkte;
fill(0);
rect(0,0,1000,1000);
fill(255);
text(“Du hast “+endpunkte+” Punkte erreicht”,width/2-120,height/2);
text(“Taste drücken zum Neustart”,width/2-120,height/2+50);
if(keyPressed){
fehler=0;
punkte=0;
spielstatus=1;
}
}
}