Greenfoot Objekte löschen und neu platzieren nach dem Tot meiner Figur?

1 Antwort

1) Schreibe dir eine reset-/setup-Funktion. In dieser Funktion setzt du den Startzustand des Spiels (Score, Spielerpositionen, u.ä.). Du kannst sie dann zu Programmstart einmal aufrufen und einmal, sobald der Tod den Spieler ereilt.

if (player.isDead()) {
  reset();
}

Du brauchst also einmal die Referenzen auf alle Spielobjekte, die bei Start angelegt / gesetzt werden. Vielleicht hast du sie bereits in einer zentralen Game-Klasse vorliegen. Wenn nicht, kannst du sie dir auch über die World holen (sofern sie bereits der Welt zugefügt wurden).

Beispiel:

Player player = getWorld().getObjects(Player.class).get(0);
player.setLocation(0, 0);

Sofern du von Objekten Eigenschaften setzen möchtest, die nicht von der Greenfoot API stammen (vergleiche mit den set-Methoden der Actor-Klasse), solltest du in ihren Klassen entsprechende Setter-Methoden hinzufügen.

Beispiel:

class Enemy extends Actor {
  private float speed;

  public void setSpeed(float speed) {
    this.speed = speed;
  }
}

// usage:
Enemy enemy = getWorld().getObjects(Enemy.class).get(0);
enemy.setSpeed(5f);

2) Ich stell mir unter deiner Lebensanzeige ein Statusleiste mit n Herzen vor. Du brauchst also ein Klasse für ein Actor-Objekt, welches ein Herz zeichnet und eine Klasse für ein Objekt, welches die Herzen verwaltet.

Also ungefähr so:

class Heart extends Actor {
  private GreenfootImage image;

  public Heart() {
    image = new GreenfootImage("heart.jpg");
  }

  public int getWidth() {
    return image.getWidth();
  }
}

class HeartBar extends Actor {
  private Heart[] hearts;
  private int numberOfLives = 3;
  private int spacing = 10;
  
  public HeartBar() {
    for (int i = 0; i < hearts.length; ++i) {
      hearts[i] = new Heart();
      getWorld().addObject(hearts[i], i * hearts[i].getWidth() + spacing);
    }
  }

  public void updateAfterPlayerDeath() {
    --numberOfLives;

    if (numberOfLives >= 0) {
      getWorld().removeObject(hearts[i]);
    }
  }
}

Die Methode updateAfterPlayerDeath muss jedesmal aufgerufen werden, wenn der Spieler stirbt. Achte darauf, dass du das HeartBar-Objekt insgesamt nur einmal erstellst und der Welt zufügst.

3) Hast du denn auf deinem Rechner eine Schriftart namens Times installiert? Ich hätte ja nun auf den ersten Blick vermutet, dass du eigentlich Times New Roman einbinden möchtest.

Font font = new Font("Times New Roman", 16);

Problem323 
Fragesteller
 12.12.2021, 11:52

Danke für deine schnell Antwort.
Also das mit Herzen hat jetzt doch funktioniert, aber wenn es Probleme geben sollte probiere ich mal deine Methode.

