Willy 03

Unser Willy ist jetzt unser Held (Hero) und ein Objekt]]. Ansonsten ist die Funktionalität des kleinen Progrämmchens wie im vorigen Beispiel (außer das ich Willy dieses Mal zu Beginn statt nach Süden (nach unten) nach Osten (nach rechts) ausgerichtet habe). Solch ein Vorgang, in dem ein vorhandenes Programm besser strukturiert wird, wird Refactoring genannt. Es ist meistens eine gute Idee, während der Entwicklung klein anzufangen und daß man, bevor man dann weitergeht, das Erreichte erst einmal konsolidiert und sich die notwendigen Objekt- und Klassenstrukturen zurechtlegt.

Auf das Raster habe ich verzichtet. Das benötigen wir momentan nicht mehr, in späteren Beispielen werden wir es aber durchaus zur Veranschaulichung noch einmal über unser Spielfeld legen.

Der Quellcode

Klassen können in Processing auch im Hauptprgramm stehen, per Konvention legt man aber für jede Klasse einen eigenen Tab im Sketch an. Das macht die ganze Angelegenheit übersichtlicher.

Die Klasse Hero

class Hero {
  // Konstanten
  int numFrames = 8;
  int xOffset = -17;  // handoptimiert ;-)

  //Variable
  int direction;
  int myTileSize;
  PImage[] hero = new PImage[numFrames];

  // Konstruktor
  Hero(int tdir, int tSize) {
    direction = tdir;  // Anfangsrichtung
    myTileSize = tSize;
    for (int i = 0; i < numFrames; i++) {
      String imageName = "willy_steht" + nf(i, 4) + ".png";
      hero[i] = loadImage(imageName);
    }
  }

  // bisher die einzige Methode unseres Helden
  void display(int x, int y) {
    image(hero[direction], x*myTileSize + xOffset, y*myTileSize);
  }
}

Klassen in Processing sind Java-technisch gesehen »innere Klassen«, das heißt, sie kennen die im Hauptprogramm deklarierten globalen Konstanten und Variablen. Das macht es zwar einfacher, ist aber im Sinne einer vollständigen Kapselung der Klassen fatal. Denn wenn wir unsere »Hero«-Klasse in einem anderen Processing-Sketch verwenden wollen, treten unter Umständen Fehler auf, da sich die Klasse auf Deklarationen im Hauptprogramm verläßt, die es im neuen Programm nicht gibt. Daher habe ich darauf geachtet, daß diese Hero-Klasse vollständig unabhängig ist und keine global deklarierten Variablen nutzt.

Logischer bei der Methode display() wäre es vermutlich gewesen, auch die direction zu übergeben. Ich wollte aber zeigen, daß man auch Variablen mit der Punktmethode übergeben kann und dazu keinen Funktionenaufruf benötigt. Das also willy.direction = south auch möglich ist. (Dies entspricht allerdings nicht unbedingt der reinen Lehre, die verlangt, daß Eigenschaften von Objekten gekapselt sind, daß heißt, daß der Zugriff auf sie nur über Methoden erfolgen soll. Aber da Processing keine private-Deklaration kennt, läßt sich dies sowieso nur schwer erzwingen.)

Das Hauptprogramm

// Konstanten
int tileSize = 32;
int south = 0;
int west  = 2;
int north = 4;
int east  = 6;

// Unser Held -- nun als Objekt
Hero willy;

// globale Variablen
int xTile, yTile;
int row, col;
PImage greenFloor;

void setup() {
  size(15*tileSize, 10*tileSize);
  frameRate(30);
  greenFloor = loadImage("grasstile.png");
  row = width/tileSize;
  col = height/tileSize;
  willy = new Hero(east, tileSize);
  xTile = row/2;    // Startposition etwa in der Mitte der Welt
  yTile = col/2 - 1;

}

void draw() {
  /* Hintergrund zeichnen */
  background(102, 204, 51);
  for (int x = 0; x < row; x+=8) {
    for (int y = 0; y < col; y+=6) {
      image(greenFloor, x*tileSize, y*tileSize);
    }
  }

   /* Jetz kommt Willy */
  willy.display(xTile, yTile);
}

void keyPressed() {
  if(key == CODED) {
    if (keyCode == UP) {
      willy.direction = north;
      if (yTile > 0) {
        yTile--;
      }
    }
    else if (keyCode == RIGHT) {
      willy.direction = east;
      if (xTile < (row - 1)) {
        xTile++;
      }
    }
    else if (keyCode == DOWN) {
      willy.direction = south;
      if (yTile < (col - 2)) {
        yTile++;
      }
    }
    else if (keyCode == LEFT) {
      willy.direction = west;
      if (xTile > 0) {
        xTile--;
      }
    }
  }
}

Sprachregelung

Im weitern Verlauf werde ich – wie in Java (und daher auch in Processing) – im allgemeinen üblich, die Blaupausen (in unserem Beispiel Hero) Klassen nennen, die daraus abgeleiteten Instanzen (in unserem Beispiel Willy) Objekte. Das wird nicht in allen Programmiersprachen und -umgebungen so gehalten, und um Euch nicht unnötig zu verwirren, erwähne ich das hier.

What’s Next?

Als nächstes werde ich Willy das richtige Laufen beibringen. image


Zurück zu Willy 02.




Sie sind hier: StartProgrammierungCreative CodingProcessing → willy03.txt


Suche

Werkzeuge