zulda/Welt.java

244 lines
9.0 KiB
Java

import ea.*;
import java.util.ArrayList;
/**
* Die Spielwelt besetht aus 4x3 {@link Karte}n, durch dei die {@link Lunk Spielfigur}
* wandern kann. Sie enthaät alles, was im Spiel sichtbar ist und interagieren kann.
*
* Sie prüft, ob die Bewegung einer Figur erlaub tist und setzt ggf. die Figuren
* auf eine neue Position (z.B. auch auf eine neue Karte).
*
* Der Prototyp enthält als Beispiel eine Karte mit wenig Inhalt und einigen
* zufälligen Elementen.
*/
public class Welt extends Knoten {
// Index der aktuelle sichtbaren Karte im Karten-Array
private int karteX, karteY;
// Speicher der 12 Karten
private Karte[][] karten;
// Referenz zur Spielfigur
private Lunk lunk;
// Aktuelle Position der Spielerfigur als Index der aktuellen Karte
// (Index des Feldes, auf dem Lunk steht.)
private int lunkX, lunkY;
public Welt( Lunk pLunk ) {
lunk = pLunk;
// Initialisiere die Karten der Welt
karten = new Karte[4][3];
for( int i = 0; i < karten.length; i++ ) {
for (int j = 0; j < karten[0].length; j++) {
if( i == 2 && j == 2 ) {
karten[i][j] = new Karte_0(i, j, this);
} else if( i == 0 || j == 0 ) {
karten[i][j] = new Karte_Random(i, j, this);
} else {
karten[i][j] = new Karte(i, j, this);
}
}
}
// Zeige die erste Karte, die angezeigt werden soll.
karteX = 2;
karteY = 2;
add(karten[karteX][karteY]);
karten[karteX][karteY].karteAnzeigen();
// Setze Lunks Startposition auf der aktuellen Karte.
lunkX = 10;
lunkY = 8;
karten[karteX][karteY].verschiebeZuFeldAnIndex(lunk, lunkX, lunkY);
add(lunk);
}
/**
* Gibt den Spielercharakter zurück.
* @return
*/
public Lunk getSpieler() {
return lunk;
}
/**
* Bewegt den {@ink Lunk Spielercharakter} ein Feld nach links. Überschreitet
* die Figur den Rand der Karte, wird die aktuelle Karte gewechselt, sofern
* nicht der Rand der Welt erreicht wurde. Ist das Feld nicht passierbar
* oder der Rand der Welt erricht, passiert nichts.
*/
public void bewegeLinks() {
lunk.zustandSetzen("run_left");
if (lunk.aktuelleFigur().getX() < 48) {
if( karteX > 0 ) {
wechseleKarte(karteX-1, karteY);
karten[karteX][karteY].verschiebeZuFeldAnKoordinate(lunk, 19*48, lunk.getY());
}
} else {
Feld feld = karten[karteX][karteY].feldAnKoordinate(lunk.getX()-48, lunk.getY());
// feld ist ungleich null, da sonst nicht der else-Zweig ausgeführt werden würde
if( feld.istPassierbar() ) {
karten[karteX][karteY].verschiebeZuFeld(lunk, feld);
// Gegenstände auf dem neuen Feld einsammeln
for( Gegenstand g: karten[karteX][karteY].getGegenstaendeAufFeld(feld) ) {
g.einsammeln(lunk);
}
}
}
lunk.zustandSetzen("idle_left");
}
/**
* Bewegt den {@ink Lunk Spielercharakter} ein Feld nach rechts. Überschreitet
* die Figur den Rand der Karte, wird die aktuelle Karte gewechselt, sofern
* nicht der Rand der Welt erreicht wurde. Ist das Feld nicht passierbar
* oder der Rand der Welt erricht, passiert nichts.
*/
public void bewegeRechts() {
lunk.zustandSetzen("run_right");
if (lunk.aktuelleFigur().getX() >= 19*48) {
if( karteX < 3 ) {
wechseleKarte(karteX+1, karteY);
karten[karteX][karteY].verschiebeZuFeldAnKoordinate(lunk, 0, lunk.getY());
}
} else {
Feld feld = karten[karteX][karteY].feldAnKoordinate(lunk.getX()+48, lunk.getY());
// feld ist ungleich null, da sonst nicht der else-Zweig ausgeführt werden würde
if( feld.istPassierbar() ) {
karten[karteX][karteY].verschiebeZuFeld(lunk, feld);
// Gegenstände auf dem neuen Feld einsammeln
for( Gegenstand g: karten[karteX][karteY].getGegenstaendeAufFeld(feld) ) {
g.einsammeln(lunk);
}
}
}
lunk.zustandSetzen("idle_right");
}
/**
* Bewegt den {@ink Lunk Spielercharakter} ein Feld nach oben. Überschreitet
* die Figur den Rand der Karte, wird die aktuelle Karte gewechselt, sofern
* nicht der Rand der Welt erreicht wurde. Ist das Feld nicht passierbar
* oder der Rand der Welt erricht, passiert nichts.
*/
public void bewegeHoch() {
lunk.zustandSetzen("run_right");
if (lunk.aktuelleFigur().getY() < 48) {
if( karteY > 0 ) {
wechseleKarte(karteX, karteY-1);
karten[karteX][karteY].verschiebeZuFeldAnKoordinate(lunk, lunk.getX(), 14*48);
}
} else {
Feld feld = karten[karteX][karteY].feldAnKoordinate(lunk.getX(), lunk.getY()-48);
// feld ist ungleich null, da sonst nicht der else-Zweig ausgeführt werden würde
if( feld.istPassierbar() ) {
karten[karteX][karteY].verschiebeZuFeld(lunk, feld);
// Gegenstände auf dem neuen Feld einsammeln
for( Gegenstand g: karten[karteX][karteY].getGegenstaendeAufFeld(feld) ) {
g.einsammeln(lunk);
}
}
}
lunk.zustandSetzen("idle_right");
}
/**
* Bewegt den {@ink Lunk Spielercharakter} ein Feld nach unten. Überschreitet
* die Figur den Rand der Karte, wird die aktuelle Karte gewechselt, sofern
* nicht der Rand der Welt erreicht wurde. Ist das Feld nicht passierbar
* oder der Rand der Welt erricht, passiert nichts.
*/
public void bewegeRunter() {
lunk.zustandSetzen("run_left");
if (lunk.aktuelleFigur().getY() >= 14*48) {
if( karteY < 2 ) {
wechseleKarte(karteX, karteY+1);
karten[karteX][karteY].verschiebeZuFeldAnKoordinate(lunk, lunk.getX(), 0);
}
} else {
Feld feld = karten[karteX][karteY].feldAnKoordinate(lunk.getX(), lunk.getY()+48);
// feld ist ungleich null, da sonst nicht der else-Zweig ausgeführt werden würde
if( feld.istPassierbar() ) {
karten[karteX][karteY].verschiebeZuFeld(lunk, feld);
// Gegenstände auf dem neuen Feld einsammeln
for( Gegenstand g: karten[karteX][karteY].getGegenstaendeAufFeld(feld) ) {
g.einsammeln(lunk);
}
}
}
lunk.zustandSetzen("idle_left");
}
/**
* Lässt den {@ink Lunk Spielercharakter} alle Gegner auf dem Feld rechts
* von ihm attackieren. Gegener deren Hitpoints auf Null sinken, werden aus
* der Karte entfernt.
*/
public void attackeRechts() {
Karte aktuelleKarte = karten[karteX][karteY];
Feld feldRechts = aktuelleKarte.feldAnKoordinate(lunk.zentrum().x+48, lunk.zentrum().y);
ArrayList<Gegner> gegnerRechts = aktuelleKarte.getGegnerAufFeld(feldRechts);
for( Gegner g: gegnerRechts ) {
// TODO: Überlgen, wie Schaden berechnet wird ...
g.addHitpoints((int) ((lunk.getAttack() - g.getDefense()) * -0.5) );
if( g.getHitpoints() <= 0 ) {
aktuelleKarte.entferneGegner(g);
}
}
}
/**
* Lässt den {@ink Lunk Spielercharakter} alle Gegner auf dem Feld links
* von ihm attackieren. Gegener deren Hitpoints auf Null sinken, werden aus
* der Karte entfernt.
*/
public void attackeLinks() {
Karte aktuelleKarte = karten[karteX][karteY];
Feld feldRechts = aktuelleKarte.feldAnKoordinate(lunk.zentrum().x-48, lunk.zentrum().y);
ArrayList<Gegner> gegnerRechts = aktuelleKarte.getGegnerAufFeld(feldRechts);
for( Gegner g: gegnerRechts ) {
// TODO: Überlgen, wie Schaden berechnet wird ...
g.addHitpoints((int) ((lunk.getAttack() - g.getDefense()) * -0.5) );
if( g.getHitpoints() <= 0 ) {
aktuelleKarte.entferneGegner(g);
}
}
}
/**
* Tauscht die aktuelle Karte gegen eine neue am Index (i|j) im Karten-Array
* aus. Gibt es an diesem index keine Karte, dann passiert nichts.
* @param i Horizontaler Index der neuen Karte
* @param j Vertikaler Index der neuen Karte
*/
private void wechseleKarte( int i, int j ) {
if( i >= 0 || i < karten.length && j >= 0 && j < karten[0].length ) {
karten[karteX][karteY].karteVerstecken();
entfernen(karten[karteX][karteY]);
karteX = i;
karteY = j;
add(karten[karteX][karteY]);
karten[karteX][karteY].karteAnzeigen();
// Lunk einmal entfernen und wieder adden, damit die Figur
// nicht von der neuen Karte verdeckt wird.
entfernen(lunk);
add(lunk);
}
}
}