Zu meiner ersten Frage, wo schreibe ich diese Reset Funktion hin? So das ich diese zum Start und zum Tod aufrufen kann. Also alle meine Objekte wie sie beim Start sind, sind in meiner Welt mit this.addObject( new ... und so weiter festgelegt.

Also das ist mein Code von der Welt:

public void Objekte()

  {

    // Plattformen oben 

    this.addObject(new Plattform1(), 45, 220);

    this.addObject(new Plattform1(), 201, 185);

    this.addObject(new Plattform1(), 388, 125);

    this.addObject(new Plattform1(), 533, 183);

    // Plattformen unten 

    this.addObject(new Plattform2(), 45, 536);

    this.addObject(new Plattform2(), 201, 495);

    this.addObject(new Plattform2(), 388, 440);

    this.addObject(new Plattform2(), 553, 501);

    // Spieler

    this.addObject(new Spieler1(), 55, 185);

    this.addObject(new Spieler2(), 55, 500);

    // LavaFunken oben 

    this.addObject(new LavaFunken1(), 158, 127);

    this.addObject(new LavaFunken1(), 405, 130);

    this.addObject(new LavaFunken1(), 540, 118);

    this.addObject(new LavaFunken1(), 9, 118);

    // LavaFunken unten

    this.addObject(new LavaFunken2(), 158, 426);

    this.addObject(new LavaFunken2(), 405, 430);

    this.addObject(new LavaFunken2(), 540, 426);

    this.addObject(new LavaFunken2(), 9, 445);

    //Münzen

    this.addObject(new Münzen1(), 92, 198);

  }

   Jedoch brauche ich nur einen Teil von dieses Restet wenn der Spieler stirbt. Da mein Spiel in zwei Hälften geteilt ist.

Das ist der Code von meinem Spieler 1:

public void LebenVerloren()

  {

    if(this.isTouching(LavaBlock1.class)) 

    {

      this.Leben = this.Leben -1;

      this.setLocation(55, 185); 

    }

Dort müsste ja dann statt set.Location, der Befehl rein um alle Objekte im Oberen Bildschirm zu Resten.

0
Problem323 
Fragesteller
 12.12.2021, 12:46
@Problem323

Da ich ja immer nur ein Objekt von meiner Klasse neu platzieren kann. Das ist mein Hauptproblem

0
regex9  13.12.2021, 01:15
@Problem323

Die Methode könnte in dieselbe Klasse, in der schon deine Methode Objekte steht.

Allerdings würde ich Objekte noch einmal etwas verändern (in dem Zuge auch den Namen, damit deutlich wird, dass es sich um eine Funktion handelt). Damit du all die Objekte, die du der Spielwelt zufügst, leichter in zuruecksetzen wieder ansprechen kannst, würde ich sie jeweils in Felder speichern.

private Plattform1 plattformOben1;
private Plattform1 plattformOben2;
private Plattform1 plattformOben3;
private Plattform1 plattformOben4;
private Plattform2 plattformUnten1;
// etc. ...

public void initialisiereObjekte() {
  this.plattformOben1 = new Plattform1();
  this.addObject(this.plattformOben1, 45, 220);

  this.plattformOben2 = new Plattform1();
  this.addObject(this.plattformOben2, 201, 185);

  // etc. ...
}

public void zuruecksetzen() {
  this.plattformOben1.setLocation(45, 220);
  this.plattformOben2.setLocation(201, 185);
  // etc. ...
}       

Der Aufruf zum Zurücksetzen der Spielobjekte muss in deine LebenVerloren-Methode hinein, das ist richtig. Der Spieler muss dafür eine Referenz auf das Objekt der Klasse haben, in der zuruecksetzen steht. Entweder du übergibst diese über den Konstruktor oder du machst die Klasse zum Subtyp von Actor, fügst sie der Welt zu und holst dir das Objekt in LebenVerloren über das World-Objekt. Letzteres hatte ich ja schon einmal gezeigt, Ersteres würde so klappen:

1) Deine Spieler1-Klasse bekommt ein Feld und der Konstruktor einen Parameter. Genau das Gleiche wird vermutlich in Spieler2 benötigt, sofern es sich dabei nicht um einen NPC handelt.

public class Spieler1 extends Actor {
  private DeineKlasse spiel;

  public Spieler1(DeineKlasse spiel) {
    this.spiel = spiel;
  }

  // ...
}

2) In der initialisiereObjekte-Methode werden die Spieler-Objekte so angelegt:

this.spieler1 = new Spieler1(this);
this.addObject(this.spieler1, 55, 185);

this.spieler2 = new Spieler2(this);
this.addObject(this.spieler2, 55, 500);

3) Da this auf das Objekt der Klasse verweist, bekommst du somit das Objekt in die Spielerobjekte hinein, über die du zuruecksetzen aufrufen kannst.

this.spiel.zuruecksetzen();
0