Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2015 Prof. Dr. Nitsche Übung 7 Grafik-Programmierung In dieser Übung fahren wir mit den Grundlagen der Grafikprogrammierung aus Übung 6 fort und wenden dies auf Spiele an. Aufgabe 1: Zeichenbare Game-Objekte Zunächst definieren wir ein Interface PaintableGameObject mit der Methode paintComponent. Unsere Spielobjekte (vom Typ GameObject) sollen dieses Interface implementieren und dadurch grafisch darstellbar sein. Die eigentliche Darstellung erfolgt jeweils spezifisch für jedes Spielobjekt. In unserem Spiel brauchen wir uns dann nicht mehr weiter darum zu kümmern, wie die Spielobjekte gezeichnet werden, da aufgrund der dynamischen Bindung jedes Objekt „weiß“, wie es sich selbst zeichnen soll. Wir erweitern danach das Interface GameObject um dieses Interface, damit alle Spielobjekte gezeichnet werden können. Da durch diese Interfaces-Erweiterung die implementierenden Klassen abstrakt geworden sind, müssen wir noch die Methode paintComponent jeweils spezifisch implementieren. Hinweis: Falls Sie Ihre Lösung von Übung 4 nicht vollständig realisiert haben, können Sie von der Webseite der Veranstaltung eine Beispielvorgabe der bereits in den Übungen realisierten Interfaces und Klassen herunterladen. a) Erstellen Sie ein Interface PaintableGameObject im Paket games.basic.gameObjects.interfaces. Diese soll die Methode public void paintComponent(Graphics g) bereitstellen. b) Leiten Sie das Interface games.basic.gameObjects.interfaces. GameObject (siehe Übung 4) neben SimpleGameObject auch von PaintableGameObject ab. c) Passen Sie dann die Klassen RectangularGameObject und CircularGameObject aus dem Paket games.basic.gameObjects entsprechend an, indem Sie dort jeweils die Methode paintComponent implementieren. Dabei soll S. 1 / 4 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2015 Prof. Dr. Nitsche Übung 7 • die Farbe des Rechteckes bzw. Kreises jeweils per Attribut wählbar sein, • ebenso ob die Figuren ausgefüllt sein sollen oder nicht. Hinweis: Zum Zeichnen eines ausgefüllten Rechteckes bzw. Kreises können Sie die Methoden fillRect(x, y, width, height) bzw. fillOval(x, y, width, height) aus der Klasse java.awt.Graphics verwenden (siehe http://docs.oracle.com/javase/7/docs/api/index.html?java/awt/Graphics.html), während drawRect bzw. drawOval jeweils nur den Rahmen der Figuren zeichnet. Hinweis: Zum Festlegen der Strichdicke können Sie die Methode setStroke(new BasicStroke( <<Strichdicke>> ) aus der Klasse Graphics2D verwenden. d) Erstellen Sie eine (analog zu RectangularGameObject) eine von AbstractGameObject abgeleitete Klasse CrossGameObject, welche ein Kreuz (d.h. 2 Linien) darstellt. Aufgabe 2: Grafik für Tic Tac Toe Tic Tac Toe (auch „Drei gewinnt“ oder „Kreis und Kreuz“) ist ein Spiel für zwei Personen. Dabei machen auf einem 3×3 Felder großen Spielfeld die beiden Spieler abwechselnd ihre Zeichen (ein Spieler Kreuze, der andere Kreise). Der Spieler, der als erstes drei seiner Zeichen in eine Reihe, Spalte oder eine der beiden Hauptdiagonalen setzen kann, gewinnt. [wikipedia] Implementieren Sie die grafische Darstellung für das Spiel Tic Tac Toe. Dabei sollen geeignete Spielobjekte jeweils (rote) Kreuze sowie (blaue) Kreise zur Darstellung der Züge der beiden Gegner verwendet werden. S. 2 / 4 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2015 Prof. Dr. Nitsche Übung 7 a) Erstellen Sie eine von JPanel abgeleitete Klasse TicPanel im Paket games.examples.ticTacToe. • Übergeben Sie der Klasse eine Liste von darzustellenden Spielobjekten, d.h. von Objekten vom Typ games.basic.gameObjects.interfaces.GameObject. Hinweis: Für Listen bietet Java u.a. die generische Klasse ArrayList (java.util.ArrayList<GameObject>, siehe http://docs.oracle.com/javase/7/docs/api/index.html?java/util/ArrayList.html). Diese besitzt u.a. die folgenden für diese Aufgabe relevanten Funktionen: • new ArrayList<GameObject>() erzeugt eine leere Liste von GameObject-Objekten. • boolean add(GameObject elem) fügt ein Element zur Liste hinzu • for (GameObject elem : liste) { … } iteriert über alle Elemente einer Liste von GameObject-Elementen. Weitere wichtige Methoden aus ArrayList sind u.a. • GameObject get(int index) liest das Element an Position index • int size() liefert die Anzahl der Elemente in der Liste • boolean remove(GameObject elem) löscht das Element aus der Liste, sofern es enthalten ist. • Überschreiben Sie dann die Methode public void paintComponent(Graphics g) und zeichne Sie dort zunächst die Trennlinen für das 3 x 3-Feld. Zeichnen Sie ferner in das übergebene Graphics-Objekt g alle darzustellenden Spielobjekte (aus der ArrayList). b) Erzeugen Sie schließlich (in einer Klasse games.examples.ticTacToe .TicTacToe) ein JFrame-Fenster, fügen Sie ein Objekt der Klasse TicPanel zu diesem JFrame hinzu und zeigen Sie das Fenster auf dem Bildschirm an. c) Erzeugen Sie zum Testen eine Liste von Spielobjekten (Kreuze und Kreise), welche Sie sich auf dem Panel darstellen lassen. Hinweis: Zum Neuzeichnen des Fensters können Sie die Methode frame.repaint() aufrufen. S. 3 / 4 Hochschule Niederrhein Fachbereich 03 Bachelor Informatik Grundlagen der Java Programmierung SS 2015 TicTacToe Prof. Dr. Nitsche Übung 7 TicPanel objListe : ArrayList<GameObject> main(String[] args) { Jframe frame = … … TicPanel panel = new TicPanel( objListe); … } +paintComponent(Graphics g) GameObject +paintComponent(Graphics g) AbstractGameObject -pos: Positionable CrossGameObject CircularGameObject -width, height: int -color: java.awt.Color -radius: int -color: java.awt.Color -filled: boolean +paintComponent(Graphics g) +paintComponent(Graphics g) d) Nicht ausgelastet? Lassen Sie beim Zeichnen der Kreise und Kreuze einen Abstand zum Rand des jeweiligen Feldes, d.h. zu den Rahmenlinien des 3x3-Feldes. Zusatz-Aufgabe 3: Spielsteuerung für Tic Tac Toe Erweitern Sie die Klasse TicTacToe um die Spielsteuerung für das Spiel TicTacToe. Dazu können Sie von Tastatur jeweils das Feld einlesen und abwechselnd (für jeden Spieler) Kreuze bzw. Punkte in dieses Feld setzen. Wer alle Felder einer Zeile, Spalte oder Diagonale besetzt hat, hat das Spiel gewonnen. Zusatz-Aufgabe 4 (für Java-Experten): Java-Rätsel Was gibt das folgende Java-Programm aus – und warum verhält es sich so seltsam? package click; package hack; import click.CodeTalk; public class CodeTalk { public void doIt() { printMessage(); } void printMessage() { System.out.println("Click"); } public class TypeIt { private static class ClickIt extends CodeTalk { void printMessage() { System.out.println("Hack"); } } public static void main(String[] args) { ClickIt clickit = new ClickIt(); clickit.doIt(); } } } S. 4 / 4