Fang den Kreis


In dieser Übung kannst du die Entstehung eines kleinen Spiels begleiten.

Idee: dem Spieler wird eine Farbe angezeigt und er muss alle Kreise mit dieser Farbe anklicken. Die Treffer werden dabei gezählt. Damit das mehr Spaß macht, bewegen sich die Kreise verchieden schnell und sind auch verschieden groß.

Schrit 1: Kreis anklicken

Für die Kreise wird ein Prototyp angelegt:

function kreis_schablone(fuellfarbe, linienfarbe, dicke, durchmesser, xkoord, ykoord) {
  this.fuellfarbe = fuellfarbe;
  this.linienfarbe = linienfarbe;
  this.dicke = dicke;
  this.durchmesser = durchmesser;
  this.xkoord = xkoord;
  this.ykoord = ykoord;
  this.zeichnen = function() {
    stroke(this.linienfarbe);
    strokeWeight(this.dicke);
    fill(this.fuellfarbe);
    ellipse(this.xkoord, this.ykoord, this.durchmesser, this.durchmesser);
  }  
  this.verschieben = function(x, y) {
    this.xkoord = this.xkoord + x;
    this.ykoord = this.ykoord + y;
  }
}

Dieser Prototyp beinhaltet alle wichtigen Eigenschaften und Methoden, damit ein Kreis gezeichnet und bewegt werden kann. Mit der Anweisung:

var kreis01 = new kreis_schablone('skyblue', 0, 0, 80, 90, 150);

wird ein neuer Kreis angelegt. Die Eigenschaften werden als Argumente in den Klammern angegeben. Mit Hilfe von

push();
kreis01.zeichnen();
pop();

wird innerhalb der draw-Funktion der Kreis 01 mit den vorher angegeben Eigenschaften in den Zeichenbereich gezeichnet. Mit push(); und pop(); erreicht man, dass die Einstellungen für Füllfarbe, Liniendicke, ... nur auf den Kreis angewendet werden.

Die Funktion mousePressed wird aufgerufen, sobald die Maustaste gedrückt wurde.

function mousePressed() {
  var d1 = dist(mouseX, mouseY, kreis01.xkoord, kreis01.ykoord);
  if (d1 < kreis01.durchmesser/2) {
    treffer1++;
  }
}

Die Anweisung dist(x1, y1, x2, y2) misst den Abstand vom Punkt (x1, y1) zum Punkt (x2, y2). Für diese beiden Punkte wird die Mausposition und die Kreisposition eingetragen, so dass dadurch die Entfernung der Maus zur Mitte des Kreises gemessen werden kann. Ist diese Entfernung kleiner als die Hälfte des Kreisdurchmessers (= Radius), dann wird der Wert der Variable treffer1 um eins größer (treffer1++ ist das gleiche wie treffer1 = treffer1 + 1), denn man hat den Kreis mit der Maus angeklickt. Klicke im folgenden Programm auf die Kreise und beobachte, wie die Treffer anwachsen.


Schritt 2: Automation

Da im Spiel viele Kreise automatisch gezeichnet werden sollen, muss dieser Vorgang automatisiert werden. Der Prototyp für einen Kreis wird um die Methode angeklickt ergänzt:

this.angeklickt = function() {
  var abstand = dist(mouseX, mouseY, this.xkoord, this.ykoord);  
  if (abstand < this.durchmesser/2) {
    this.treffer++;
  }  
}

Für die Kreise wird ein Array kreise angelegt und die Kreise werden zu Elementen des Arrays.

var kreise = [];
kreise[0] = new kreis_schablone('skyblue', 'seagreen', 5, 80, 150, 150);
kreise[1] = new kreis_schablone('indigo', 'thistle', 10, 120, 210, 230);
kreise[2] = new kreis_schablone('orange', 'tomato', 7, 60, 100, 400);

Da viele Kreise gezeichnet werden sollen, ist es sinnvoll das Zeichnen der Kreise zu automatisieren. Damit immer genau so viele Kreise gezeichnet werden, wie im Array kreise gespeichert sind, wird die Anzahl aus der Variablen kreise.length geholt, die angibt, wie viele Elemente im Array kreise enthalten sind:

push();
for (var i = 0; i < kreise.length; i++) {
  kreise[i].zeichnen();
}
pop();

Die Kreise sollen sich bewegen, also werden diese immer wieder zufällig verschoben:

if (frameCount % 2 == 0) { 
  for (var i = 0; i < kreise.length; i++) {
    kreise[i].verschieben(random(-2,2), random(-2,2)); 
  }    
}

Die Prüfung, ob ein Kreis angeklickt wurde, erfolgt wieder mit Hilfe der Funktion mousePressed, wobei jetzt die Methode des Prototyps aufgerufen wird.

function mousePressed() {
  for (var i = 0; i < 3; i++) {
    kreise[i].angeklickt();
  }
}

Damit können jetzt beliebig viele Kreise angelegt werden. Versuche das, indem du noch ein paar Kreise kreise[3], kreise[4],... anlegst.

Wenn du die Kreise anklickst werden die Treffer größer. Ein Problem gibt es noch, denn wenn beide Kreise übereinander liegen, werden für beide Kreise ein Treffer gezählt, obwohl ja der obere angeklickt wird.


Schritt 3: Treffer bei übereinanderliegenden Kreisen.

Das Problem kann man lösen, indem man eine Steuervariable getroffen einführt.

this.angeklickt = function() {
  var abstand = dist(mouseX, mouseY, this.xkoord, this.ykoord);  
  if (abstand < this.durchmesser/2) {
    this.treffer++;
    this.getroffen = 1;
  }  
  else {
    this.getroffen = 0;
  }
}

Diese Variable steuert, ob die for-Schleife mit Hilfe von break; vorzeitig verlassen wird. Da der oberste Kreis, als letztes gezeichnet wird, muss die for-Schleife in umgekehrter Reihenfolge durchlaufen werden.

function mousePressed() {
  for (var i = 2; i < -1; i--) {
    kreise[i].angeklickt();
    if (kreise[i].getroffen) {
      break;
    }
  }
}

Jetzt wird ein Treffer nur für den oben liegenden Kreis gezählt.


Schritt 4: Viele Kreise und Farbe vergleichen

Im nächsten Schritt sollen jetzt viele Kreise erzeugt werden und ein Treffer soll nur gezählt werden, wenn die Farben übereinstimmen. Nach einem Treffer soll der Kreis entfernt werden.

Es wird ein Array für die Farben angelegt:

var farbSammlung = [
  "skyblue",
  "indigo",
  "orange",
  "teal"
];

Mit Hilfe der Anweisung:

farbSammlung[Math.floor(random(farbSammlung.length))

kann daraus eine Farbe zufällig ausgewählt werden.

Mit

if (kreise[i].fuellfarbe == vergleichsfarbe) {
    kreise.splice(i,1);  
}

wird der aktuell angeklickte Kreis aus dem Array gelöscht, wenn dessen Farbe mit der Vergleichsfarbe übereinstimmt.


Das Spiel Fang den Kreis

Im letzten Schritt wird die Bewegung dynamischer und flüssiger. Dazu wird die Funktion noise verwendet, die bereits erklärt wurde.

Anleitung

Klicke mit der Maus auf Kreise, deren Farbe mit der Farbe des Spielfeldrands übereinstimmen. Wenn du auf Play klickst, beginnt eine neue Runde.


Jetzt bist du dran:

  • Farbauswahl
  • Steuerung
  • Spiel-Start
  • Spiel-Ende
  • ...

all das kann jetzt noch weiter entwickelt werden.