CollisionListener (Kollisionen-Erkennung)
Methoden
Die Klasse Actor bietet drei überladene Methoden an, um CollisionListener zu registrieren:
- addCollisionListener(E collider, CollisionListener<E> listener): Kollision zwischen dieser Figur und einer einzelnen collider-Figur.
- addCollisionListener(Class<E>clazz, CollisionListener<E> listener): Kollision zwischen dieser Figur und einer Klasse anderen Figuren.
- addCollisionListener(CollisionListener<E> listener): Kollision zwischen dieser Figur und allen anderen Figuren.
Tutorial: FroggyJump1
Zu diesem Tutorial gibt es ein Repository in der Engine-Pi-Github-Organsiation. Die einzelnen Entwicklungsstadien sind in folgenden Git-Branches hinterlegt:
- blank:
Die Projektstruktur, die leere Hauptklasse
FroggyJumpist angelegt, sowie die zwei benötigten Grafikdateien sind dem Repository hinzugefügt. - basic: Der
FroggyJump-Szene wurden zehn vertikal übereinander positionierte Plattformen hinzugefügt. Der Frosch kann horizontal bewegt werden und springt automatisch von den Plattformen ab. - jump-through: Der Frosch kann durch die Plattformen hindurchspringen.
- platforms-deluxe Die Szene wurde um zufällig angeordnete Plattformen erweitert, die nach oben hin immer mehr Abstand zueinander aufweisen.
- spike-balls: Eisenkugeln mit Stacheln fallen auf den Frosch, wenn er ihnen zu nahe kommt.
- death-scene bzw. final: Wird der Frosch von einer Stachelkugel getroffen, erscheint eine Szene, die seinen Tod verkündet.
Spielkonzept und grundlegender Aufbau
Ein Frosch soll fröhlich durch das Spielfeld hüpfen und sich immer dann vom Boden abstoßen, wenn sich die Gelegenheit dazu bietet.

Dieser Frosch soll durch das Spiel springen
In der Szene FroggyJump kann der Spieler eine Figur der Klasse Frog steuern.
Zusätzlich bieten Figuren der Klasse Platform Halt.
Damit ergibt sich das Codegerüst für das Spiel:
Klasse FroggyJump
import pi.Camera;
import pi.Controller;
import pi.Scene;
import pi.graphics.geom.Vector;
public class FroggyJump extends Scene
{
private Frog frog;
private static final double PLATFORM_HEIGHT = 0.5;
public FroggyJump()
{
frog = new Frog();
add(frog);
gravityOfEarth();
Camera camera = camera();
camera.focus(frog);
camera.offset(new Vector(0, 4));
makePlatforms(10);
}
private void makePlatforms(int count)
{
for (int i = 0; i < count; i++)
{
Platform platform = new Platform(5, PLATFORM_HEIGHT);
platform.anchor(0, (double) i * 4);
add(platform);
}
}
public static void main(String[] args)
{
Controller.instantMode(false);
Controller.start(new FroggyJump(), 400, 600);
}
}
Klasse Frog
import java.awt.event.KeyEvent;
import pi.Controller;
import pi.actor.Image;
import pi.event.FrameListener;
class Frog extends Image implements FrameListener
{
private boolean jumpEnabled = true;
private static final double MAX_SPEED = 4;
public Frog()
{
super("images/Frog.png");
pixelPerMeter(25);
makeDynamic();
rotationLocked(true);
}
public void jumpEnabled(boolean jumpEnabled)
{
this.jumpEnabled = jumpEnabled;
}
@Override
public void onFrame(double pastTime)
{
// Die Blickrichtung des Frosches steuern
flippedHorizontally(velocityX() < 0);
// Die horizontale Bewegung steuern
if (Controller.isKeyPressed(KeyEvent.VK_A))
{
if (velocityX() > 0)
{
velocityX(0);
}
applyForce(-600, 0);
}
else if (Controller.isKeyPressed(KeyEvent.VK_D))
{
if (velocityX() < 0)
{
velocityX(0);
}
applyForce(600, 0);
}
// Die horizontale Geschwindigkeit begrenzen
if (Math.abs(velocityX()) > MAX_SPEED)
{
velocityX(MAX_SPEED * Math.signum(velocityX()));
}
// Wenn möglich den Frosch springen lassen
if (isGrounded() && velocityY() <= 0 && jumpEnabled)
{
velocityY(0);
applyImpulse(0, 180);
}
}
}
Klasse Platform
import pi.actor.Rectangle;
class Platform extends Rectangle
{
public Platform(double width, double height)
{
super(width, height);
makeStatic();
color("brown");
}
}

