Navigation überspringen

Kollisionserkennung

Wenn wir Programme schreiben, dann sollen Nutzer in der Regel mit diesen Programmen interagieren können. Eine kleine Einführung in Interaktion hatten wir bereits in vorherigen Sprints. Nun wollen wir weiter in das Thema einsteigen:

Das einfachste interaktive Element ist eine Form, die "aktiv" wird, sobald der Mauszeiger auf ihr liegt, und "inaktiv", sobald der Mauszeiger wieder fort ist. Dazu müssen wir zunächst wissen, wie wir feststellen, dass der Mauszeiger auf einem Objekt liegt. Das nennt man auch Kollisionerkennung und ist in Computerspielen von hoher Bedeutung.

Rechteck

Kollisionserkennung zwischen einem Punkt (Mauszeiger) und eine Rechteck, das parallel zu den Achsen des Koordinatensystems liegt, ist sehr einfach. Wenn der Punkt (x, y) ist und das rechteck über rx, ry, rwidth, rheight definiert ist, dann liegt eine Kollision vor, wenn die folgenden zwei Bedingungen gelten (bei rectMode(CORNER)) :

rx <= x && x <= rx + rwidth // Ausformuliert: x liegt zwischen rx und rwidth 
ry <= y && y <= ry + rheight // Ausformuliert: y liegt zwischen ry und rheight

Im Code sieht das so aus (statt x, y findest du mouseX, mouseY).  Tip: Kopiere diesen Code in Processing und du wirst sehen: Das Rechteck wird rot, sobald du mit der Maus drüber fährst.

// interface_1
// Kollision mit Rechteck (Selektion per Rollover)

int rx = 50;
int ry = 50;
int rwidth = 150; // Breite
int rheight = 200; // Höhe

void setup() {
   size(300, 300);
   noStroke(); // Das bedeutet: Das Rechteck hat keinen Rand
}

void draw() {

   // setze Füllfarbe ...
   if (rx <= mouseX && 
       ry <= mouseY && 
       mouseX <= rx + rwidth &&
       mouseY <= ry + rheight) {
      // ... wenn Mauszeiger im Rechteck => rot
      fill(255, 0, 0);
   } else {
      // ... sonst: weiß
      fill(255);
   }

   rect(rx, ry, rwidth, rheight);
}

Tip: Sieh dir an, wie die Bedingung in des if-Anweisung geschrieben wurde. Was fällt dir auf? Richtig: Hinter dem && beginnt immer eine neue Zeile. Das ist eine Codestyle Konvention, die deinen Code übersichtlicher macht. Die Konvention lautet: Wenn eine Bedingung aus mehreren booleschen Ausdrücken besteht, dann wir mit jedem Logik-Operator eine neu Zeile begonnen.

Kreis

Kollisionserkennung zwischen einem Punkt und einem Kreis ist sogar noch einfacher. Dazu vergleicht man die Distanz des Punkts (x, y) mit dem Mittelpunkt (cx, cy) des Kreises. Ist die Distanz geringer als der Radius, so ist der Punkt im Kreis:

dist(x, y, cx, cy) < radius

Die Funktion dist() berechnet den Abstand zweier Punkte. Im folgenden Code nehmen wieder mouseX, mouseY den Platz von x, y ein und der Radius errechnet sich aus diameter/2.

// interface_2
// Kollision mit Kreis (Selektion per Rollover)

int cx = 170;
int cy = 160;
int diameter = 180; // Durchmesser

void setup() {
   size(300, 300);
   noStroke();
}

void draw() {
   // setze Füllfarbe ...
   if (dist(mouseX, mouseY, cx, cy) < diameter/2) {
      // ... wenn Mauszeiger im Rechteck => rot
      fill(255, 0, 0);
   } else {
   // ... sonst: weiß
   fill(255);
   }

   ellipse(cx, cy, diameter, diameter);
}

Zusammenfassung

  • Das Erkennen von Kollisionen hat in der Programmierung eine große Bedeutung.
  • Bei der Kollisionserkennung geht es darum, herauszufinden, wann 2 oder mehr Elemente miteinander kollidieren, sei es 2 Spielfiguren oder der Mauszeiger mit einer Schaltfläche uvm.
  • Am einfachsten ist die Kollisionserkennung mit einem Kreis: Sobald der Abstand zum Mittelpunkt des Kreises kleiner ist als dessen Radius, findet eine Kollision statt.
  • Den Abstand zwischen 2 Punkten kann man in Processing mit der Funktion dist() ganz einfach berechnen.
  • Bei der Kollision mit einem Rechteck, muss man berechnen, ob der Punkt sich innerhalb des Rechteckt befindet - und das auf der x-Achse und der y-Achse. Je nachdem welchen Zeichenmodus man verwendet muss man hier die Position de Rechtecks mit dessen Breite und Höhe verrechen, z.B. x + Breite und y + Höhe im rectMode CORNER.

Made with eXeLearning (New Window)