Klassen Alle Unter-Objekte durchlaufen in der Hauptklasse

Bobo2040

Mitglied
Hallo, ich bin neu hier im Forum und auch was Java angeht. Ich habe eine kleine Klasse erstellt mit Unterklassen(Game -> SpaceShip(Spieler/Enemy)).
Ich möchte jetzt in der Klasse Game, alle existierenden Objekte der Klasse SpaceShip durchlaufen und gegebenenfalls dieses Objekt löschen.(Lebenspunkte <= 0)

Ich denke es ist relativ leicht zu lösen, leider weiß ich nicht wie. Hier mal mein Bisheriger Code:
Java:
//Class Game.java
package game;

public class Game{

    public static void main(String[] args) {
        Player player = new Player();
        Enemy enemy = new Enemy();
       
        player.setName("Spieler");
        player.setHp(1000);
       
        enemy.setName("Gegner");
        enemy.setHp(500);
       
        player.showStats();
        enemy.showStats();
       
        while(true) {
            deleteDeadPlayerAndEnemy();
        }
       
    }
   
    static void deleteDeadPlayerAndEnemy() {
        //Hier will ich alle Objekte überprüfen und anschließend ein Objekt löschen
        //wenn die .getHp() Methode des bestimmten Objektes einen Wert von 0 oder kleiner zurückgibt
    }
   
}


//Class SpaceShip.java
package game;

public class SpaceShip{
    private int hp,x,y,speed,damage;
    private String name;

    public void showStats() {
        System.out.println(this.name);
        System.out.println("X: " + this.x);
        System.out.println("Y: " + this.y);
        System.out.println("Speed: " + this.speed);
        System.out.println("Damage: " + this.damage);
        System.out.println("-----------------------------");
    }
   
    public void setX(int x) {
        this.x = x;
    }
    public int getX() {
        return this.x;
    }
    public void setY(int y) {
        this.y = y;
    }
    public int getY() {
        return this.y;
    }
    public void setSpeed(int speed) {
        this.speed = speed;
    }
    public int getSpeed() {
        return this.speed;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
    public void setHp(int hp) {
        this.hp = hp;
    }
    public int getHp() {
        return this.hp;
    }
    public void setDamage(int damage) {
        this.damage = damage;
    }
    public int getDamage() {
        return this.damage;
    }
   
    public void moveLeft() {
        this.x = this.x - this.speed;
    }
    public void moveRight() {
        this.x = this.x + this.speed;
    }
    public void moveUp() {
        this.y = this.y + this.speed;
    }
    public void moveDown() {
        this.y = this.y - this.speed;
    }

    public void fightEnemy(Enemy enemy) {
        enemy.setHp(enemy.getHp() - this.damage);
        System.out.println("Gegner wird Attackiert" + enemy.getHp());
    }
    public void fightPlayer(Player player) {
        player.setHp(player.getHp() - this.damage);
        System.out.println("Spieler wird Attackiert" + player.getHp());
    }
}


//Class Player.java
package game;

class Player extends SpaceShip{
   
}
//Class Enemy.java
package game;

class Enemy extends SpaceShip{
   
}

Ich weiß nicht, ob das die eleganteste Lösung ist, wie ich das vorhabe.
Danke schonmal im Voraus. 🙂
 
@Bobo2040
Ich würde alle Objekte in einer Liste speichern und dann diese durchgehen und aussortieren.
Java:
public class Game
{

    public final static int NUMBER_OF_GAME_OBJECTS = 1000;
    public final static int LIFE_BORDER_FOR_EXAMPLE = 10;

