mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-04-14 06:33:34 +02:00
195 lines
5.2 KiB
Java
195 lines
5.2 KiB
Java
import schule.ngb.zm.Zeichenmaschine;
|
|
import schule.ngb.zm.shapes.Text;
|
|
|
|
import java.awt.Font;
|
|
|
|
public class Raindrops extends Zeichenmaschine {
|
|
|
|
//@formatter:off
|
|
// Einstellungen für das Spiel
|
|
|
|
// Breite / Höhe des Spielfensters.
|
|
public static final int GAME_WIDTH = 400;
|
|
public static final int GAME_HEIGHT = 600;
|
|
// Breite des Randes (dort werden keine Tropfen erstellt).
|
|
public static final int GAME_BORDER = 10;
|
|
|
|
// Anzahl Tropfen zu Beginn des Spiels.
|
|
public static final int GAME_START_DROPS = 5;
|
|
// Maximale Anzahl Tropfen im Spiel.
|
|
public static final int GAME_MAX_DROPS = 12;
|
|
// Anzahl gefangenere Tropfen, ab der ein neuer Level anfängt.
|
|
public static final int GAME_NEXT_LEVEL_AT = 10;
|
|
// Anzahl Tropfen, die fallen gelassen werden dürfen,
|
|
// bevor das Spiel vorbei ist.
|
|
public static final int GAME_MAX_DROPPED = 13;
|
|
//@formatter:on
|
|
|
|
public static void main( String[] args ) {
|
|
new Raindrops();
|
|
}
|
|
|
|
/**
|
|
* Array der Tropfen-Objekte.
|
|
*/
|
|
private Drop[] drops;
|
|
|
|
/**
|
|
* Das Eimer-Objekt.
|
|
*/
|
|
private Bucket bucket;
|
|
|
|
/**
|
|
* Anzahl Tropfen, die aktuell im Spiel sind.
|
|
*/
|
|
private int noOfDrops = GAME_START_DROPS;
|
|
|
|
/**
|
|
* Anzahl gefangener / fallen gelassener Tropfen.
|
|
*/
|
|
private int dropped = 0, catched = 0;
|
|
|
|
/**
|
|
* Text-Objekte für die Anzeige der gefangenen / fallen gelassenen Tropfen.
|
|
*/
|
|
private Text textDropped, textCatched;
|
|
|
|
public Raindrops() {
|
|
super(GAME_WIDTH, GAME_HEIGHT, "ZM: Raindrops");
|
|
}
|
|
|
|
/**
|
|
* Initialisierung des Spiels und der benötigten Objekte.
|
|
*/
|
|
public void setup() {
|
|
hideCursor();
|
|
|
|
// Hintergrund blaugrau
|
|
background.setColor(129, 174, 206);
|
|
|
|
// Hintergrundbild zeichnen (DrawingLayer)
|
|
drawing.setFillColor(0, 144, 81);
|
|
drawing.noStroke();
|
|
drawing.rect(0, height - 40, width, 40, NORTHWEST);
|
|
|
|
// Eimer-Objekt erstellen
|
|
bucket = new Bucket(width / 2, height - 60);
|
|
bucket.scale(.25);
|
|
shapes.add(bucket);
|
|
|
|
// Tropfen-Objekte erstellen
|
|
// Die maximale Anzahl Tropfen kann durch GAME_MAX_DROPS eingestellt werden
|
|
// Es werden alle Tropfen erstellt, anber nur die ersten noOfDrops
|
|
// Objekt im Spiel angezeigt.
|
|
drops = new Drop[GAME_MAX_DROPS];
|
|
for( int i = 0; i < drops.length; i++ ) {
|
|
drops[i] = new Drop();
|
|
drops[i].scale(.1);
|
|
shapes.add(drops[i]);
|
|
}
|
|
|
|
// Die ersten noOfDrops Tropfen zu Beginn anzeigen.
|
|
// Die Tropfen werden mit zufälliger x-Koordinate etwas versetzt
|
|
// übereinander positioniert, damit sie nicht alle gleichzeitig fallen.
|
|
for( int i = 0; i < noOfDrops; i++ ) {
|
|
drops[i].moveTo(
|
|
random(GAME_BORDER, GAME_WIDTH - GAME_BORDER),
|
|
Drop.START_Y - i * (2 * Drop.START_Y) - random(-10, 10)
|
|
);
|
|
drops[i].activate();
|
|
drops[i].show();
|
|
}
|
|
|
|
// Erstellen der Text-Objekte für dei Zähler.
|
|
textCatched = new Text(10, 60, "0");
|
|
textCatched.setFontsize(64);
|
|
textCatched.setAnchor(NORTHWEST); //linksbündig
|
|
shapes.add(textCatched);
|
|
textDropped = new Text(width - 10, 60, "0");
|
|
textDropped.setFontsize(64);
|
|
textDropped.setAnchor(NORTHEAST); // rechtsbündig
|
|
shapes.add(textDropped);
|
|
}
|
|
|
|
/**
|
|
* Hier passiert die Spiel-Logik. Die Position des Eimers und der Tropfen
|
|
* wird aktualisiert. Es wird geprüft, ob ein Tropfen mit dem Eimer
|
|
* kollidiert oder den Boden erreicht hat.
|
|
*
|
|
* @param delta
|
|
*/
|
|
public void update( double delta ) {
|
|
// Position des Eimers auf Mausposition setzen.
|
|
if( mouseX < 0 ) {
|
|
// Stopp am linken Rand
|
|
bucket.setX(0);
|
|
} else if( mouseX > width ) {
|
|
// Stopp am rechten Rand
|
|
bucket.setX(width);
|
|
} else {
|
|
bucket.setX(mouseX);
|
|
}
|
|
|
|
// Die Position der Tropfen aktualisieren und Kollisionen prüfen.
|
|
for( int i = 0; i < noOfDrops; i++ ) {
|
|
drops[i].update(delta);
|
|
|
|
if( drops[i].getY() >= height - 40 ) {
|
|
// Tropfen hat Boden erreicht!
|
|
dropped += 1;
|
|
textDropped.setText("" + dropped);
|
|
drops[i].reset();
|
|
} else if( bucket.contains(drops[i]) ) {
|
|
// Tropfen wurde gefangen!
|
|
catched += 1;
|
|
textCatched.setText("" + catched);
|
|
drops[i].reset();
|
|
|
|
// Wurde ein Tropfen gefangen (und nur dann) wird geprüft, ob
|
|
// das nächste Level erreicht wurde.
|
|
if( catched > 0 && (catched % GAME_NEXT_LEVEL_AT) == 0 ) {
|
|
// Falls noch nicht alle Tropfen im Spiel, aktiviere einen
|
|
// weiteren.
|
|
if( noOfDrops < drops.length ) {
|
|
noOfDrops += 1;
|
|
drops[noOfDrops - 1].activate();
|
|
drops[noOfDrops - 1].reset();
|
|
}
|
|
|
|
// Geschwindigkeit aller Tropfen erhöhen.
|
|
for( int j = 0; j < drops.length; j++ ) {
|
|
drops[j].increaseSpeed();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Prüfen, ob das Spiel verloren wurde.
|
|
if( dropped >= GAME_MAX_DROPPED ) {
|
|
stop(); // Stoppt den Game-Loop und ruft dann teardown() auf.
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Wird aufgerufen, nachdem das Spiel gestoppt wurde und zeigt den Game Over
|
|
* Bildschirm an.
|
|
*/
|
|
public void teardown() {
|
|
// Alle Formen (Eimer, Tropfen, Texte) entfernen.
|
|
shapes.removeAll();
|
|
|
|
// "Game Over" Text
|
|
Text gameOver = new Text(width / 2, 300, "Game Over");
|
|
gameOver.setFontsize(64);
|
|
shapes.add(gameOver);
|
|
|
|
// Ergebnis anzeigen (Anzahl gefangener Tropfen, Spielzeit in Sekunden).
|
|
Font f = new Font(Font.SANS_SERIF, Font.PLAIN, 32);
|
|
shapes.add(new Text(width / 2, 360, "Catched: " + catched, f));
|
|
shapes.add(new Text(width / 2, 360 + f.getSize(), "Time: " + (runtime / 1000.0), f));
|
|
|
|
redraw();
|
|
}
|
|
|
|
}
|