Objekt/Klasse: Mover
Ein bewegliches Objekt...
class Mover { }
...hat eine Position (Eigenschaften)...
float x; float y;...die zu Beginn seiner Existenz initialisiert wird:
Mover() { x = width/2; y = height/2; }
Es kann sich mit jedem Frame zeichnen lassen...
void display() { point(x,y); }
...und verändert sich von Frame zu Frame (Methoden).
void update() { float r = random(4); if (r>3) { x = x + 1; } else if (r>2) { x = x - 1; } else if (r>1) { y = y + 1; } else { y = y - 1; } }
Insgesamt:
class Mover { float x; float y; Mover() { x = width/2; y = height/2; } void display() { point(x,y); } void update() { float r = random(4); if (r>3) { x = x + 1; } else if (r>2) { x = x - 1; } else if (r>1) { y = y + 1; } else { y = y - 1; } } }↑
Objekte verwenden
Der Mover ist als Variable verwendbar...
Mover m;
...und muss initialisiert (erzeugt) werden (new!):
void setup() { size(400,300); background(255); m = new Mover(); }
Jetzt kann er mit jedem Frame gezeichnet und aktualisiert werden:
void draw() { m.update(); m.display(); }↑
Ball: Geschwindigkeit und Kollisionen
Ein Ball besitzt Variablen für Position und Geschwindigkeit. Abhängig davon bewegt er sich von Frame zu Frame.
class Ball { float x; float y; float vx; float vy; Ball() { x = width/2; y = height/2; vx = random(-4,4); vy = random(-4,4); } void display() { strokeWeight(16); point(x,y); } void update() { x += vx; y += vy; } }
Wenn er an einer Wand ankommt, dreht er um (siehe auch: ||).
void update() { x += vx; y += vy; if (x < 0 || x > width) { vx = -vx; } }↑
Collection und Schleife: viele Bälle
Eine Variable als Behälter für Objekte: ArrayList, zwischen < und > ist angegeben, was enthalten ist.
ArrayList<Ball> baelle; void setup() { size(800,600); baelle = new ArrayList(); for (int i=0; i<10; i++) { baelle.add(new Ball()); } } void draw() { background(255); for (int i=0; i<baelle.size(); i++) { Ball nextBall = baelle.get(i); nextBall.update(); nextBall.display(); } }
(neuer Tab für den Ball...)
class Ball { float x; float y; float vx; float vy; Ball() { x = width/2; y = height/2; vx = random(-4, 4); vy = random(-4, 4); } void display() { stroke(100,100,255); strokeWeight(16); point(x, y); } void update() { x = x+vx; y = y+vy; if (x<0) { vx = -vx; x = 0; } else if (x>width) { vx = -vx; x = width; } if (y<0) { vy = -vy; y = 0; } else if (y>height) { vy = -vy; y = height; } } }↑
Add/remove: Bälle hinzufügen und entfernen
Die Liste der Bälle kann jederzeit verändert werden. Dazu zunächst eine Anpassung an die Ball-Klasse: Bälle erzeugen an Wunschposition. Achtung: Ball() gibt es doppelt. Ball() ohne Eingabe zwischen den Klammern startet in der Mitte, Ball(xpos, ypos) startet an der festeglegten Position.
class Ball { float x; float y; float vx; float vy; Ball() { x = width/2; y = height/2; vx = random(-4, 4); vy = random(-4, 4); } Ball(float xpos, float ypos) { x = xpos; y = ypos; vx = random(-4, 4); vy = random(-4, 4); } void display() { stroke(100,100,255); strokeWeight(16); point(x, y); } void update() { x = x+vx; y = y+vy; if (x<0) { vx = -vx; x = 0; } else if (x>width) { vx = -vx; x = width; } if (y<0) { vy = -vy; y = 0; } else if (y>height) { vy = -vy; y = height; } } }
Jetzt Ball hinzufügen bei Mausklick mit add() und der neuen Erzeugung mit Position:
ArrayList<Ball> baelle; void setup() { size(800,600); baelle = new ArrayList(); } void draw() { background(255); for (int i=0; i<baelle.size(); i++) { Ball nextBall = baelle.get(i); nextBall.update(); nextBall.display(); } } void mousePressed() { baelle.add(new Ball(mouseX,mouseY); }
Auf rechte und linke Maustaste reagieren mit mouseButton (Achtung: ==). Löschen von Bällen mit remove(). Der älteste Ball steht am Ende der Liste. Das ist size()-1, weil die Liste von 0 an durchnumeriert ist.
void mousePressed() { if (mouseButton == LEFT) { baelle.add(new Ball(mouseX,mouseY)); } else if (mouseButton == RIGHT) { baelle.remove(baelle.size()-1); } }
Damit es keine Fehler beim Löschen gibt: Testen, ob die Liste leer ist.
void mousePressed() { if (mouseButton == LEFT) { baelle.add(new Ball(mouseX,mouseY)); } else if (mouseButton == RIGHT) { if (baelle.size() > 0) { baelle.remove(baelle.size()-1); } } }↑
Ball: Gravitation (Android)
Die Geschwindigkeit ändert sich mit der Erdbeschleunigung (gemessen vom Handy). Siehe: Ketai-library (wir verwenden momentan Gingerbread v9). Siehe auch AndroSensor (Android) oder Sensor Monitor (iOS).
import ketai.sensors.*; KetaiSensor sensor; float accelerometerX, accelerometerY, accelerometerZ; Ball b; void setup() { sensor = new KetaiSensor(this); sensor.start(); orientation(PORTRAIT); b = new Ball(); }
Ein "Callback" sagt Bescheid, wenn die Sensoren sich melden:
void onAccelerometerEvent(float x, float y, float z) { accelerometerX = -x/10; accelerometerY = y/10; accelerometerZ = z/10; }
Und der Ball ändert seine Geschwindigkeit abhängig davon (dazu kommt -0.01*vx als Trägheit).
vx += accelerometerX - 0.01*vx; vy += accelerometerY - 0.01*vy;
Insgesamt:
import ketai.sensors.*; KetaiSensor sensor; float accelerometerX, accelerometerY, accelerometerZ; Ball b; void setup() { sensor = new KetaiSensor(this); sensor.start(); orientation(PORTRAIT); b = new Ball(); } void draw() { background(0); b.update(); b.display(); } void onAccelerometerEvent(float x, float y, float z) { accelerometerX = -x/10; accelerometerY = y/10; accelerometerZ = z/10; } class Ball { float x; float y; float vx; float vy; Ball() { x = width/2; y = height/2; vx = random(-1, 1); vy = random(-1, 1); } void display() { stroke(100,100,255); strokeWeight(16); point(x, y); } void update() { x = x+vx; y = y+vy; if (x<0) { vx = -vx; x = 0; } else if (x>width) { vx = -vx; x = width; } if (y<0) { vy = -vy; y = 0; } else if (y>height) { vy = -vy; y = height; } vx += accelerometerX - 0.01*vx; vy += accelerometerY - 0.01*vy; } }↑