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;
  }
}