Der Frosch kann sich bewegen, knallt aber unangenehmerweise noch gegen die Decke
Ein paar Erklärungen zum Codegerüst für FroggyJump:
Physikalische Eigenschaften
Wie im Physics-Tutorial beschrieben, werden die physikalischen Eigenschaften der Spielobjekte und ihrer Umgebung bestimmt:
- Plattformen sind statische Objekte: Sie ignorieren die Schwerkraft und können nicht durch andere Objekte verschoben werden – egal, mit wie viel Kraft der Frosch auf sie fällt.
- Der Frosch ist ein dynamisches Objekt: Er wird von der Schwerkraft beeinflusst und von den statischen Plattformen aufgehalten.
- In der Szene
FroggyJumpwird die Schwerkraft der Erde simuliert. Sie wird mit der MethodegravityOfEarth()gesetzt.
Bewegung des Frosches
Die Bewegung des Frosches wird in jedem Frame kontrolliert. Wie im Game Loop
Tutorial beschrieben, wird hierzu das Interface Listener genutzt.
In jedem Einzelbild wird die Bewegung des Frosches kontrolliert:
Blickrichtung des Frosches
Das Bild des Frosches wird gespiegelt, falls er sich nach links bewegt.
Horizontale Bewegung des Frosches
Jedes Einzelbild, in dem der Spieler den Frosch (per Tastendruck) nach links
oder rechts steuern möchte, wird eine Bewegungskraft auf den Frosch angewendet.
Wird der Frosch in die Gegenrichtung seiner aktuellen Bewegung gesteuert, wird
seine horizontale Geschwindigkeit zuvor auf 0 gesetzt, um ein langsames
Abbremsen zu verhindern. Das ermöglicht schnelle Reaktion auf Nutzereingabe und
ein besseres Spielgefühl.
if (Controller.isKeyPressed(KeyEvent.VK_A))
{
if (velocityX() > 0)
{
velocityX(0);
}
applyForce(-600, 0);
}
else if (Controller.isKeyPressed(KeyEvent.VK_D))
{
if (velocityX() < 0)
{
velocityX(0);
}
applyForce(600, 0);
}
Zusätzlich wird seine Geschwindigkeit auf die Konstante MAX_SPEED
begrenzt.
Springe, wenn möglich
Mit der Methode isGrounded() bietet die Engine einen einfachen Test, um sicherzustellen, dass der Frosch Boden unter den Füßen hat. Wenn dies gegeben ist, wird ein Sprungimpuls auf den Frosch angewandt. Zuvor wird die vertikale Komponente seiner Geschwindigkeit auf 0 festgesetzt - das garantiert, dass der Frosch jedes mal die selbe Sprunghöhe erreicht.
Die Kamera folgt dem Frosch
Der Frosch soll stets sichtbar bleiben. Hierzu werden zwei Funktionen der Engine-Kamera genutzt:
- Der Frosch wird mit Camera#focus(pi.actor.Actor) in den Mittelpunkt der Kamera gesetzt. Sie folgt dem Frosch.
- Gleichzeitig soll der Frosch nicht exakt im Mittelpunkt des Bildschirms sein: Weil das Spielziel ist, sich nach oben zu bewegen, braucht der Spieler mehr Blick nach oben als nach unten. Mit Camera#offsetY(double) wird die Kamera nach oben verschoben.
Durch Platformen Springen: Kollisionen kontrollieren
Das Interface CollisionListener wurde bereits in seiner grundlegenden Form im Nutzereingabe-Tutorial benutzt.
CollisionListener kann mehr als nur melden, wenn zwei
Actor-Objekte sich überschneiden. Um das FroggyJump-Spiel zu implementieren,
nutzen wir weitere Features.
Unser Frosch soll fähig sein, von unten „durch die Platform hindurch“ zu springen. Von oben fallend soll er natürlich auf der Platform stehen bleiben.
Um diesen Effekt zu erzeugen, müssen Kollisionen zwischen Frosch und Platform unterschiedlich behandelt werden:
- Kollidiert der Frosch von unten, so soll die Kollision ignoriert werden. Er prallt so nicht von der Decke ab und kann weiter nach oben Springen.
- Kollidiert der Frosch von oben, so soll die Kollision normal aufgelöst werden, sodass er nicht durch den Boden fällt.
Hierzu stellt das CollisionEvent-Objekt in der onCollision-Methode Funktionen bereit.
Kompletter Code
-
Der Abschnitt stammt aus dem Engine-Alpha-Wiki: https://engine-alpha.org/wiki/v4.x/Collision ↩