Feinde überlappen sich in Java Spiel

Hey, ich arbeite gerade an meinem ersten Spiel in Java. Ich benutze dafür zu großen Teilen swing und awt. Mein Spiel besteht daraus, dass mehrere Gegner erstellt werden, die man besiegen muss. Diese Feinde kommen auf den Spieler zu, abhängig von seiner Position. Ich habe dann Kollision eingebaut, die über Rechtecke um den Spieler und den Feind funktioniert. Überschneiden sich diese Rechtecke, wird die Kollision erkannt (intersect Methode). Meine Gegner speichere ich in einer ArrayList, über die der Gegner entfernt werden kann, sollte er besiegt werden. Nun überschneiden sich die Gegner jedoch auch selbst, wenn sie auf den Spieler zukommen. Wie kann ich die Kollision zwischen Objekten in einer Liste implementieren? Mein Ansatz war erst über die Liste zu iterieren und mit jeder Iteration die Rechtecke zu vergleichen. Ich bin jetzt seit mehreren Stunden dabei, aber die Feinde überlappen sich trotzdem. Hat jemand eine Idee? Hier mal ein Beispiel Code, wie sich meine Gegner (Flammen) bewegen(sie überlappen sich trotzdem). Der Spieler ist hier ein Schneemann. Die Methode getBounds ist in meiner Flame Klasse als Rechteck definiert. Wichtig wäre noch, dass sowohl das überprüfen der Kollisionen und das erstellen von Gegnern teil des Game loops sind (update Methode).
Falls noch Fragen zu bestimmten Methoden bestehen dann lasst es mich wissen, danke im Voraus


Java:
private void moveFlames(int snowmanX, int snowmanY) {
    for (Flame flame : flames) {
        flame.move(snowmanX, snowmanY);

        // Kollision mit anderen Flammen überprüfen
        for (Flame otherFlame : flames) {
            if (flame != otherFlame && flame.getBounds().intersects(otherFlame.getBounds())) {
                 flame.setSpeedX(-flame.getSpeedX());
                 flame.setSpeedY(-flame.getSpeedY());
                
            }
        }
    }
}

Java:
private void update() {
        int panelWidth = panel.getWidth();
        int panelHeight = panel.getHeight();
    
         if (upPressed && posY > 0) {
             posY -= speed;
             snowman.setDirection(1);
         }
          if (downPressed && posY < panelHeight - 135) {
               posY += speed;
               snowman.setDirection(0);
          }
          if (leftPressed && posX > 30) {
              posX -= speed;
               snowman.setDirection(2);
          }
          if (rightPressed && posX < panelWidth - 60) {
              posX += speed;
               snowman.setDirection(3);
          }
            
         if(!gameOver){
            snowman.setPosition(posX, posY);
            snowman.animate();
            if (flames.size() < MAX_FLAMES) { //In der Liste gespeicherte Objekte werden abgeglichen
                createFlame(); // Erzeugt neue Flammen, wenn die maximale Anzahl nicht erreicht ist
            }
            if(tokens.size() < MAX_TOKENS){
                createToken();
            }
            moveSnowballs();
            moveFlames(snowman.getX(), snowman.getY()); //Hier bewegen sich die Flammen 
            checkCollisionWithSnowman(snowman);
            checkCollisionWithSnowballs();
            checkCollisionWithToken();
            
            }
            else{
            JFrame frame = new JFrame("Game Over"); //Neuer Game-Over Bildschirm
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setResizable(false);
            
            GameOverScreen gameOverScreen = new GameOverScreen(score); // Übergebe den Highscore oder die Punktzahl
            frame.add(gameOverScreen);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
    
            // Stoppe das Spiel
            timer.stop();
            this.dispose();
            }
    }
 

KonradN

Super-Moderator
Mitarbeiter
Ich bin mir jetzt nicht ganz sicher, aber meine Vermutung wäre, dass es schlicht daran liegt, dass Du auch eine Bewegung hast ohne check auf Kollisionen.

Du hast ja:
Java:
            if (flame != otherFlame && flame.getBounds().intersects(otherFlame.getBounds())) {
                 flame.setSpeedX(-flame.getSpeedX());
                 flame.setSpeedY(-flame.getSpeedY());
                
            }
Und das wird bei jedem Flame gemacht, das sich überschneiden sollte.

Ich würde da also raten, das in mehr Methoden zu unterteilen und eine Methode zu machen, die nur prüft, ob es eine Überschneidung gibt.

