21.05.03 Grafische Elemente/Figuren zeichnen

Mit Texte und Bildern auf einem Canvas können Sie nun umgehen. Oftmals ist es jedoch sinnvoller, Figuren und Elemente selbst zu zeichnen anstatt hierfür Bilder zu verwenden. U. a. weil Bilder relativ viel Speicherplatz belegen (sowohl im JAR, als auch im Arbeitsspeicher des Handys) und für jede Modifikation eines Bildes eine extra Datei benötigt wird. In Java ME können Sie zumindest Basiskomponenten wie Rechtecke und Kreise zeichnen. Wie das funktioniert lernen Sie in diesem Kapitel.

Gezeichnet wird immer über das Graphics-Objekt, das Sie in der paint-Methode übergeben bekommen. Dieses Objekt stellt neben den bereits bekannten Methoden (drawImage, drawString, drawChar, drawChars, setColor, setFont, fillRect und drawRegion) noch eine Vielzahl weiterer Methoden zum Zeichnen auf dem Canvas bereit.

Generell gibt es meistens die Möglichkeit ein komplettes Element vollständig ausgefüllt (fillXYZ), oder nur dessen Kontur/Rahmen (drawXYZ) zu zeichnen. So existiert zur bereits bekannten Methode fillRect(int x, int y, int width, int height), die ein Rechteck komplett mit der momentan gesetzten Farbe ausfüllt, ein drawRect(int x, int y, int width, int height), welche nur die Begrenzungslinie (Kontur) des Rechtecks in der momentan gesetzen Farbe zeichnet. Diese können Sie auch gestrichelt anzeigen. Verwenden Sie hierzu die Methode graphics.setStrokeStyle(Graphics.DOTTED). Möchten Sie wieder eine durchgezogene Linie haben, rufen Sie die Methode ein weiteres Mal mit dem Wert Graphics.SOLID auf.

protected void paint(Graphics g) {
  g.setColor(255, 0, 0); // Rot
  g.fillRect(50, 50, 100, 100); // ausgefüllt
  g.setColor(0, 255, 0); // Grün
  g.drawRect(75, 75, 100, 100); // Rahmen
}

Rechtecke zeichnen
Ellipse, Kreisbogen, Kreis

Diese Komponenten werden mit den Methoden draw/fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) gezeichnet. Die x und y Koordinate gibt den Ursprung des Rechtecks an, das die vollständige (360 Grad) zu zeichnenden Form umschließt. width und height spezifizieren die Höhe und Breite. Sind diese Größen identisch, wird ein Kreis gezeichnet, ansonsten eine Ellipse/ein Oval. Die Zeichnung der Figur beginnt (0 Grad) bei 3 Uhr und kann um startAngle Grad im Uhrzeigersinn (negativer Wert) oder gegen den Uhrzeigersinn (positiver Wert) „verschoben“ werden. Der Kreis bzw. das Oval wird von dieser Position an für die nächsten (negativer Wert) bzw. vorhergehenden (positiver Wert) arcAngle Grad gefüllt. Für einen kompletter Kreis oder eine komplette Ellipse muss hier folglich der Wert 360 angegeben werden.

protected void paint(Graphics g) {

  // Zweifarbiges Oval zeichnen
  g.setColor(255, 255, 255);
  g.fillArc(getWidth() / 2 - 20, getHeight() / 2 - 15, 40, 30, 45, 180);
  g.setColor(0, 0, 255);
  g.fillArc(getWidth() / 2 - 20, getHeight() / 2 - 15, 40, 30, 45, -180);
  // Umrahmen
  g.setColor(255, 0, 0);
  g.drawArc(getWidth() / 2 - 20, getHeight() / 2 - 15, 40, 30, 0, 360);
  // Mittiger Kreis mit einem Radius von 10 Pixeln
  g.setColor(255, 0, 0);
  g.fillArc(getWidth() / 2 - 10, getHeight() / 2 - 10, 20, 20, 0, 360);
  // Den Kreisbogen von 6 bis 9 Uhr markieren
  g.setColor(0, 255, 0);
  g.fillArc(getWidth() / 2 - 10, getHeight() / 2 - 10, 20, 20, -90, -90);
}

Kreise und Ovale zeichnen
Linien

