Skip to content

Pong Ball

Ziel

In Pong Ball erlernen wir das Konzept von ereignisorientierter Programmierung. Wir reagieren auf Keyboard Input und Timer Events um einen Ball über den Bildschirm zu steuern.

Projekt Importieren

Laden Sie die Vorlage als ZIP herunter über GitLab in dem Sie diesem Link folgen.

Pong Ball.zip

Importieren Sie das Projekt in Eclipse. Starten Sie das Projekt PongBallApp.java. Ignorieren Sie ActivePanel.java (dient nur als Hilfsmittel).

Implementieren Sie PongBallPanel.java.

Grundgerüst

  1. Deklarieren und Implementieren Sie die Methode drawBall mit welcher Sie einen Ball auf dem Bildschirm an einer Position mit einer Farbe zeichnen.
  2. Als Referenzpunkt des Balls soll die untere Mitte verwendet werden.
  3. Zeichnen Sie einen schwarzen Bildschirm und den Ball in der Mitte des Bildschirms.

Parametrisierung

  1. Erstellen Sie eine Konstante für den Radius des Balls und deklarieren Sie diese als static final im Klassenrumpf.
  2. Erstellen Sie zwei Attribute x und y vom Typen int im Klassenrumpf. Sie dienen als Koordinaten des Balls.
  3. Überschreiben Sie die Methode onInit() und setzen Sie die Koordinaten des Balls beim Starten des Panels in die Bildschirmmitte.
  4. Zeichnen Sie in paintComponent den Ball an der Stelle x, y.

Ereignisse: Keyboard Events

An dieser Stelle wollen wir den Ball mit den Pfeiltasten auf dem Keyboard steuern. Überschreiben Sie die Methode onKeyDown. Folgen Sie dieser Vorgehensweise:

  1. Wenn keyCode KeyEvent.VK_UP entspricht, dekrementieren Sie die y-Koordinate um 10.
  2. Wenn keyCode KeyEvent.VK_DOWN entspricht, inkrementieren Sie die y-Koordinate um 10.
  3. Verfahren Sie analog mit der x Koordinate und KeyEvent.VK_LEFT respektive KeyEvent.VK_RIGHT.
  4. Führen Sie am Schluss einen repaint() aus.

An dieser Stelle sollten Sie nun in der Lage sein den Ball zu kontrollieren.

Bonus, WASD

Implementieren Sie die Bewegung mittels WASD Tasten zusätzlich zu den Pfeiltasten.

Physik und States

Ziel soll es sein, den Ball via Space-Taste "anzuschubsen". Dieser soll beim Kollidieren mit den Wänden die Bewegungsrichtung umkehren.

Konzept der Bewegung

Bewegt sich der Ball, so solle er periodisch seine x und y Koordinate ändern. Periodisch heisst jedes mal, wenn die zu überschreibende Methode onTick aufgerufen wird.

onTick wird alle 16ms aufgerufen und erlaubt uns den Gamestate (in diesem Fall die x und y Koordinate) ständig neu zu rechnen.

Um eine Bewegung durchführen zu können werden x und y inkrementiert und später via repaint() ein neues Frame gezeichnet.

Geschwindigkeit

Um welchen Wert sollen x und y inkrementiert werden? Hierzu dienen zwei neue Variablen vx und vy (Velocity) um die Geschwindigkeit und die Richtung des Balls zu bestimmen.

  • Die x Koordinate soll jedes mal um vx inkrementiert werden. Ist vx positiv, so bewegt sich der Ball gegen rechts. Umgekehrt, wenn vx negativ ist, bewegt sich der Ball nach links.
  • Analog hierzu verhält sich y und vy.
  1. Deklarieren Sie vx und vy im Klassenrumpf als Attribute. Verwenden Sie den Typen int für den Moment`.
  2. Setzen Sie vx und vy in onInit auf 0.
  3. Überschreiben Sie onTick() und inkrementieren Sie x um vx und y um vy.

Anschubsen

  1. Wenn VK_SPACE gedrückt wird, soll der Ball angeschubst werden. Hierzu soll vx und vy auf einen positiven oder negativen Wert gesetzt werden.

Kollisionen mit der Wand

Zur Zeit fliegt der Ball in die Unendlichkeit. Das wollen wir ändern.

Kollidiert der Ball mit der Wand so wird einfach vx resp. vy umgekehrt um die Richtung zu ändern.

  1. Ändern Sie onTick so, dass die Richtung bei der Kollision mit der Wand ändert.
  2. Tipp: Entscheiden Sie anhand von x resp. y wie sich vx und vy ändern sollen.
  3. Vorzeichenwechsel: Wie können Sie das Vorzeichen einer Variablen ändern?

Zufällige Richtung beim Starten

  1. Ändern Sie Ihren Code so, dass beim drücken der Space Taste eine zufällige Startrichtung verwendet wird.
  2. Beim erneuten Drücken von Space, soll der Ball wieder zentriert werden und eine neue Richtung erhalten.

Konstante Geschwindigkeit

Ziel ist es, eine Konstante Geschwindigkeit für den Ball zu erzielen, allerdings die Richtung des Balls frei zu lassen.

Bei einem festen Betrag v und Winkel alpha lässt sich vx und vy mit Trigonometrie berechnen.

  1. Gegeben alpha und v: Wie berechnen sich vx und vy?
  2. Ändern Sie den Datentypen von x, y, vx und vy auf double.
  3. Casten Sie x und y beim Aufruf von drawBall in einen int.
  4. Setzen Sie vx und vy in der Anfangsbedingung (onKeyDown) so, dass folgendes erfüllt ist:
    1. Der Betrag des Vektors v ist Konstant = 5.
    2. Der Winkel alpha wird zufällig zwischen 0 und 2 * PI gewählt.
    3. vx und vy werden durch Betrag und Alpha errechnet.
  5. Entfernen Sie nun den Code, welcher auf die Pfeiltasten reagiert.

Checkpoint: Big Bad Button

java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;

public class BigButtonPanel extends JPanel {

	// Hintergrund des Panels schwarz zeichnen
	// bei Buttonpress
	// via fillRect

	boolean pressed = false;

	public void init() {
		setLayout(null);
		JButton button = new JButton("BIG BAD BUTTON");
		add(button);
		button.setBounds(getWidth() / 2 - 200, getHeight() / 2 - 100, 400, 200);

		button.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {

				pressed = !pressed;
				repaint();
			}
		});
		// Listener registrieren und auf event reagieren
	}

	@Override
	protected void paintComponent(Graphics g) {

		if (pressed) {
			g.setColor(Color.BLACK);
			g.fillRect(0, 0, getWidth(), getHeight());
		} else {
			g.setColor(Color.WHITE);
			g.fillRect(0, 0, getWidth(), getHeight());
		}

	}

}

Video zur Übung