Dann kannst Du folgenden Algorithmus umsetzen:
  • Position merken
  • In die gewünschte Richtung bewegen
  • Gibt es eine Kollision? Dann bewege Dich in die andere Richtung
  • Gibt es eine Kollision? Dann setze die gemerkte Position (die hatte ja noch keine Kollision)

Ansonsten sah der Code prinzipiell ok aus, wobei da natürlich noch Fragen offen sind. So bewegst Du Dich in die entgegengesetzte Richtung, aber du änderst nicht die Richtung? Wäre da nicht eine Veränderung der Richtung notwendig? Aber wenn Du mit dem Ziel die Richtung vorgibst (beim move Aufruf), dann ist das evtl. auch so nicht ok. Dann ist die Logik evtl. einfach nur:
  • Position merken
  • In die gewünschte Richtung bewegen
  • Gibt es eine Kollision? Dann setze gemerkte Position.

Sprich: Wenn die neue Position nicht frei ist, dann bewegt sich die Flamme nicht.
 
Ansonsten sah der Code prinzipiell ok aus, wobei da natürlich noch Fragen offen sind. So bewegst Du Dich in die entgegengesetzte Richtung, aber du änderst nicht die Richtung? Wäre da nicht eine Veränderung der Richtung notwendig? Aber wenn Du mit dem Ziel die Richtung vorgibst (beim move Aufruf), dann ist das evtl. auch so nicht ok. Dann ist die Logik evtl. einfach nur:
  • Position merken
  • In die gewünschte Richtung bewegen
  • Gibt es eine Kollision? Dann setze gemerkte Position.

Sprich: Wenn die neue Position nicht frei ist, dann bewegt sich die Flamme nicht.
Ja, ich hatte die move Methode in der falschen for Schleife im Beispiel, das konnte natürlich nicht gehen. Meine Idee war ursprünglich bei einer Kollision, dass die Flammen sich nur in die Richtung des Schneemanns bewegen können, wenn sie nicht kollidieren. Wenn sie kollidieren, dürfen sie jedoch nicht stehenbleiben. Meine derzeitige Logik war eigentlich:

  • Abfrage, ob Kollision erkannt wurde
  • Wenn Nein, dann bewege die Flamme normal weiter
  • Wenn Ja, dann bewege Flamme in gewünschte Position
Mein Problem ist nur, dass ich keinen wirklichen Ansatz habe, in welche Richtung die Flamme gehen soll. Sonst stimmt jetzt alles. Die move Methode funktioniert so:
Java:
public void move(int snowmanX, int snowmanY) {
        double angle = Math.atan2(snowmanY - y, snowmanX - x); //Berechnet Winkel abhängig von der X und Y Koordinate relativ zum Ursprung
        x += (int) (speed * Math.cos(angle)); //Richtung für die Flamme;  cos bzw. sin wird mit speed multipliziert
        y += (int) (speed * Math.sin(angle));
       
}

Die Flamme bewegt sich immer zum Schneemann hin, wenn diese Methode aufgerufen wird. Mir ist nur keine andere eingefallen, da mir noch ziemlich die Erfahrung fehlt. Hier mal ein unvollständiger Ansatz:
Java:
    private void moveFlames(int snowmanX, int snowmanY) {
        for (Flame flame : flames) {
            boolean collided = false; // Hilfsvariable, um festzuhalten, ob eine Kollision aufgetreten ist
            for (Flame otherFlame : flames) {
                if (flame != otherFlame && flame.getBounds().intersects(otherFlame.getBounds())) {
                    // Kollision erkannt, markiere die Kollision
                    collided = true;
                   
                    //To-Do; neue Richtung
                    break; // Beende die Schleife, da eine Kollision erkannt wurde
                }
            }
           
            if (!collided) {
                flame.move(snowmanX, snowmanY); // Bewege die Flamme, wenn keine Kollision auftritt
               
            }
        }
    }

Vielleicht überdenke ich die Flammen grundsätzlich und platziere sie auf einem Gitter. Das würde Kollisionsüberprüfung einfacher machen, falls das hier zu kompliziert wird.
 