    public static void main(String[] args)
    {

        List<GameObject> gameObjects = new ArrayList<>();
        for (int i = 0; i < NUMBER_OF_GAME_OBJECTS; i++)
        {
            gameObjects.add(new Player());
        }

        System.out.println(gameObjects.size());

        for (int i = 0; i < gameObjects.size(); i++)
        {
            if (gameObjects.get(i).getLifeCount() < LIFE_BORDER_FOR_EXAMPLE)
            {
                gameObjects.remove(i);
            }
        }

        System.out.println(gameObjects.size());
    }

}
/** Output */
1000
909
 
Danke für die Antwort, ich habe das jetzt mal probiert. Jedoch bekomme ich den Fehler "Cannot find Symbol GameObject...". Ich denke mir fehlt da ein Import, jedoch wird mir dieser nicht bei Netbeans angezeigt. Im Internet habe ich auf die schnelle auch nicht gefunden was ich da Importieren muss. Wärst du so nett, mir das zu sagen, also wie der Import heißt?

EDIT:
Ich habs, GameObject ist nur der Klassenname, auf den sich das bezieht. In meinem Fall wäre das SpaceShip. Danke aufjedenfall! 🙂
 
Zuletzt bearbeitet:
Java:
for (int i = 0; i < gameObjects.size(); i++)
        {
            if (gameObjects.get(i).getLifeCount() < LIFE_BORDER_FOR_EXAMPLE)
            {
                gameObjects.remove(i);
            }
        }
Damit überspringst du immer das Element, welches nach einem gelöschtem kommt 😉

Angenommen du löscht an Index 2, dann rutscht das, was vorher an Index 3 war, auf Index 2, als nächstes betrachtest du das an Index 3, und das was von 3 auf 2 gerutscht ist, wird ignoriert 😉
 
Ja, so mehr oder weniger. Wie gesagt ich bin noch Anfänger und lerne gerade. Ich habe jetzt ein neues Problem und zwar wenn ich das aus der Liste gelöscht habe, dann kann ich trotzdem noch darauf zugreifen. Ist ja prinzipiell auch logisch, aber wie kann ich das bewerkstelligen, das es komplett weg ist? Oder sollte ich meine "ganze" Klassenstruktur so umbauen, das ich Daten abfrage/verarbeite und Methoden ausführe immer über die Liste mache?
Mir erscheint das es so nämlich ein größerer Rechenaufwand oder nicht?
 
Damit überspringst du immer das Element, welches nach einem gelöschtem kommt 😉

Angenommen du löscht an Index 2, dann rutscht das, was vorher an Index 3 war, auf Index 2, als nächstes betrachtest du das an Index 3, und das was von 3 auf 2 gerutscht ist, wird ignoriert 😉
Hm.. stimmt! Dann würde ich alle in Frage kommenden Objekte in einer internen Liste speichern und diese am Ende der Methode aus der Liste der bestehenden GameObjeke löschen. Man könnte aber auch i um eins zurücksetzen und weiter suchen.

Ich habe jetzt ein neues Problem und zwar wenn ich das aus der Liste gelöscht habe, dann kann ich trotzdem noch darauf zugreifen.
Es kommt darauf an: willst du dann darauf zugreifen, ist es in irgendeiner Weise wichtig?
 
Nein, ich möchte ja das ich darauf nicht mehr zugreifen kann, da der Spieler/Gegner ja "tot" ist. Ich habe es jetzt so gelöst, das ich alles in GameObject Speicher und dann von dort aus die Daten abrufe um die Attribute zu bekommen. Das funktioniert auch soweit.
Ich habe jetzt jedoch ein neues Problem, im Internet habe ich ein Tutorial zu Graphics2D gefunden und erstmal abgetippt und etwas rumgespielt. Das funktioniert auch, ich hätte dazu noch eine Frage, und hoffe ihr könnt mir dabei behilflich sein.

Hier ist der Code aus dem Tutorial:
Java:
package spiel;

import javax.swing.JComponent;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.geom.*;


/**
*
* @author macbook
*/
public class Spiel extends JFrame {

    public static void main(String[] args) {
        Spiel spiel = new Spiel();
    }
  
    public Spiel() {
      
        this.setSize(500,500);
        this.setTitle("Spiel");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(new DrawStuff());
        this.setVisible(true);
      
    }
  
    private class DrawStuff extends JComponent {
        public void paint(Graphics g) { //hier ist das Problem
          
            Graphics2D graph = (Graphics2D)g;
          
            graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            Shape drawLine = new Line2D.Float(20,95,55,250);
            Shape drawKreis = new Arc2D.Float(100, 100, 50,50,0, 360, Arc2D.OPEN);
            Shape drawEllipse = new Ellipse2D.Float(10,10,100,100);
          
            GradientPaint theGradient = new GradientPaint(0,0, Color.BLACK, 1,30, Color.WHITE);
          
            graph.setPaint(theGradient);
            graph.fill(drawKreis);
            graph.draw(drawLine);
            graph.draw(drawKreis);
            graph.draw(drawEllipse);
          
          
        }
    } 
}
Ich verstehe nicht woher in der paint() Methode das Graphics g kommt, es wird auch nicht Initialisiert und auch nicht beim Aufruf der Klasse draw() übergeben. Es funktioniert aber trotzdem. Woher kommt das Graphics g und warum muss es nicht übergeben werden? und warum muss die paint() Methode nicht aufgerufen werden?
 
Nein, ich möchte ja das ich darauf nicht mehr zugreifen kann, da der Spieler/Gegner ja "tot" ist. Ich habe es jetzt so gelöst, das ich alles in GameObject Speicher und dann von dort aus die Daten abrufe um die Attribute zu bekommen. Das funktioniert auch soweit.
Das entspricht doch dem Vorschlag von @Javinner?

Woher kommt das Graphics g und warum muss es nicht übergeben werden?
Das wird von Java selbst aufgerufen, das Graphics-Objekt gehört zu dem angezeigtem Fenster.
 
Okay, ja entspricht es auch.
Wieso wird die Methode paint() dann aufgerufen, wenn ich ein neues Objekt von der Klasse draw erstelle?
Kennt jemand vielleicht ein gutes und vor allem ausführliches Tutorial für Graphics2D?
 

Neue Themen


Zurück
Oben