Eine Linie wird auf ein Canvas mit der Methode drawLine(int x1, int y1, int x2, int y2) gezeichnet. x1 und y1 bilden die Startkoordinaten, x2 und y2 die Endkoordinaten. Um eine Linie einmal quer durchs Display von unten links nach oben rechts zu zeichnen, verwendet man folgenden Code:

g.drawLine(0, getHeight(), getWidth(), 0);

Rundes Rechteck

Beim Zeichnen oder Ausfüllen eines Rechtecks können Sie auch abgerundete Ecken darstellen. Diese können Sie sogar soweit abrunden, bis ein Kreis entsteht. Verwenden Sie einfach anstelle von draw/fillRect die Methode draw/fillRoundRect und ergänzen Sie sie am Ende um zwei weitere Parameter. Der Erste gibt den horizontalen Durchmesser der Abrundung der Ecken an, der Zweite den vertikalen Durchmesser.

g.fillRoundRect(20, 40, 150, 40, 30, 20);

Dreiecke

Möchten Sie Dreiecke auf Ihr Canvas zeichnen, verwenden Sie die Methode draw/fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3). Dabei stellen die einzelnen x/y-Paare die Eckpunkte des Dreiecks im Koordinatensystem dar. Um bspw. ein Dreieck über das komplette Handydisplay darzustellen, welches seine Spitze mittig und oben im Canvas hat, wird folgender Code verwendet:

g.fillTriangle(0, getHeight(), getWidth(), getHeight(), getWidth() / 2, 0);

Ein Boot zeichnen

Wenn Sie diese Techniken kombinieren, können Sie recht flexibel kleinere Szenen wie bspw. ein Boot auf dem Meer bei Nacht zeichnen.

protected void paint(Graphics g) {

  g.setColor(0, 0, 0);
  g.fillRect(0, 0, getWidth(), getHeight());
  drawShip(40, 140, g);
  drawSea(135, g);
  drawSky(g);
}

private void drawShip(int xPos, int yPos, Graphics g) {

  yPos -= 60;
  g.setColor(200, 200, 100);
  g.fillRoundRect(xPos, yPos, 100, 60, 20, 60);
  g.setColor(0, 0, 0);
  g.fillRect(xPos, yPos, 100, 30);
  g.setColor(200, 200, 100);
  g.fillRect(xPos + 47, yPos - 30, 6, 60);
  g.setColor(255, 255, 255);
  g.fillArc(xPos + 23, yPos - 27, 60, 50, 90, -180);
  g.drawLine(xPos + 60, yPos + 20, xPos + 66, yPos + 30);
  g.drawLine(xPos + 61, yPos + 20, xPos + 67, yPos + 30);
  g.setColor(0, 0, 0);
  g.fillArc(xPos + 38, yPos - 25, 30, 46, 90, -180);
}

private void drawSea(int yPos, Graphics g) {

  g.setColor(100, 100, 255);
  g.fillRect(0, yPos, getWidth(), getHeight() - yPos);
  g.fillArc(5, yPos - 10, 40, 20, 180, -180);
  g.fillArc(80, yPos - 5, 25, 10, 180, -180);
  g.fillArc(140, yPos - 5, 30, 10, 180, -180);
  g.setColor(0, 0, 0);
  g.fillArc(25, yPos - 5, 20, 10, 180, -180);
}

private void drawSky(Graphics g) {

  g.setColor(255, 255, 0);
  g.fillTriangle(10, 20, 18, 20, 14, 28);
  g.fillTriangle(10, 24, 18, 24, 14, 16);
  g.fillTriangle(40, 30, 48, 30, 44, 38);
  g.fillTriangle(40, 34, 48, 34, 44, 26);
  g.fillTriangle(100, 25, 108, 25, 104, 32);
  g.fillTriangle(100, 29, 108, 29, 104, 21);
  g.setColor(255, 255, 200);
  g.fillArc(getWidth() - 40, -40, 80, 80, -90, -90);
  g.setColor(100, 100, 100);
  g.drawArc(getWidth() - 16, 9, 5, 5, 0, 360);
  g.drawArc(getWidth() - 35, -2, 7, 7, 0, 360);
  g.drawArc(getWidth() - 5, 20, 8, 8, 0, 360);
  g.drawArc(getWidth() - 15, 30, 4, 4, 0, 360);
  g.drawArc(getWidth() - 5, 0, 3, 3, 0, 360);
}

Mit ein bisschen künstlerischem Talent, bekommen Sie diese Szene bestimmt auch schöner hin als ich.

Boot

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.