Zuletzt bearbeitet:
Ich habe gerade einen Weg gefunden, mit dem ich ganz zufrieden bin. Danke für die Hilfe
Java:
    public void moveFlames(int snowmanX, int snowmanY) {
        for (int i = 0; i < flames.size(); i++) {
            Flame flame = flames.get(i);
            int oldX = flame.getX();
            int oldY = flame.getY();
   
            flame.move(snowmanX, snowmanY); // Bewege die Flamme entsprechend der Schneemann-Bewegung
   
            for (int j = i + 1; j < flames.size(); j++) {
                Flame otherFlame = flames.get(j);
                if (flame.getBounds().intersects(otherFlame.getBounds())) {
                    // Berechne die Differenz der Positionen
                    int diffX = flame.getX() - otherFlame.getX();
                    int diffY = flame.getY() - otherFlame.getY();
   
                    // Skaliere die Differenz, um die Bewegung zu vergrößern
                    int scale = 2;
                    diffX *= scale;
                    diffY *= scale;
                   
   
                    // Verschiebe die Flammen voneinander weg
                    flame.setX(oldX - diffX);
                    flame.setY(oldY - diffY);
                    otherFlame.setX(otherFlame.getX() + diffX);
                    otherFlame.setY(otherFlame.getY()+ diffY);
                }
            }
        }
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Mein Jump and Run charakter bewegt sich nicht mehr rückwärts... Spiele- und Multimedia-Programmierung 0
R Memory - Nicht alle Button lassen sich aktivieren? Spiele- und Multimedia-Programmierung 1
P Sich bewegende Kamera Spiele- und Multimedia-Programmierung 12
I Wo befindet sich ein Punkt? Spiele- und Multimedia-Programmierung 6
N der Player bewegt sich nicht Spiele- und Multimedia-Programmierung 14
R Game Loop verhält sich eigenartig Spiele- und Multimedia-Programmierung 1
A Spielball bewegt sich nicht richtig, prallt falsch ab Spiele- und Multimedia-Programmierung 7
Blender3D VLCJ Video lässt sich nicht mehr abspielen nach mysql Installation Spiele- und Multimedia-Programmierung 1
Androbin Mein Spiel will sich nicht zeichnen lassen !!! Spiele- und Multimedia-Programmierung 7
S Animation zieht "Spur" hinter sich her Spiele- und Multimedia-Programmierung 2
M Bildschirmgröße ändert sich Spiele- und Multimedia-Programmierung 10
M Würdet ihr sagen Java Applets eignen sich gut Spiele- und Multimedia-Programmierung 5
J Java3D - Farben vermischen sich Spiele- und Multimedia-Programmierung 7
E [LWJGL] Karusell, mehrere Objekte drehen sich um einen Mittelpunkt Spiele- und Multimedia-Programmierung 31
CookieSoft 3D Würfel will sich nicht drehen! [LWJGL] Spiele- und Multimedia-Programmierung 2
M Beim schießen richtet sich die Kugel nach der Maus aus (Quaternion) Spiele- und Multimedia-Programmierung 5
J Pufferproblem bei sich wiederholenden MouseEvents Spiele- und Multimedia-Programmierung 4
T JOGL im OrthoMode und Texturen verfärben sich Spiele- und Multimedia-Programmierung 3
S Programm hängt sich auf wenn Lied abspielt Spiele- und Multimedia-Programmierung 4
W 2 Bälle, die sich abstoßen Spiele- und Multimedia-Programmierung 24
F RPG - Spielfigur soll sich nicht frei bewegen können. Anregugen wären gerne gesehen^^ Spiele- und Multimedia-Programmierung 13
Ivan Dolvich [LWJGL] Texturen überlagern sich Spiele- und Multimedia-Programmierung 2
P JFileChooser öffnet sich drei mal Spiele- und Multimedia-Programmierung 4
Dragonfire Java Sound API - Lautstärke ändert sich nicht Spiele- und Multimedia-Programmierung 2
H Jogl-Animator - Inhalt ändert sich nicht Spiele- und Multimedia-Programmierung 4
M Sich nach links verschiebendes Bild Spiele- und Multimedia-Programmierung 2
L Figur soll sich selbständig Bewegen Spiele- und Multimedia-Programmierung 12
S Polygon bewegt sich nach mehreren aufrufen immer schneller Spiele- und Multimedia-Programmierung 3
B Bounds drehen sich nicht mit.... Spiele- und Multimedia-Programmierung 7
R Eignet sich Java für ein Beat'em'Up? Spiele- und Multimedia-Programmierung 3
R Kreuz lässt sich nicht zeichnen Spiele- und Multimedia-Programmierung 11

Ähnliche Java Themen

Neue Themen


Oben